5#include "Stroika/Foundation/StroikaPreComp.h"
9#if qStroika_Foundation_Common_Platform_MacOS
15#include <LPlaceHolder.h>
19#include <UMemoryMgr.h>
25#elif qStroika_FeatureSupported_XWindows
34#include "Stroika/Frameworks/Led/SpellCheckEngine_Basic.h"
35#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_LedNative.h"
36#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_PlainText.h"
37#if qStroika_Foundation_Common_Platform_MacOS
38#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_STYLText.h"
41#if qStroika_Foundation_Common_Platform_MacOS
42#include "Stroika/Frameworks/Led/FilteredFilePicker.h"
43#elif qStroika_Foundation_Common_Platform_Windows
44#include "LedItControlItem.h"
45#include "LedItServerItem.h"
50#include "LedItApplication.h"
52#include "LedItDocument.h"
55using namespace Stroika::Frameworks::Led;
56using namespace Stroika::Frameworks::Led::Platform;
57using namespace Stroika::Frameworks::Led::StyledTextIO;
59using Memory::MakeSharedPtr;
62#if qStroika_Foundation_Common_Platform_MacOS
63class LedItDocumentWindow :
public LWindow {
65 LedItDocumentWindow (ResIDT inWINDid, UInt32 inAttributes, LCommander* inSuper)
66 : LWindow (inWINDid, inAttributes, inSuper)
68 sWindowList.push_back (
this);
69 ::AppendMenu (::GetMenuHandle (kWindowsMenuID),
"\pREPLACEME");
70 LMenu* windowMenu = LMenuBar::GetCurrentMenuBar ()->FetchMenu (kWindowsMenuID);
71 AssertNotNil (windowMenu);
72 size_t nMenuItems = ::CountMenuItems (windowMenu->GetMacMenuH ());
73 for (
size_t i = 1; i <= nMenuItems; ++i) {
74 windowMenu->SetCommand (i, i - 1 + kBaseWindowCmd);
78 ~LedItDocumentWindow ()
81 sWindowList.erase (std::find (sWindowList.begin (), sWindowList.end (), w));
82 LMenu* windowMenu = LMenuBar::GetCurrentMenuBar ()->FetchMenu (kWindowsMenuID);
83 AssertNotNil (windowMenu);
84 windowMenu->RemoveItem (1);
85 size_t nMenuItems = ::CountMenuItems (windowMenu->GetMacMenuH ());
86 for (
size_t i = 1; i <= nMenuItems; ++i) {
87 windowMenu->SetCommand (i, i - 1 + kBaseWindowCmd);
92 virtual void CalcStandardBoundsForScreen (
const Rect& inScreenBounds, Rect& outStdBounds)
const override
94 LWindow::CalcStandardBoundsForScreen (inScreenBounds, outStdBounds);
95 short winWidth = ::GetRectWidth (outStdBounds);
96 short desiredWidth = 8.5 * 72;
97 short newWidth = Led_Min (winWidth, desiredWidth);
98 outStdBounds.right = outStdBounds.left + newWidth;
102 static vector<LWindow*> sWindowList;
104vector<LWindow*> LedItDocumentWindow::sWindowList;
106static FilteredSFPutDLog::TypeSpec sPutFileTypeList[] = {
107 {
"HTML file", kTEXTFileType},
108 {
"Led Rich Text Format", kLedPrivateDocumentFileType},
109 {
"Microsoft Rich Text Format (RTF)", kTEXTFileType},
110 {
"Text file", kTEXTFileType},
113inline FileFormat MapPutFileTypeListIdxToFormat (
size_t typeIndex)
117 return (eHTMLFormat);
119 return (eLedPrivateFormat);
123 return (eTextFormat);
126 return (eTextFormat);
130inline size_t MapPutFileFormatToTypeListIdx (FileFormat format)
135 case eLedPrivateFormat:
147inline OSType MapFormatToOSType (FileFormat fileFormat)
149 switch (fileFormat) {
151 return (kTEXTFileType);
152 case eLedPrivateFormat:
153 return (kLedPrivateDocumentFileType);
155 return (kTEXTFileType);
157 return (kTEXTFileType);
159 return (kLedPrivateDocumentFileType);
161 return (kLedPrivateDocumentFileType);
176class Led_BusyCursor {
180 ::SetCursor (*::GetCursor (watchCursor));
189#if qStroika_Foundation_Common_Platform_Windows
192#ifndef _AFX_OLD_EXCEPTIONS
193#define DELETE_EXCEPTION(e) \
198#define DELETE_EXCEPTION(e)
201static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CString strFilterExt, CString strFilterName);
202static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate);
211#if qStroika_Foundation_Common_Platform_Windows
212FileFormat LedItDocument::sHiddenDocOpenArg = eUnknownFormat;
214IMPLEMENT_DYNCREATE (LedItDocument, COleServerDoc)
216BEGIN_MESSAGE_MAP (LedItDocument, COleServerDoc)
217ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE_LINK, OnUpdatePasteLinkMenu)
218ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_CONVERT, OnUpdateObjectVerbMenu)
219ON_COMMAND (ID_OLE_EDIT_CONVERT, OnEditConvert)
220ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_LINKS, OnUpdateEditLinksMenu)
221ON_COMMAND (ID_OLE_EDIT_LINKS, OnEditLinks)
222ON_UPDATE_COMMAND_UI (ID_OLE_VERB_FIRST, OnUpdateObjectVerbMenu)
223ON_UPDATE_COMMAND_UI (ID_FILE_SAVE, OnUpdateFileSave)
224ON_COMMAND (ID_FILE_SAVE_COPY_AS, OnFileSaveCopyAs)
227BEGIN_DISPATCH_MAP (LedItDocument, COleServerDoc)
235static const IID IID_ILedIt = {0xfc00622, 0x28bd, 0x11cf, {0x89, 0x9c, 0x0, 0xaa, 0x0, 0x58, 0x3, 0x24}};
237BEGIN_INTERFACE_MAP (LedItDocument, COleServerDoc)
238INTERFACE_PART (LedItDocument, IID_ILedIt, Dispatch)
243#if qStroika_Foundation_Common_Platform_MacOS
244LedItDocument::LedItDocument (LCommander* inSuper, FileFormat format)
245 : LSingleDoc (inSuper)
247#elif qStroika_Foundation_Common_Platform_Windows
248LedItDocument::LedItDocument ()
251#elif qStroika_FeatureSupported_XWindows
252LedItDocument::LedItDocument ()
259 , fParagraphDatabase ()
260 , fHidableTextDatabase ()
261 , fCommandHandler (kMaxNumUndoLevels)
263#if qStroika_Foundation_Common_Platform_MacOS
266#elif qStroika_Foundation_Common_Platform_Windows || qStroika_FeatureSupported_XWindows
267 fFileFormat (eDefaultFormat)
271#if qStroika_FeatureSupported_XWindows
274#if qStroika_Foundation_Common_Platform_MacOS
278#if qStroika_Foundation_Common_Platform_Windows
282 fTextStore.AddMarkerOwner (
this);
283 fStyleDatabase = MakeSharedPtr<StyleDatabaseRep> (fTextStore);
284 fParagraphDatabase = MakeSharedPtr<ParagraphDatabaseRep> (fTextStore);
285 fHidableTextDatabase = MakeSharedPtr<UniformHidableTextMarkerOwner> (fTextStore);
288LedItDocument::~LedItDocument ()
290#if qStroika_Foundation_Common_Platform_MacOS
291 if (mWindow != NULL) {
292 mWindow->PostAction (NULL);
300 fTextStore.RemoveMarkerOwner (
this);
301#if qStroika_Foundation_Common_Platform_Windows
302 ::AfxOleUnlockApp ();
306void LedItDocument::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
308 if (updateInfo.fRealContentUpdate) {
309#if qStroika_Foundation_Common_Platform_MacOS
311 SetUpdateCommandStatus (
true);
312#elif qStroika_Foundation_Common_Platform_Windows
318TextStore* LedItDocument::PeekAtTextStore ()
const
320 return &
const_cast<LedItDocument*
> (
this)->fTextStore;
323#if qStroika_FeatureSupported_XWindows
324void LedItDocument::LoadFromFile (
const string& fileName, FileFormat fileFormat)
326 Require (not fileName.empty ());
327 fPathName = fileName;
328 fFileFormat = fileFormat;
331#if qPrintGLIBTraceMessages
332 g_message (
"DOING LedItDocument::LoadFromFile (path= '%s', format=%d)\n", fPathName.c_str (), fileFormat);
335 StackBuffer<char> fileData{Memory::eUninitialized, fileLen};
336 int fd = ::open (fPathName.c_str (), O_RDONLY);
338 Execution::Throw (bad_alloc{});
340 fileLen = ::lseek (fd, 0, SEEK_END);
341 fileData.GrowToSize (fileLen);
343 ::lseek (fd, 0, SEEK_SET);
344 if (::read (fd, fileData, fileLen) !=
int (fileLen)) {
345 Execution::Throw (bad_alloc{});
354 StyledTextIOSrcStream_Memory source (fileData, fileLen);
355 WordProcessor::WordProcessorTextIOSinkStream sink (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
358 switch (fFileFormat) {
360 StyledTextIOReader_PlainText textReader (&source, &sink);
364 case eLedPrivateFormat: {
365 StyledTextIOReader_LedNativeFileFormat textReader (&source, &sink);
370 StyledTextIOReader_RTF textReader (&source, &sink, &fRTFInfo);
375 StyledTextIOReader_HTML textReader (&source, &sink, &fHTMLInfo);
379 case eUnknownFormat: {
385 SDKString suffix = ExtractFileSuffix (fPathName);
386 if (suffix ==
".rtf") {
387 fFileFormat = eRTFFormat;
390 if (suffix ==
".htm" or suffix ==
".html") {
391 fFileFormat = eHTMLFormat;
394 if (suffix ==
".led") {
395 fFileFormat = eLedPrivateFormat;
398 if (suffix ==
".txt") {
399 fFileFormat = eTextFormat;
404 StyledTextIOReader_RTF reader (&source, &sink, &fRTFInfo);
405 if (reader.QuickLookAppearsToBeRightFormat ()) {
406 fFileFormat = eRTFFormat;
416 StyledTextIOReader_LedNativeFileFormat reader (&source, &sink);
417 if (reader.QuickLookAppearsToBeRightFormat ()) {
418 fFileFormat = eLedPrivateFormat;
428 StyledTextIOReader_HTML reader (&source, &sink);
429 if (reader.QuickLookAppearsToBeRightFormat ()) {
430 fFileFormat = eHTMLFormat;
439 fFileFormat = eTextFormat;
451 fTextView->SetEmptySelectionStyle ();
455void LedItDocument::Save ()
458 g_message (
"DOING Save- '%s'\n", fPathName.c_str ());
459 Require (fFileFormat != eUnknownFormat);
461 WordProcessor::WordProcessorTextIOSrcStream source (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
462 StyledTextIOWriterSinkStream_Memory sink;
464 switch (fFileFormat) {
466 StyledTextIOWriter_PlainText textWriter (&source, &sink);
471 StyledTextIOWriter_RTF textWriter (&source, &sink, &fRTFInfo);
476 StyledTextIOWriter_HTML textWriter (&source, &sink, &fHTMLInfo);
480 case eLedPrivateFormat: {
481 StyledTextIOWriter_LedNativeFileFormat textWriter (&source, &sink);
489 int fd = ::open (fPathName.c_str (), O_RDWR | O_CREAT, 0666);
491 Execution::Throw (bad_alloc{});
494 ::lseek (fd, 0, SEEK_SET);
495 if (::write (fd, sink.PeekAtData (), sink.GetLength ()) != int (sink.GetLength ())) {
496 Execution::Throw (bad_alloc{});
507#if qStroika_Foundation_Common_Platform_MacOS
508const vector<LWindow*>& LedItDocument::GetDocumentWindows ()
510 return LedItDocumentWindow::sWindowList;
513void LedItDocument::DoSaveHelper ()
515 Led_BusyCursor busyCursor;
518 Execution::ThrowIfNull (mFile);
519 Execution::ThrowIfNull (mWindow);
521 mWindow->PostAction (NULL);
523 WordProcessor::WordProcessorTextIOSrcStream source (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
525 ThrowIfOSErr_ (::SetFPos (mFile->GetDataForkRefNum (), fsFromStart, 0));
526 StyledTextIOWriterSinkStream_FileDescriptor sink (mFile->GetDataForkRefNum ());
530 char* cheeseBuf = NULL;
532 cheeseBuf =
new char[64 * 1024];
533 sink.SetBufferSize (64 * 1024);
542 switch (fFileFormat) {
544 StyledTextIOWriter_PlainText textWriter (&source, &sink);
548 short curResFile = ::CurResFile ();
550 mFile->CreateNewFile (kApplicationSignature, kTEXTFileType, 0);
555 mFile->OpenResourceFork (fsRdWrPerm);
560 if (mFile->GetResourceForkRefNum () != -1) {
561 ::UseResFile (mFile->GetResourceForkRefNum ());
564 StScrpHandle macStyleHandle = (StScrpHandle)::Get1Resource (
'styl', 128);
565 if (macStyleHandle != NULL) {
566 ::RemoveResource (Handle (macStyleHandle));
569 vector<StyledInfoSummaryRecord> ledStyleRuns = fStyleDatabase->GetStyleInfo (0, fTextStore.GetLength ());
570 size_t nStyleRuns = ledStyleRuns.size ();
571 Assert (offsetof (StScrpRec, scrpStyleTab) ==
sizeof (
short));
572 macStyleHandle = (StScrpHandle)::Led_DoNewHandle (
sizeof (
short) + nStyleRuns *
sizeof (ScrpSTElement));
573 HLock (Handle (macStyleHandle));
574 (*macStyleHandle)->scrpNStyles = nStyleRuns;
575 StandardStyledTextImager::Convert (ledStyleRuns, (*macStyleHandle)->scrpStyleTab);
576 HUnlock (Handle (macStyleHandle));
578 ::AddResource (Handle (macStyleHandle),
'styl', 128,
"\p");
582 ::UseResFile (curResFile);
583 mFile->CloseResourceFork ();
587 ::UseResFile (curResFile);
588 mFile->CloseResourceFork ();
594 StyledTextIOWriter_RTF textWriter (&source, &sink);
599 StyledTextIOWriter_HTML textWriter (&source, &sink, &fHTMLInfo);
603 case eLedPrivateFormat: {
604 StyledTextIOWriter_LedNativeFileFormat textWriter (&source, &sink);
626void LedItDocument::NameNewDoc ()
630 ::GetIndString (name, STRx_Untitled, 1);
633 while (UWindows::FindNamedWindow (name) != nil) {
636 ::GetIndString (name, STRx_Untitled, 2);
639 ::NumToString (num, numStr);
640 LString::AppendPStr (name, numStr);
643 mWindow->SetDescriptor (name);
646void LedItDocument::OpenFile (
const FSSpec& inFileSpec)
652 Require (mFile == NULL);
653 mFile =
new LFile (inFileSpec);
656 ThrowIfError_ (::FSpGetFInfo (&inFileSpec, &docFinderInfo));
657 bool isStationary = docFinderInfo.fdFlags & kIsStationery;
658 bool openedReadOnly =
false;
660 mFile->OpenDataFork (fsRdWrPerm);
663 openedReadOnly =
true;
664 mFile->OpenDataFork (fsRdPerm);
669 fTextView->SetEmptySelectionStyle ();
675 mWindow->SetDescriptor (inFileSpec.name);
678 if (openedReadOnly or isStationary) {
682 mIsSpecified = not(openedReadOnly or isStationary);
683 mIsModified = isStationary;
694Boolean LedItDocument::IsModified ()
703void LedItDocument::DoAESave (FSSpec& inFileSpec, OSType inFileType)
708 mFile =
new LFile (inFileSpec);
710 OSType fileType = MapFormatToOSType (fFileFormat);
711 if (inFileType != fileType_Default) {
712 fileType = inFileType;
716 mFile->CreateNewDataFile (kApplicationSignature, fileType, 0);
717 mFile->OpenDataFork (fsRdWrPerm);
720 mWindow->SetDescriptor (inFileSpec.name);
727Boolean LedItDocument::AskSaveAs (FSSpec& outFSSpec, Boolean inRecordIt)
729 FilteredSFPutDLog filteredPicker (sPutFileTypeList, (
sizeof sPutFileTypeList) / (
sizeof sPutFileTypeList[0]));
732 GetDescriptor (defaultName);
733 size_t typeIndex = MapPutFileFormatToTypeListIdx (fFileFormat);
735 bool replacingFile =
false;
736 if (filteredPicker.PickFile (defaultName, &fileResult, &replacingFile, &typeIndex)) {
737 fFileFormat = MapPutFileTypeListIdxToFormat (typeIndex);
745 mIsSpecified =
false;
748 SendAESaveAs (fileResult, fileType_Default,
false);
751 ThrowIfOSErr_ (::FSpDelete (&fileResult));
753 DoAESave (fileResult, fileType_Default);
754 outFSSpec = fileResult;
759 mIsSpecified =
false;
769void LedItDocument::DoSave ()
774 mFile->GetSpecifier (fileSpec);
775 mWindow->SetDescriptor (fileSpec.name);
781void LedItDocument::DoRevert ()
783 fTextStore.Replace (fTextStore.GetStart (), fTextStore.GetEnd (), LED_TCHAR_OF (
""), 0);
784 fCommandHandler.Commit ();
786 fCommandHandler.Commit ();
791void LedItDocument::DoPrint ()
793 LPrintout* thePrintout = LPrintout::CreatePrintout (prto_TextDoc);
794 thePrintout->SetPrintSpec (mPrintSpec);
795 LPlaceHolder* textPlace = (LPlaceHolder*)thePrintout->FindPaneByID (
'TBox');
797 LedItView editorView;
798 editorView.AddAttributes (textAttr_MultiStyle | textAttr_Editable | textAttr_Selectable | textAttr_WordWrap);
799 editorView.SpecifyTextStore (&fTextStore);
800 editorView.SetStyleDatabase (fStyleDatabase);
801 editorView.SetParagraphDatabase (fParagraphDatabase);
802 editorView.SetHidableTextDatabase (fHidableTextDatabase);
803 editorView.SetScrollBarType (Led_PPView::v, Led_PPView::eScrollBarNever);
804 editorView.SetScrollBarType (Led_PPView::h, Led_PPView::eScrollBarNever);
805 textPlace->InstallOccupant (&editorView, atNone);
806 editorView.FinishCreate ();
807 editorView.SetForceAllRowsShowing (
false);
809 thePrintout->DoPrintJob ();
813void LedItDocument::PurgeUnneededMemory ()
816 fCommandHandler.Commit ();
820 fTextView->PurgeUnneededMemory ();
823void LedItDocument::BuildDocWindow (
const FSSpec* inFileSpec)
825 Assert (mWindow == NULL);
829 Led_CheckSomeLocalHeapRAMAvailable ();
831 mWindow =
new LedItDocumentWindow (WIND_TextDoc,
832 windAttr_Regular | windAttr_CloseBox | windAttr_TitleBar | windAttr_Resizable | windAttr_SizeBox |
833 windAttr_Zoomable | windAttr_Enabled | windAttr_Targetable,
835 mWindow->FinishCreate ();
843 WindowPtr theWindPtr = ::GetWindowFromPort (mWindow->GetMacPort ());
845 WindowPtr theWindPtr = mWindow->GetMacPort ();
847 Rect windowStructureRect = UWindows::GetWindowStructureRect (theWindPtr);
848 GDHandle dominantDevice = UWindows::FindDominantDevice (windowStructureRect);
849 Rect screenRect = (**dominantDevice).gdRect;
850 const int kSluffBetweenWindBottomAndScreenBottom = 10;
851 if (windowStructureRect.bottom + kSluffBetweenWindBottomAndScreenBottom < screenRect.bottom) {
852 Rect newWindBounds = UWindows::GetWindowContentRect (theWindPtr);
855 newWindBounds.bottom += (screenRect.bottom - windowStructureRect.bottom - kSluffBetweenWindBottomAndScreenBottom);
856 mWindow->DoSetBounds (newWindBounds);
860 SDimension16 winSize;
861 mWindow->GetFrameSize (winSize);
867 minMax.bottom = 10 * 1024;
868 minMax.right = 10 * 1024;
869 mWindow->SetMinMaxSize (minMax);
872 LedItView* editorView =
new LedItView ();
874 editorView->AddAttributes (textAttr_MultiStyle | textAttr_Editable | textAttr_Selectable | textAttr_WordWrap);
875 editorView->SpecifyTextStore (&fTextStore);
876 editorView->SetStyleDatabase (fStyleDatabase);
877 editorView->SetParagraphDatabase (fParagraphDatabase);
878 editorView->SetHidableTextDatabase (fHidableTextDatabase);
879 editorView->SetCommandHandler (&fCommandHandler);
880 editorView->SetSpellCheckEngine (&LedItApplication::Get ().fSpellCheckEngine);
881 editorView->PutInside (mWindow);
882 editorView->PlaceInSuperFrameAt (0, 0,
false);
883 editorView->ResizeFrameTo (winSize.width, winSize.height,
false);
884 SBooleanRect editViewBindings;
885 editViewBindings.top =
true;
886 editViewBindings.left =
true;
887 editViewBindings.bottom =
true;
888 editViewBindings.right =
true;
889 editorView->SetFrameBinding (editViewBindings);
890 editorView->FinishCreate ();
892 fTextView = editorView;
893 mWindow->SetLatentSub (editorView);
895 if (inFileSpec == NULL) {
899 OpenFile (*inFileSpec);
905void LedItDocument::DoReadCode ()
907 Led_BusyCursor busyCursor;
909 StScrpHandle styleInfo = NULL;
911 short curResFile = ::CurResFile ();
912 mFile->OpenResourceFork (fsRdPerm);
913 ::UseResFile (mFile->GetResourceForkRefNum ());
914 styleInfo = (StScrpHandle)::Get1Resource (
'styl', 128);
915 if (styleInfo != NULL) {
916 ::DetachResource ((Handle)styleInfo);
918 ::UseResFile (curResFile);
919 mFile->CloseResourceFork ();
924 ThrowIfOSErr_ (::SetFPos (mFile->GetDataForkRefNum (), fsFromStart, 0));
925 StyledTextIOSrcStream_FileDescriptor source (mFile->GetDataForkRefNum (), Handle (styleInfo));
926 WordProcessor::WordProcessorTextIOSinkStream sink (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
929 switch (fFileFormat) {
931 source.SetBufferSize (0);
932 if (styleInfo == NULL) {
933 StyledTextIOReader_PlainText textReader (&source, &sink);
937 StyledTextIOReader_STYLText textReader (&source, &sink);
943 source.SetBufferSize (16 * 1024);
944 StyledTextIOReader_RTF textReader (&source, &sink);
949 source.SetBufferSize (16 * 1024);
950 StyledTextIOReader_HTML textReader (&source, &sink, &fHTMLInfo);
954 case eLedPrivateFormat: {
956 StyledTextIOReader_LedNativeFileFormat textReader (&source, &sink);
972 source.SetBufferSize (1 * 1024);
976 StyledTextIOReader_RTF reader (&source, &sink);
977 if (reader.QuickLookAppearsToBeRightFormat ()) {
978 fFileFormat = eRTFFormat;
988 StyledTextIOReader_LedNativeFileFormat reader (&source, &sink);
989 if (reader.QuickLookAppearsToBeRightFormat ()) {
990 fFileFormat = eLedPrivateFormat;
1000 StyledTextIOReader_HTML reader (&source, &sink);
1001 if (reader.QuickLookAppearsToBeRightFormat ()) {
1002 fFileFormat = eHTMLFormat;
1011 fFileFormat = eTextFormat;
1017 if (styleInfo != NULL) {
1018 ::DisposeHandle ((Handle)styleInfo);
1022 if (styleInfo != NULL) {
1023 ::DisposeHandle ((Handle)styleInfo);
1027Boolean LedItDocument::ObeyCommand (CommandT inCommand,
void* ioParam)
1029 Boolean cmdHandled =
true;
1031 switch (inCommand) {
1032 case kCmdSaveACopyAs: {
1033 OnSaveACopyAsCommand ();
1037 cmdHandled = LSingleDoc::ObeyCommand (inCommand, ioParam);
1045void LedItDocument::FindCommandStatus (CommandT inCommand, Boolean& outEnabled, Boolean& outUsesMark, UInt16& outMark, Str255 outName)
1047 outUsesMark =
false;
1048 switch (inCommand) {
1049 case kCmdSaveACopyAs: {
1054 LSingleDoc::FindCommandStatus (inCommand, outEnabled, outUsesMark, outMark, outName);
1059void LedItDocument::OnSaveACopyAsCommand ()
1061 FilteredSFPutDLog filteredPicker (sPutFileTypeList, (
sizeof sPutFileTypeList) / (
sizeof sPutFileTypeList[0]));
1064 GetDescriptor (defaultName);
1065 size_t typeIndex = MapPutFileFormatToTypeListIdx (fFileFormat);
1067 bool replacingFile =
false;
1068 if (filteredPicker.PickFile (defaultName, &fileResult, &replacingFile, &typeIndex)) {
1069 if (replacingFile) {
1070 ThrowIfOSErr_ (::FSpDelete (&fileResult));
1073 FileFormat savedFileFormat = fFileFormat;
1074 LFile* savedFile = mFile;
1076 fFileFormat = MapPutFileTypeListIdxToFormat (typeIndex);
1078 mFile =
new LFile (fileResult);
1080 OSType fileType = MapFormatToOSType (fFileFormat);
1083 mFile->CreateNewDataFile (kApplicationSignature, fileType, 0);
1084 mFile->OpenDataFork (fsRdWrPerm);
1090 fFileFormat = savedFileFormat;
1093 fFileFormat = savedFileFormat;
1100#if qStroika_Foundation_Common_Platform_Windows
1101BOOL LedItDocument::OnNewDocument ()
1103 fCommandHandler.Commit ();
1104 if (!COleServerDoc::OnNewDocument ()) {
1107 fFileFormat = eDefaultFormat;
1108 fStyleDatabase = MakeSharedPtr<StyleDatabaseRep> (fTextStore);
1109 fParagraphDatabase = MakeSharedPtr<ParagraphDatabaseRep> (fTextStore);
1110 fHidableTextDatabase = MakeSharedPtr<UniformHidableTextMarkerOwner> (fTextStore);
1114COleServerItem* LedItDocument::OnGetEmbeddedItem ()
1118 LedItServerItem* pItem =
new LedItServerItem (
this);
1119 ASSERT_VALID (pItem);
1123BOOL LedItDocument::DoSave (LPCTSTR lpszPathName, BOOL bReplace)
1125 FileFormat fileFormat = fFileFormat;
1127 CString newName = lpszPathName;
1128 if (newName.IsEmpty ()) {
1129 CDocTemplate* pTemplate = GetDocTemplate ();
1130 ASSERT (pTemplate != NULL);
1131 newName = m_strPathName;
1132 if (bReplace && newName.IsEmpty ()) {
1133 newName = m_strTitle;
1135 int iBad = newName.FindOneOf (_T(
" #%;/\\"));
1137 newName.ReleaseBuffer (iBad);
1142 if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
1143 !strExt.IsEmpty()) {
1144 ASSERT(strExt[0] ==
'.');
1151 if (not DoPromptSaveAsFileName (newName, &fileFormat)) {
1156 if (not DoPromptSaveCopyAsFileName (newName, &fileFormat)) {
1167 FileFormat realSavedDocFormat = fFileFormat;
1168 fFileFormat = fileFormat;
1170 if (!OnSaveDocument (newName)) {
1171 if (lpszPathName == NULL) {
1175 CFile::Remove (newName);
1179 TRACE0 (
"Warning: failed to delete file after failed SaveAs.\n");
1180 DELETE_EXCEPTION (e);
1188 fFileFormat = realSavedDocFormat;
1191 fFileFormat = realSavedDocFormat;
1195 SetPathName (newName);
1196 fFileFormat = fileFormat;
1202void LedItDocument::Serialize (CArchive& ar)
1204 if (ar.IsStoring ()) {
1205 Require (fFileFormat != eUnknownFormat);
1208 StyledTextIOWriterSinkStream_Memory sink;
1210 switch (fFileFormat) {
1212 StyledTextIOWriter_PlainText textWriter{&source, &sink};
1213 textWriter.Write ();
1217 StyledTextIOWriter_RTF textWriter{&source, &sink, &fRTFInfo};
1218 textWriter.Write ();
1222 StyledTextIOWriter_HTML textWriter{&source, &sink, &fHTMLInfo};
1223 textWriter.Write ();
1226 case eLedPrivateFormat: {
1227 StyledTextIOWriter_LedNativeFileFormat textWriter{&source, &sink};
1228 textWriter.Write ();
1235 ar.Write ((
char*)sink.PeekAtData (),
static_cast<UINT
> (sink.GetLength ()));
1250 POSITION pos = GetFirstViewPosition ();
1251 for (CView* p = GetNextView (pos); p != NULL; p = GetNextView (pos)) {
1252 LedItView* v =
dynamic_cast<LedItView*
> (p);
1258 CFile* file = ar.GetFile ();
1259 ASSERT_VALID (file);
1260 DWORD nLen =
static_cast<DWORD
> (file->GetLength ());
1261 StackBuffer<char> buf{Memory::eUninitialized, nLen};
1262 if (ar.Read (buf.data (), nLen) != nLen) {
1263 AfxThrowArchiveException (CArchiveException::endOfFile);
1265 StyledTextIOSrcStream_Memory source{buf.data (), nLen};
1269 switch (fFileFormat) {
1271 StyledTextIOReader_PlainText textReader{&source, &sink};
1275 case eLedPrivateFormat: {
1276 LedItControlItem::DocContextDefiner tmp{
this};
1277 StyledTextIOReader_LedNativeFileFormat textReader{&source, &sink};
1282 LedItControlItem::DocContextDefiner tmp{
this};
1283 StyledTextIOReader_RTF textReader{&source, &sink, &fRTFInfo};
1288 StyledTextIOReader_HTML textReader{&source, &sink, &fHTMLInfo};
1292 case eUnknownFormat: {
1299 StyledTextIOReader_RTF reader{&source, &sink, &fRTFInfo};
1300 if (reader.QuickLookAppearsToBeRightFormat ()) {
1301 fFileFormat = eRTFFormat;
1311 StyledTextIOReader_LedNativeFileFormat reader{&source, &sink};
1312 if (reader.QuickLookAppearsToBeRightFormat ()) {
1313 fFileFormat = eLedPrivateFormat;
1323 StyledTextIOReader_HTML reader{&source, &sink};
1324 if (reader.QuickLookAppearsToBeRightFormat ()) {
1325 fFileFormat = eHTMLFormat;
1334 fFileFormat = eTextFormat;
1346BOOL LedItDocument::OnOpenDocument (LPCTSTR lpszPathName)
1357 POSITION pos = GetFirstViewPosition ();
1358 for (CView* p = GetNextView (pos); p != NULL; p = GetNextView (pos)) {
1359 LedItView* v =
dynamic_cast<LedItView*
> (p);
1366 fCommandHandler.Commit ();
1367 fStyleDatabase = MakeSharedPtr<StyleDatabaseRep> (fTextStore);
1368 fParagraphDatabase = MakeSharedPtr<ParagraphDatabaseRep> (fTextStore);
1369 fHidableTextDatabase = MakeSharedPtr<UniformHidableTextMarkerOwner> (fTextStore);
1373 POSITION pos = GetFirstViewPosition ();
1374 while (pos != NULL) {
1375 CView* pView = GetNextView (pos);
1376 pView->OnInitialUpdate ();
1380 WordProcessor::WordProcessorFlavorPackageInternalizer internalizer (fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
1382 Led_ClipFormat readFileFormat = kBadClipFormat;
1392 switch (sHiddenDocOpenArg) {
1394 readFileFormat = kTEXTClipFormat;
1396 case eLedPrivateFormat:
1397 readFileFormat = kLedPrivateClipFormat;
1400 readFileFormat = kRTFClipFormat;
1403 readFileFormat = kHTMLClipFormat;
1407 internalizer.InternalizeFlavor_FILEData (lpszPathName, &readFileFormat, NULL, 0, fTextStore.GetEnd ());
1410 if (readFileFormat == kTEXTClipFormat) {
1411 fFileFormat = eTextFormat;
1413 else if (readFileFormat == kLedPrivateClipFormat) {
1414 fFileFormat = eLedPrivateFormat;
1416 else if (readFileFormat == kRTFClipFormat) {
1417 fFileFormat = eRTFFormat;
1419 else if (readFileFormat == kHTMLClipFormat) {
1420 fFileFormat = eHTMLFormat;
1424 fFileFormat = eDefaultFormat;
1427 SetModifiedFlag (FALSE);
1432void LedItDocument::OnUpdateFileSave (CCmdUI* pCmdUI)
1434 ASSERT_VALID (
this);
1437 pCmdUI->Enable (IsModified () or GetPathName ().GetLength () == 0);
1440void LedItDocument::OnFileSaveCopyAs ()
1442 ASSERT_VALID (
this);
1443 Assert (m_bRemember);
1445 LPSTORAGE savedStorage = m_lpRootStg;
1448 FileFormat savedFileFormat = fFileFormat;
1451 DoSave (NULL,
false);
1454 m_lpRootStg = savedStorage;
1456 fFileFormat = savedFileFormat;
1460 m_lpRootStg = savedStorage;
1462 fFileFormat = savedFileFormat;
1465void LedItDocument::DeleteContents ()
1467 fTextStore.Replace (fTextStore.GetStart (), fTextStore.GetEnd (), LED_TCHAR_OF (
""), 0);
1470bool LedItDocument::DoPromptSaveAsFileName (CString& fileName, FileFormat* fileFormat)
1473 return DoPromptFileName (fileName, AFX_IDS_SAVEFILE,
false, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, fileFormat);
1476bool LedItDocument::DoPromptSaveCopyAsFileName (CString& fileName, FileFormat* fileFormat)
1479 return DoPromptFileName (fileName, AFX_IDS_SAVEFILECOPY,
false, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, fileFormat);
1482bool LedItDocument::DoPromptOpenFileName (CString& fileName, FileFormat* fileFormat)
1485 return DoPromptFileName (fileName, AFX_IDS_OPENFILE,
true, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, fileFormat);
1488bool LedItDocument::DoPromptFileName (CString& fileName, UINT nIDSTitle,
bool isOpenDialogCall,
long fileDLogFlags, FileFormat* fileFormat)
1491 CFileDialog dlgFile{isOpenDialogCall};
1494 Verify (title.LoadString (nIDSTitle));
1496 dlgFile.m_ofn.Flags |= fileDLogFlags;
1500 CDocTemplate* ledItPrivateDocFormatTemplate = NULL;
1503 POSITION pos = AfxGetApp ()->m_pDocManager->GetFirstDocTemplatePosition ();
1504 ledItPrivateDocFormatTemplate = AfxGetApp ()->m_pDocManager->GetNextDocTemplate (pos);
1506 if (nIDSTitle == AFX_IDS_OPENFILE) {
1507 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.htm;*.html;*.led;*.rtf;*.txt;",
"All Recognized (*.htm;*.html;*.led;*.rtf;*.txt)");
1508 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
".*",
"All Files (*.*)");
1510 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.htm;*.html",
"HTML file (*.htm;*.html)");
1511 AppendFilterSuffix (strFilter, dlgFile.m_ofn, ledItPrivateDocFormatTemplate);
1512 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.rtf",
"Microsoft Rich Text Format (*.rtf)");
1513 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.txt",
"Plain Text (*.txt)");
1515 strFilter += (TCHAR)
'\0';
1517 dlgFile.m_ofn.lpstrFilter = strFilter;
1518 dlgFile.m_ofn.lpstrTitle = title;
1521 dlgFile.m_ofn.lpstrFile = fileName.GetBuffer (_MAX_PATH);
1523 if (nIDSTitle == AFX_IDS_OPENFILE) {
1524 dlgFile.m_ofn.nFilterIndex = 1;
1527 FileFormat initialFormat = *fileFormat;
1528 if (initialFormat == eUnknownFormat) {
1529 initialFormat = eDefaultFormat;
1531 switch (initialFormat) {
1533 dlgFile.m_ofn.nFilterIndex = 1;
1535 case eLedPrivateFormat:
1536 dlgFile.m_ofn.nFilterIndex = 2;
1539 dlgFile.m_ofn.nFilterIndex = 3;
1542 dlgFile.m_ofn.nFilterIndex = 4;
1549 bool bResult = (dlgFile.DoModal () == IDOK);
1550 fileName.ReleaseBuffer ();
1552 if (nIDSTitle == AFX_IDS_OPENFILE) {
1553 switch (dlgFile.m_ofn.nFilterIndex) {
1555 *fileFormat = eUnknownFormat;
1558 *fileFormat = eUnknownFormat;
1561 *fileFormat = eHTMLFormat;
1564 *fileFormat = eLedPrivateFormat;
1567 *fileFormat = eRTFFormat;
1570 *fileFormat = eTextFormat;
1573 *fileFormat = eUnknownFormat;
1578 switch (dlgFile.m_ofn.nFilterIndex) {
1580 *fileFormat = eHTMLFormat;
1583 *fileFormat = eLedPrivateFormat;
1586 *fileFormat = eRTFFormat;
1589 *fileFormat = eTextFormat;
1592 *fileFormat = eUnknownFormat;
1599 if (not(fileDLogFlags & OFN_FILEMUSTEXIST)) {
1600 if (dlgFile.GetFileExt () ==
"") {
1601 switch (*fileFormat) {
1609 fileName +=
".html";
1611 case eLedPrivateFormat:
1621#if qStroika_Foundation_Debug_AssertionsChecked
1622void LedItDocument::AssertValid ()
const
1624 COleServerDoc::AssertValid ();
1625 fTextStore.Invariant ();
1638SDKString ExtractFileSuffix (
const SDKString& from)
1640 size_t i = from.rfind (
'.');
1641 if (i == SDKString::npos) {
1646 for (
size_t j = 0; j < suffix.length (); ++j) {
1647 if (isascii (suffix[j]) and isupper (suffix[j])) {
1648 suffix[j] =
static_cast<Led_tChar
> (tolower (suffix[j]));
1655#if qStroika_Foundation_Common_Platform_Windows
1662static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CString strFilterExt, CString strFilterName)
1664 Require (not strFilterExt.IsEmpty ());
1665 Require (not strFilterName.IsEmpty ());
1668 filter += strFilterName;
1669 ASSERT (!filter.IsEmpty ());
1670 filter += (TCHAR)
'\0';
1671 filter += (TCHAR)
'*';
1672 filter += strFilterExt;
1673 filter += (TCHAR)
'\0';
1674 ++ofn.nMaxCustFilter;
1677static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate)
1679 ASSERT_VALID (pTemplate);
1680 ASSERT_KINDOF (CDocTemplate, pTemplate);
1681 CString strFilterExt;
1682 CString strFilterName;
1683 if (pTemplate->GetDocString (strFilterExt, CDocTemplate::filterExt) && !strFilterExt.IsEmpty () &&
1684 pTemplate->GetDocString (strFilterName, CDocTemplate::filterName) && !strFilterName.IsEmpty ()) {
1685 AppendFilterSuffix (filter, ofn, strFilterExt, strFilterName);
#define RequireNotNull(p)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
basic_string< SDKChar > SDKString