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
33#include "Stroika/Frameworks/Led/SpellCheckEngine_Basic.h"
34#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_LedNative.h"
35#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_PlainText.h"
36#if qStroika_Foundation_Common_Platform_MacOS
37#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_STYLText.h"
40#if qStroika_Foundation_Common_Platform_MacOS
41#include "Stroika/Frameworks/Led/FilteredFilePicker.h"
42#elif qStroika_Foundation_Common_Platform_Windows
43#include "LedItControlItem.h"
44#include "LedItServerItem.h"
49#include "LedItApplication.h"
51#include "LedItDocument.h"
54using namespace Stroika::Frameworks::Led;
55using namespace Stroika::Frameworks::Led::Platform;
56using namespace Stroika::Frameworks::Led::StyledTextIO;
60#if qStroika_Foundation_Common_Platform_MacOS
61class LedItDocumentWindow :
public LWindow {
63 LedItDocumentWindow (ResIDT inWINDid, UInt32 inAttributes, LCommander* inSuper)
64 : LWindow (inWINDid, inAttributes, inSuper)
66 sWindowList.push_back (
this);
67 ::AppendMenu (::GetMenuHandle (kWindowsMenuID),
"\pREPLACEME");
68 LMenu* windowMenu = LMenuBar::GetCurrentMenuBar ()->FetchMenu (kWindowsMenuID);
69 AssertNotNil (windowMenu);
70 size_t nMenuItems = ::CountMenuItems (windowMenu->GetMacMenuH ());
71 for (
size_t i = 1; i <= nMenuItems; ++i) {
72 windowMenu->SetCommand (i, i - 1 + kBaseWindowCmd);
76 ~LedItDocumentWindow ()
79 sWindowList.erase (std::find (sWindowList.begin (), sWindowList.end (), w));
80 LMenu* windowMenu = LMenuBar::GetCurrentMenuBar ()->FetchMenu (kWindowsMenuID);
81 AssertNotNil (windowMenu);
82 windowMenu->RemoveItem (1);
83 size_t nMenuItems = ::CountMenuItems (windowMenu->GetMacMenuH ());
84 for (
size_t i = 1; i <= nMenuItems; ++i) {
85 windowMenu->SetCommand (i, i - 1 + kBaseWindowCmd);
90 virtual void CalcStandardBoundsForScreen (
const Rect& inScreenBounds, Rect& outStdBounds)
const override
92 LWindow::CalcStandardBoundsForScreen (inScreenBounds, outStdBounds);
93 short winWidth = ::GetRectWidth (outStdBounds);
94 short desiredWidth = 8.5 * 72;
95 short newWidth = Led_Min (winWidth, desiredWidth);
96 outStdBounds.right = outStdBounds.left + newWidth;
100 static vector<LWindow*> sWindowList;
102vector<LWindow*> LedItDocumentWindow::sWindowList;
104static FilteredSFPutDLog::TypeSpec sPutFileTypeList[] = {
105 {
"HTML file", kTEXTFileType},
106 {
"Led Rich Text Format", kLedPrivateDocumentFileType},
107 {
"Microsoft Rich Text Format (RTF)", kTEXTFileType},
108 {
"Text file", kTEXTFileType},
111inline FileFormat MapPutFileTypeListIdxToFormat (
size_t typeIndex)
115 return (eHTMLFormat);
117 return (eLedPrivateFormat);
121 return (eTextFormat);
124 return (eTextFormat);
128inline size_t MapPutFileFormatToTypeListIdx (FileFormat format)
133 case eLedPrivateFormat:
145inline OSType MapFormatToOSType (FileFormat fileFormat)
147 switch (fileFormat) {
149 return (kTEXTFileType);
150 case eLedPrivateFormat:
151 return (kLedPrivateDocumentFileType);
153 return (kTEXTFileType);
155 return (kTEXTFileType);
157 return (kLedPrivateDocumentFileType);
159 return (kLedPrivateDocumentFileType);
174class Led_BusyCursor {
178 ::SetCursor (*::GetCursor (watchCursor));
187#if qStroika_Foundation_Common_Platform_Windows
190#ifndef _AFX_OLD_EXCEPTIONS
191#define DELETE_EXCEPTION(e) \
196#define DELETE_EXCEPTION(e)
199static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CString strFilterExt, CString strFilterName);
200static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate);
209#if qStroika_Foundation_Common_Platform_Windows
210FileFormat LedItDocument::sHiddenDocOpenArg = eUnknownFormat;
212IMPLEMENT_DYNCREATE (LedItDocument, COleServerDoc)
214BEGIN_MESSAGE_MAP (LedItDocument, COleServerDoc)
215ON_UPDATE_COMMAND_UI (ID_EDIT_PASTE_LINK, OnUpdatePasteLinkMenu)
216ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_CONVERT, OnUpdateObjectVerbMenu)
217ON_COMMAND (ID_OLE_EDIT_CONVERT, OnEditConvert)
218ON_UPDATE_COMMAND_UI (ID_OLE_EDIT_LINKS, OnUpdateEditLinksMenu)
219ON_COMMAND (ID_OLE_EDIT_LINKS, OnEditLinks)
220ON_UPDATE_COMMAND_UI (ID_OLE_VERB_FIRST, OnUpdateObjectVerbMenu)
221ON_UPDATE_COMMAND_UI (ID_FILE_SAVE, OnUpdateFileSave)
222ON_COMMAND (ID_FILE_SAVE_COPY_AS, OnFileSaveCopyAs)
225BEGIN_DISPATCH_MAP (LedItDocument, COleServerDoc)
233static const IID IID_ILedIt = {0xfc00622, 0x28bd, 0x11cf, {0x89, 0x9c, 0x0, 0xaa, 0x0, 0x58, 0x3, 0x24}};
235BEGIN_INTERFACE_MAP (LedItDocument, COleServerDoc)
236INTERFACE_PART (LedItDocument, IID_ILedIt, Dispatch)
241#if qStroika_Foundation_Common_Platform_MacOS
242LedItDocument::LedItDocument (LCommander* inSuper, FileFormat format)
243 : LSingleDoc (inSuper)
245#elif qStroika_Foundation_Common_Platform_Windows
246LedItDocument::LedItDocument ()
249#elif qStroika_FeatureSupported_XWindows
250LedItDocument::LedItDocument ()
257 , fParagraphDatabase ()
258 , fHidableTextDatabase ()
259 , fCommandHandler (kMaxNumUndoLevels)
261#if qStroika_Foundation_Common_Platform_MacOS
264#elif qStroika_Foundation_Common_Platform_Windows || qStroika_FeatureSupported_XWindows
265 fFileFormat (eDefaultFormat)
269#if qStroika_FeatureSupported_XWindows
272#if qStroika_Foundation_Common_Platform_MacOS
276#if qStroika_Foundation_Common_Platform_Windows
280 fTextStore.AddMarkerOwner (
this);
281 fStyleDatabase = make_shared<StyleDatabaseRep> (fTextStore);
282 fParagraphDatabase = make_shared<ParagraphDatabaseRep> (fTextStore);
283 fHidableTextDatabase = make_shared<UniformHidableTextMarkerOwner> (fTextStore);
286LedItDocument::~LedItDocument ()
288#if qStroika_Foundation_Common_Platform_MacOS
289 if (mWindow != NULL) {
290 mWindow->PostAction (NULL);
298 fTextStore.RemoveMarkerOwner (
this);
299#if qStroika_Foundation_Common_Platform_Windows
300 ::AfxOleUnlockApp ();
304void LedItDocument::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
306 if (updateInfo.fRealContentUpdate) {
307#if qStroika_Foundation_Common_Platform_MacOS
309 SetUpdateCommandStatus (
true);
310#elif qStroika_Foundation_Common_Platform_Windows
316TextStore* LedItDocument::PeekAtTextStore ()
const
318 return &
const_cast<LedItDocument*
> (
this)->fTextStore;
321#if qStroika_FeatureSupported_XWindows
322void LedItDocument::LoadFromFile (
const string& fileName, FileFormat fileFormat)
324 Require (not fileName.empty ());
325 fPathName = fileName;
326 fFileFormat = fileFormat;
329#if qPrintGLIBTraceMessages
330 g_message (
"DOING LedItDocument::LoadFromFile (path= '%s', format=%d)\n", fPathName.c_str (), fileFormat);
333 StackBuffer<char> fileData{Memory::eUninitialized, fileLen};
334 int fd = ::open (fPathName.c_str (), O_RDONLY);
336 Execution::Throw (bad_alloc{});
338 fileLen = ::lseek (fd, 0, SEEK_END);
339 fileData.GrowToSize (fileLen);
341 ::lseek (fd, 0, SEEK_SET);
342 if (::read (fd, fileData, fileLen) !=
int (fileLen)) {
343 Execution::Throw (bad_alloc{});
352 StyledTextIOSrcStream_Memory source (fileData, fileLen);
353 WordProcessor::WordProcessorTextIOSinkStream sink (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
356 switch (fFileFormat) {
358 StyledTextIOReader_PlainText textReader (&source, &sink);
362 case eLedPrivateFormat: {
363 StyledTextIOReader_LedNativeFileFormat textReader (&source, &sink);
368 StyledTextIOReader_RTF textReader (&source, &sink, &fRTFInfo);
373 StyledTextIOReader_HTML textReader (&source, &sink, &fHTMLInfo);
377 case eUnknownFormat: {
383 SDKString suffix = ExtractFileSuffix (fPathName);
384 if (suffix ==
".rtf") {
385 fFileFormat = eRTFFormat;
388 if (suffix ==
".htm" or suffix ==
".html") {
389 fFileFormat = eHTMLFormat;
392 if (suffix ==
".led") {
393 fFileFormat = eLedPrivateFormat;
396 if (suffix ==
".txt") {
397 fFileFormat = eTextFormat;
402 StyledTextIOReader_RTF reader (&source, &sink, &fRTFInfo);
403 if (reader.QuickLookAppearsToBeRightFormat ()) {
404 fFileFormat = eRTFFormat;
414 StyledTextIOReader_LedNativeFileFormat reader (&source, &sink);
415 if (reader.QuickLookAppearsToBeRightFormat ()) {
416 fFileFormat = eLedPrivateFormat;
426 StyledTextIOReader_HTML reader (&source, &sink);
427 if (reader.QuickLookAppearsToBeRightFormat ()) {
428 fFileFormat = eHTMLFormat;
437 fFileFormat = eTextFormat;
449 fTextView->SetEmptySelectionStyle ();
453void LedItDocument::Save ()
456 g_message (
"DOING Save- '%s'\n", fPathName.c_str ());
457 Require (fFileFormat != eUnknownFormat);
459 WordProcessor::WordProcessorTextIOSrcStream source (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
460 StyledTextIOWriterSinkStream_Memory sink;
462 switch (fFileFormat) {
464 StyledTextIOWriter_PlainText textWriter (&source, &sink);
469 StyledTextIOWriter_RTF textWriter (&source, &sink, &fRTFInfo);
474 StyledTextIOWriter_HTML textWriter (&source, &sink, &fHTMLInfo);
478 case eLedPrivateFormat: {
479 StyledTextIOWriter_LedNativeFileFormat textWriter (&source, &sink);
487 int fd = ::open (fPathName.c_str (), O_RDWR | O_CREAT, 0666);
489 Execution::Throw (bad_alloc{});
492 ::lseek (fd, 0, SEEK_SET);
493 if (::write (fd, sink.PeekAtData (), sink.GetLength ()) != int (sink.GetLength ())) {
494 Execution::Throw (bad_alloc{});
505#if qStroika_Foundation_Common_Platform_MacOS
506const vector<LWindow*>& LedItDocument::GetDocumentWindows ()
508 return LedItDocumentWindow::sWindowList;
511void LedItDocument::DoSaveHelper ()
513 Led_BusyCursor busyCursor;
516 Execution::ThrowIfNull (mFile);
517 Execution::ThrowIfNull (mWindow);
519 mWindow->PostAction (NULL);
521 WordProcessor::WordProcessorTextIOSrcStream source (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
523 ThrowIfOSErr_ (::SetFPos (mFile->GetDataForkRefNum (), fsFromStart, 0));
524 StyledTextIOWriterSinkStream_FileDescriptor sink (mFile->GetDataForkRefNum ());
528 char* cheeseBuf = NULL;
530 cheeseBuf =
new char[64 * 1024];
531 sink.SetBufferSize (64 * 1024);
540 switch (fFileFormat) {
542 StyledTextIOWriter_PlainText textWriter (&source, &sink);
546 short curResFile = ::CurResFile ();
548 mFile->CreateNewFile (kApplicationSignature, kTEXTFileType, 0);
553 mFile->OpenResourceFork (fsRdWrPerm);
558 if (mFile->GetResourceForkRefNum () != -1) {
559 ::UseResFile (mFile->GetResourceForkRefNum ());
562 StScrpHandle macStyleHandle = (StScrpHandle)::Get1Resource (
'styl', 128);
563 if (macStyleHandle != NULL) {
564 ::RemoveResource (Handle (macStyleHandle));
567 vector<StyledInfoSummaryRecord> ledStyleRuns = fStyleDatabase->GetStyleInfo (0, fTextStore.GetLength ());
568 size_t nStyleRuns = ledStyleRuns.size ();
569 Assert (offsetof (StScrpRec, scrpStyleTab) ==
sizeof (
short));
570 macStyleHandle = (StScrpHandle)::Led_DoNewHandle (
sizeof (
short) + nStyleRuns *
sizeof (ScrpSTElement));
571 HLock (Handle (macStyleHandle));
572 (*macStyleHandle)->scrpNStyles = nStyleRuns;
573 StandardStyledTextImager::Convert (ledStyleRuns, (*macStyleHandle)->scrpStyleTab);
574 HUnlock (Handle (macStyleHandle));
576 ::AddResource (Handle (macStyleHandle),
'styl', 128,
"\p");
580 ::UseResFile (curResFile);
581 mFile->CloseResourceFork ();
585 ::UseResFile (curResFile);
586 mFile->CloseResourceFork ();
592 StyledTextIOWriter_RTF textWriter (&source, &sink);
597 StyledTextIOWriter_HTML textWriter (&source, &sink, &fHTMLInfo);
601 case eLedPrivateFormat: {
602 StyledTextIOWriter_LedNativeFileFormat textWriter (&source, &sink);
624void LedItDocument::NameNewDoc ()
628 ::GetIndString (name, STRx_Untitled, 1);
631 while (UWindows::FindNamedWindow (name) != nil) {
634 ::GetIndString (name, STRx_Untitled, 2);
637 ::NumToString (num, numStr);
638 LString::AppendPStr (name, numStr);
641 mWindow->SetDescriptor (name);
644void LedItDocument::OpenFile (
const FSSpec& inFileSpec)
650 Require (mFile == NULL);
651 mFile =
new LFile (inFileSpec);
654 ThrowIfError_ (::FSpGetFInfo (&inFileSpec, &docFinderInfo));
655 bool isStationary = docFinderInfo.fdFlags & kIsStationery;
656 bool openedReadOnly =
false;
658 mFile->OpenDataFork (fsRdWrPerm);
661 openedReadOnly =
true;
662 mFile->OpenDataFork (fsRdPerm);
667 fTextView->SetEmptySelectionStyle ();
673 mWindow->SetDescriptor (inFileSpec.name);
676 if (openedReadOnly or isStationary) {
680 mIsSpecified = not(openedReadOnly or isStationary);
681 mIsModified = isStationary;
692Boolean LedItDocument::IsModified ()
701void LedItDocument::DoAESave (FSSpec& inFileSpec, OSType inFileType)
706 mFile =
new LFile (inFileSpec);
708 OSType fileType = MapFormatToOSType (fFileFormat);
709 if (inFileType != fileType_Default) {
710 fileType = inFileType;
714 mFile->CreateNewDataFile (kApplicationSignature, fileType, 0);
715 mFile->OpenDataFork (fsRdWrPerm);
718 mWindow->SetDescriptor (inFileSpec.name);
725Boolean LedItDocument::AskSaveAs (FSSpec& outFSSpec, Boolean inRecordIt)
727 FilteredSFPutDLog filteredPicker (sPutFileTypeList, (
sizeof sPutFileTypeList) / (
sizeof sPutFileTypeList[0]));
730 GetDescriptor (defaultName);
731 size_t typeIndex = MapPutFileFormatToTypeListIdx (fFileFormat);
733 bool replacingFile =
false;
734 if (filteredPicker.PickFile (defaultName, &fileResult, &replacingFile, &typeIndex)) {
735 fFileFormat = MapPutFileTypeListIdxToFormat (typeIndex);
743 mIsSpecified =
false;
746 SendAESaveAs (fileResult, fileType_Default,
false);
749 ThrowIfOSErr_ (::FSpDelete (&fileResult));
751 DoAESave (fileResult, fileType_Default);
752 outFSSpec = fileResult;
757 mIsSpecified =
false;
767void LedItDocument::DoSave ()
772 mFile->GetSpecifier (fileSpec);
773 mWindow->SetDescriptor (fileSpec.name);
779void LedItDocument::DoRevert ()
781 fTextStore.Replace (fTextStore.GetStart (), fTextStore.GetEnd (), LED_TCHAR_OF (
""), 0);
782 fCommandHandler.Commit ();
784 fCommandHandler.Commit ();
789void LedItDocument::DoPrint ()
791 LPrintout* thePrintout = LPrintout::CreatePrintout (prto_TextDoc);
792 thePrintout->SetPrintSpec (mPrintSpec);
793 LPlaceHolder* textPlace = (LPlaceHolder*)thePrintout->FindPaneByID (
'TBox');
795 LedItView editorView;
796 editorView.AddAttributes (textAttr_MultiStyle | textAttr_Editable | textAttr_Selectable | textAttr_WordWrap);
797 editorView.SpecifyTextStore (&fTextStore);
798 editorView.SetStyleDatabase (fStyleDatabase);
799 editorView.SetParagraphDatabase (fParagraphDatabase);
800 editorView.SetHidableTextDatabase (fHidableTextDatabase);
801 editorView.SetScrollBarType (Led_PPView::v, Led_PPView::eScrollBarNever);
802 editorView.SetScrollBarType (Led_PPView::h, Led_PPView::eScrollBarNever);
803 textPlace->InstallOccupant (&editorView, atNone);
804 editorView.FinishCreate ();
805 editorView.SetForceAllRowsShowing (
false);
807 thePrintout->DoPrintJob ();
811void LedItDocument::PurgeUnneededMemory ()
814 fCommandHandler.Commit ();
818 fTextView->PurgeUnneededMemory ();
821void LedItDocument::BuildDocWindow (
const FSSpec* inFileSpec)
823 Assert (mWindow == NULL);
827 Led_CheckSomeLocalHeapRAMAvailable ();
829 mWindow =
new LedItDocumentWindow (WIND_TextDoc,
830 windAttr_Regular | windAttr_CloseBox | windAttr_TitleBar | windAttr_Resizable | windAttr_SizeBox |
831 windAttr_Zoomable | windAttr_Enabled | windAttr_Targetable,
833 mWindow->FinishCreate ();
841 WindowPtr theWindPtr = ::GetWindowFromPort (mWindow->GetMacPort ());
843 WindowPtr theWindPtr = mWindow->GetMacPort ();
845 Rect windowStructureRect = UWindows::GetWindowStructureRect (theWindPtr);
846 GDHandle dominantDevice = UWindows::FindDominantDevice (windowStructureRect);
847 Rect screenRect = (**dominantDevice).gdRect;
848 const int kSluffBetweenWindBottomAndScreenBottom = 10;
849 if (windowStructureRect.bottom + kSluffBetweenWindBottomAndScreenBottom < screenRect.bottom) {
850 Rect newWindBounds = UWindows::GetWindowContentRect (theWindPtr);
853 newWindBounds.bottom += (screenRect.bottom - windowStructureRect.bottom - kSluffBetweenWindBottomAndScreenBottom);
854 mWindow->DoSetBounds (newWindBounds);
858 SDimension16 winSize;
859 mWindow->GetFrameSize (winSize);
865 minMax.bottom = 10 * 1024;
866 minMax.right = 10 * 1024;
867 mWindow->SetMinMaxSize (minMax);
870 LedItView* editorView =
new LedItView ();
872 editorView->AddAttributes (textAttr_MultiStyle | textAttr_Editable | textAttr_Selectable | textAttr_WordWrap);
873 editorView->SpecifyTextStore (&fTextStore);
874 editorView->SetStyleDatabase (fStyleDatabase);
875 editorView->SetParagraphDatabase (fParagraphDatabase);
876 editorView->SetHidableTextDatabase (fHidableTextDatabase);
877 editorView->SetCommandHandler (&fCommandHandler);
878 editorView->SetSpellCheckEngine (&LedItApplication::Get ().fSpellCheckEngine);
879 editorView->PutInside (mWindow);
880 editorView->PlaceInSuperFrameAt (0, 0,
false);
881 editorView->ResizeFrameTo (winSize.width, winSize.height,
false);
882 SBooleanRect editViewBindings;
883 editViewBindings.top =
true;
884 editViewBindings.left =
true;
885 editViewBindings.bottom =
true;
886 editViewBindings.right =
true;
887 editorView->SetFrameBinding (editViewBindings);
888 editorView->FinishCreate ();
890 fTextView = editorView;
891 mWindow->SetLatentSub (editorView);
893 if (inFileSpec == NULL) {
897 OpenFile (*inFileSpec);
903void LedItDocument::DoReadCode ()
905 Led_BusyCursor busyCursor;
907 StScrpHandle styleInfo = NULL;
909 short curResFile = ::CurResFile ();
910 mFile->OpenResourceFork (fsRdPerm);
911 ::UseResFile (mFile->GetResourceForkRefNum ());
912 styleInfo = (StScrpHandle)::Get1Resource (
'styl', 128);
913 if (styleInfo != NULL) {
914 ::DetachResource ((Handle)styleInfo);
916 ::UseResFile (curResFile);
917 mFile->CloseResourceFork ();
922 ThrowIfOSErr_ (::SetFPos (mFile->GetDataForkRefNum (), fsFromStart, 0));
923 StyledTextIOSrcStream_FileDescriptor source (mFile->GetDataForkRefNum (), Handle (styleInfo));
924 WordProcessor::WordProcessorTextIOSinkStream sink (&fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
927 switch (fFileFormat) {
929 source.SetBufferSize (0);
930 if (styleInfo == NULL) {
931 StyledTextIOReader_PlainText textReader (&source, &sink);
935 StyledTextIOReader_STYLText textReader (&source, &sink);
941 source.SetBufferSize (16 * 1024);
942 StyledTextIOReader_RTF textReader (&source, &sink);
947 source.SetBufferSize (16 * 1024);
948 StyledTextIOReader_HTML textReader (&source, &sink, &fHTMLInfo);
952 case eLedPrivateFormat: {
954 StyledTextIOReader_LedNativeFileFormat textReader (&source, &sink);
970 source.SetBufferSize (1 * 1024);
974 StyledTextIOReader_RTF reader (&source, &sink);
975 if (reader.QuickLookAppearsToBeRightFormat ()) {
976 fFileFormat = eRTFFormat;
986 StyledTextIOReader_LedNativeFileFormat reader (&source, &sink);
987 if (reader.QuickLookAppearsToBeRightFormat ()) {
988 fFileFormat = eLedPrivateFormat;
998 StyledTextIOReader_HTML reader (&source, &sink);
999 if (reader.QuickLookAppearsToBeRightFormat ()) {
1000 fFileFormat = eHTMLFormat;
1009 fFileFormat = eTextFormat;
1015 if (styleInfo != NULL) {
1016 ::DisposeHandle ((Handle)styleInfo);
1020 if (styleInfo != NULL) {
1021 ::DisposeHandle ((Handle)styleInfo);
1025Boolean LedItDocument::ObeyCommand (CommandT inCommand,
void* ioParam)
1027 Boolean cmdHandled =
true;
1029 switch (inCommand) {
1030 case kCmdSaveACopyAs: {
1031 OnSaveACopyAsCommand ();
1035 cmdHandled = LSingleDoc::ObeyCommand (inCommand, ioParam);
1043void LedItDocument::FindCommandStatus (CommandT inCommand, Boolean& outEnabled, Boolean& outUsesMark, UInt16& outMark, Str255 outName)
1045 outUsesMark =
false;
1046 switch (inCommand) {
1047 case kCmdSaveACopyAs: {
1052 LSingleDoc::FindCommandStatus (inCommand, outEnabled, outUsesMark, outMark, outName);
1057void LedItDocument::OnSaveACopyAsCommand ()
1059 FilteredSFPutDLog filteredPicker (sPutFileTypeList, (
sizeof sPutFileTypeList) / (
sizeof sPutFileTypeList[0]));
1062 GetDescriptor (defaultName);
1063 size_t typeIndex = MapPutFileFormatToTypeListIdx (fFileFormat);
1065 bool replacingFile =
false;
1066 if (filteredPicker.PickFile (defaultName, &fileResult, &replacingFile, &typeIndex)) {
1067 if (replacingFile) {
1068 ThrowIfOSErr_ (::FSpDelete (&fileResult));
1071 FileFormat savedFileFormat = fFileFormat;
1072 LFile* savedFile = mFile;
1074 fFileFormat = MapPutFileTypeListIdxToFormat (typeIndex);
1076 mFile =
new LFile (fileResult);
1078 OSType fileType = MapFormatToOSType (fFileFormat);
1081 mFile->CreateNewDataFile (kApplicationSignature, fileType, 0);
1082 mFile->OpenDataFork (fsRdWrPerm);
1088 fFileFormat = savedFileFormat;
1091 fFileFormat = savedFileFormat;
1098#if qStroika_Foundation_Common_Platform_Windows
1099BOOL LedItDocument::OnNewDocument ()
1101 fCommandHandler.Commit ();
1102 if (!COleServerDoc::OnNewDocument ()) {
1105 fFileFormat = eDefaultFormat;
1106 fStyleDatabase = make_shared<StyleDatabaseRep> (fTextStore);
1107 fParagraphDatabase = make_shared<ParagraphDatabaseRep> (fTextStore);
1108 fHidableTextDatabase = make_shared<UniformHidableTextMarkerOwner> (fTextStore);
1112COleServerItem* LedItDocument::OnGetEmbeddedItem ()
1116 LedItServerItem* pItem =
new LedItServerItem (
this);
1117 ASSERT_VALID (pItem);
1121BOOL LedItDocument::DoSave (LPCTSTR lpszPathName, BOOL bReplace)
1123 FileFormat fileFormat = fFileFormat;
1125 CString newName = lpszPathName;
1126 if (newName.IsEmpty ()) {
1127 CDocTemplate* pTemplate = GetDocTemplate ();
1128 ASSERT (pTemplate != NULL);
1129 newName = m_strPathName;
1130 if (bReplace && newName.IsEmpty ()) {
1131 newName = m_strTitle;
1133 int iBad = newName.FindOneOf (_T(
" #%;/\\"));
1135 newName.ReleaseBuffer (iBad);
1140 if (pTemplate->GetDocString(strExt, CDocTemplate::filterExt) &&
1141 !strExt.IsEmpty()) {
1142 ASSERT(strExt[0] ==
'.');
1149 if (not DoPromptSaveAsFileName (newName, &fileFormat)) {
1154 if (not DoPromptSaveCopyAsFileName (newName, &fileFormat)) {
1165 FileFormat realSavedDocFormat = fFileFormat;
1166 fFileFormat = fileFormat;
1168 if (!OnSaveDocument (newName)) {
1169 if (lpszPathName == NULL) {
1173 CFile::Remove (newName);
1177 TRACE0 (
"Warning: failed to delete file after failed SaveAs.\n");
1178 DELETE_EXCEPTION (e);
1186 fFileFormat = realSavedDocFormat;
1189 fFileFormat = realSavedDocFormat;
1193 SetPathName (newName);
1194 fFileFormat = fileFormat;
1200void LedItDocument::Serialize (CArchive& ar)
1202 if (ar.IsStoring ()) {
1203 Require (fFileFormat != eUnknownFormat);
1206 StyledTextIOWriterSinkStream_Memory sink;
1208 switch (fFileFormat) {
1210 StyledTextIOWriter_PlainText textWriter{&source, &sink};
1211 textWriter.Write ();
1215 StyledTextIOWriter_RTF textWriter{&source, &sink, &fRTFInfo};
1216 textWriter.Write ();
1220 StyledTextIOWriter_HTML textWriter{&source, &sink, &fHTMLInfo};
1221 textWriter.Write ();
1224 case eLedPrivateFormat: {
1225 StyledTextIOWriter_LedNativeFileFormat textWriter{&source, &sink};
1226 textWriter.Write ();
1233 ar.Write ((
char*)sink.PeekAtData (),
static_cast<UINT
> (sink.GetLength ()));
1248 POSITION pos = GetFirstViewPosition ();
1249 for (CView* p = GetNextView (pos); p != NULL; p = GetNextView (pos)) {
1250 LedItView* v =
dynamic_cast<LedItView*
> (p);
1256 CFile* file = ar.GetFile ();
1257 ASSERT_VALID (file);
1258 DWORD nLen =
static_cast<DWORD
> (file->GetLength ());
1259 StackBuffer<char> buf{Memory::eUninitialized, nLen};
1260 if (ar.Read (buf.data (), nLen) != nLen) {
1261 AfxThrowArchiveException (CArchiveException::endOfFile);
1263 StyledTextIOSrcStream_Memory source{buf.data (), nLen};
1267 switch (fFileFormat) {
1269 StyledTextIOReader_PlainText textReader{&source, &sink};
1273 case eLedPrivateFormat: {
1274 LedItControlItem::DocContextDefiner tmp{
this};
1275 StyledTextIOReader_LedNativeFileFormat textReader{&source, &sink};
1280 LedItControlItem::DocContextDefiner tmp{
this};
1281 StyledTextIOReader_RTF textReader{&source, &sink, &fRTFInfo};
1286 StyledTextIOReader_HTML textReader{&source, &sink, &fHTMLInfo};
1290 case eUnknownFormat: {
1297 StyledTextIOReader_RTF reader{&source, &sink, &fRTFInfo};
1298 if (reader.QuickLookAppearsToBeRightFormat ()) {
1299 fFileFormat = eRTFFormat;
1309 StyledTextIOReader_LedNativeFileFormat reader{&source, &sink};
1310 if (reader.QuickLookAppearsToBeRightFormat ()) {
1311 fFileFormat = eLedPrivateFormat;
1321 StyledTextIOReader_HTML reader{&source, &sink};
1322 if (reader.QuickLookAppearsToBeRightFormat ()) {
1323 fFileFormat = eHTMLFormat;
1332 fFileFormat = eTextFormat;
1344BOOL LedItDocument::OnOpenDocument (LPCTSTR lpszPathName)
1355 POSITION pos = GetFirstViewPosition ();
1356 for (CView* p = GetNextView (pos); p != NULL; p = GetNextView (pos)) {
1357 LedItView* v =
dynamic_cast<LedItView*
> (p);
1364 fCommandHandler.Commit ();
1365 fStyleDatabase = make_shared<StyleDatabaseRep> (fTextStore);
1366 fParagraphDatabase = make_shared<ParagraphDatabaseRep> (fTextStore);
1367 fHidableTextDatabase = make_shared<UniformHidableTextMarkerOwner> (fTextStore);
1371 POSITION pos = GetFirstViewPosition ();
1372 while (pos != NULL) {
1373 CView* pView = GetNextView (pos);
1374 pView->OnInitialUpdate ();
1378 WordProcessor::WordProcessorFlavorPackageInternalizer internalizer (fTextStore, fStyleDatabase, fParagraphDatabase, fHidableTextDatabase);
1380 Led_ClipFormat readFileFormat = kBadClipFormat;
1390 switch (sHiddenDocOpenArg) {
1392 readFileFormat = kTEXTClipFormat;
1394 case eLedPrivateFormat:
1395 readFileFormat = kLedPrivateClipFormat;
1398 readFileFormat = kRTFClipFormat;
1401 readFileFormat = kHTMLClipFormat;
1405 internalizer.InternalizeFlavor_FILEData (lpszPathName, &readFileFormat, NULL, 0, fTextStore.GetEnd ());
1408 if (readFileFormat == kTEXTClipFormat) {
1409 fFileFormat = eTextFormat;
1411 else if (readFileFormat == kLedPrivateClipFormat) {
1412 fFileFormat = eLedPrivateFormat;
1414 else if (readFileFormat == kRTFClipFormat) {
1415 fFileFormat = eRTFFormat;
1417 else if (readFileFormat == kHTMLClipFormat) {
1418 fFileFormat = eHTMLFormat;
1422 fFileFormat = eDefaultFormat;
1425 SetModifiedFlag (FALSE);
1430void LedItDocument::OnUpdateFileSave (CCmdUI* pCmdUI)
1432 ASSERT_VALID (
this);
1435 pCmdUI->Enable (IsModified () or GetPathName ().GetLength () == 0);
1438void LedItDocument::OnFileSaveCopyAs ()
1440 ASSERT_VALID (
this);
1441 Assert (m_bRemember);
1443 LPSTORAGE savedStorage = m_lpRootStg;
1446 FileFormat savedFileFormat = fFileFormat;
1449 DoSave (NULL,
false);
1452 m_lpRootStg = savedStorage;
1454 fFileFormat = savedFileFormat;
1458 m_lpRootStg = savedStorage;
1460 fFileFormat = savedFileFormat;
1463void LedItDocument::DeleteContents ()
1465 fTextStore.Replace (fTextStore.GetStart (), fTextStore.GetEnd (), LED_TCHAR_OF (
""), 0);
1468bool LedItDocument::DoPromptSaveAsFileName (CString& fileName, FileFormat* fileFormat)
1471 return DoPromptFileName (fileName, AFX_IDS_SAVEFILE,
false, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, fileFormat);
1474bool LedItDocument::DoPromptSaveCopyAsFileName (CString& fileName, FileFormat* fileFormat)
1477 return DoPromptFileName (fileName, AFX_IDS_SAVEFILECOPY,
false, OFN_HIDEREADONLY | OFN_PATHMUSTEXIST, fileFormat);
1480bool LedItDocument::DoPromptOpenFileName (CString& fileName, FileFormat* fileFormat)
1483 return DoPromptFileName (fileName, AFX_IDS_OPENFILE,
true, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST, fileFormat);
1486bool LedItDocument::DoPromptFileName (CString& fileName, UINT nIDSTitle,
bool isOpenDialogCall,
long fileDLogFlags, FileFormat* fileFormat)
1489 CFileDialog dlgFile{isOpenDialogCall};
1492 Verify (title.LoadString (nIDSTitle));
1494 dlgFile.m_ofn.Flags |= fileDLogFlags;
1498 CDocTemplate* ledItPrivateDocFormatTemplate = NULL;
1501 POSITION pos = AfxGetApp ()->m_pDocManager->GetFirstDocTemplatePosition ();
1502 ledItPrivateDocFormatTemplate = AfxGetApp ()->m_pDocManager->GetNextDocTemplate (pos);
1504 if (nIDSTitle == AFX_IDS_OPENFILE) {
1505 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.htm;*.html;*.led;*.rtf;*.txt;",
"All Recognized (*.htm;*.html;*.led;*.rtf;*.txt)");
1506 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
".*",
"All Files (*.*)");
1508 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.htm;*.html",
"HTML file (*.htm;*.html)");
1509 AppendFilterSuffix (strFilter, dlgFile.m_ofn, ledItPrivateDocFormatTemplate);
1510 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.rtf",
"Microsoft Rich Text Format (*.rtf)");
1511 AppendFilterSuffix (strFilter, dlgFile.m_ofn,
"*.txt",
"Plain Text (*.txt)");
1513 strFilter += (TCHAR)
'\0';
1515 dlgFile.m_ofn.lpstrFilter = strFilter;
1516 dlgFile.m_ofn.lpstrTitle = title;
1519 dlgFile.m_ofn.lpstrFile = fileName.GetBuffer (_MAX_PATH);
1521 if (nIDSTitle == AFX_IDS_OPENFILE) {
1522 dlgFile.m_ofn.nFilterIndex = 1;
1525 FileFormat initialFormat = *fileFormat;
1526 if (initialFormat == eUnknownFormat) {
1527 initialFormat = eDefaultFormat;
1529 switch (initialFormat) {
1531 dlgFile.m_ofn.nFilterIndex = 1;
1533 case eLedPrivateFormat:
1534 dlgFile.m_ofn.nFilterIndex = 2;
1537 dlgFile.m_ofn.nFilterIndex = 3;
1540 dlgFile.m_ofn.nFilterIndex = 4;
1547 bool bResult = (dlgFile.DoModal () == IDOK);
1548 fileName.ReleaseBuffer ();
1550 if (nIDSTitle == AFX_IDS_OPENFILE) {
1551 switch (dlgFile.m_ofn.nFilterIndex) {
1553 *fileFormat = eUnknownFormat;
1556 *fileFormat = eUnknownFormat;
1559 *fileFormat = eHTMLFormat;
1562 *fileFormat = eLedPrivateFormat;
1565 *fileFormat = eRTFFormat;
1568 *fileFormat = eTextFormat;
1571 *fileFormat = eUnknownFormat;
1576 switch (dlgFile.m_ofn.nFilterIndex) {
1578 *fileFormat = eHTMLFormat;
1581 *fileFormat = eLedPrivateFormat;
1584 *fileFormat = eRTFFormat;
1587 *fileFormat = eTextFormat;
1590 *fileFormat = eUnknownFormat;
1597 if (not(fileDLogFlags & OFN_FILEMUSTEXIST)) {
1598 if (dlgFile.GetFileExt () ==
"") {
1599 switch (*fileFormat) {
1607 fileName +=
".html";
1609 case eLedPrivateFormat:
1619#if qStroika_Foundation_Debug_AssertionsChecked
1620void LedItDocument::AssertValid ()
const
1622 COleServerDoc::AssertValid ();
1623 fTextStore.Invariant ();
1636SDKString ExtractFileSuffix (
const SDKString& from)
1638 size_t i = from.rfind (
'.');
1639 if (i == SDKString::npos) {
1644 for (
size_t j = 0; j < suffix.length (); ++j) {
1645 if (isascii (suffix[j]) and isupper (suffix[j])) {
1646 suffix[j] =
static_cast<Led_tChar
> (tolower (suffix[j]));
1653#if qStroika_Foundation_Common_Platform_Windows
1660static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CString strFilterExt, CString strFilterName)
1662 Require (not strFilterExt.IsEmpty ());
1663 Require (not strFilterName.IsEmpty ());
1666 filter += strFilterName;
1667 ASSERT (!filter.IsEmpty ());
1668 filter += (TCHAR)
'\0';
1669 filter += (TCHAR)
'*';
1670 filter += strFilterExt;
1671 filter += (TCHAR)
'\0';
1672 ++ofn.nMaxCustFilter;
1675static void AppendFilterSuffix (CString& filter, OPENFILENAME& ofn, CDocTemplate* pTemplate)
1677 ASSERT_VALID (pTemplate);
1678 ASSERT_KINDOF (CDocTemplate, pTemplate);
1679 CString strFilterExt;
1680 CString strFilterName;
1681 if (pTemplate->GetDocString (strFilterExt, CDocTemplate::filterExt) && !strFilterExt.IsEmpty () &&
1682 pTemplate->GetDocString (strFilterName, CDocTemplate::filterName) && !strFilterName.IsEmpty ()) {
1683 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