Stroika Library 3.0d18
 
Loading...
Searching...
No Matches
LedIt/Sources/LedItView.cpp
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4
5#include "Stroika/Foundation/StroikaPreComp.h"
6
7#if qStroika_Foundation_Common_Platform_MacOS
8#include <AERegistry.h>
9#include <ColorPicker.h>
10#include <Dialogs.h>
11#include <TextUtils.h>
12
13#include <LDialogBox.h>
14#include <LEditField.h>
15#include <LMenu.h>
16#include <LMenuBar.h>
17#include <LStdControl.h>
18#include <PP_Messages.h>
19#include <UAppleEventsMgr.h>
20#include <UModalDialogs.h>
21#elif qStroika_Foundation_Common_Platform_Windows
22DISABLE_COMPILER_MSC_WARNING_START (5054)
23#include <afxodlgs.h> // MFC OLE dialog classes
24DISABLE_COMPILER_MSC_WARNING_END (5054)
25#endif
26
27#include "Stroika/Foundation/DataExchange/BadFormatException.h"
28
29#include "Stroika/Frameworks/Led/StdDialogs.h"
30
31#include "ColorMenu.h"
32#if qStroika_Foundation_Common_Platform_Windows
33#include "LedItControlItem.h"
34#endif
35#include "LedItDocument.h"
36#include "LedItResources.h"
37#include "Options.h"
38
39#include "LedItApplication.h"
40
41#include "LedItView.h"
42
43using namespace Stroika::Foundation;
44using namespace Stroika::Frameworks::Led;
45using namespace Stroika::Frameworks::Led::Platform;
46using namespace Stroika::Frameworks::Led::StyledTextIO;
47
48class My_CMDNUM_MAPPING : public
49#if qStroika_Foundation_Common_Platform_Windows
50 Platform::MFC_CommandNumberMapping
51#elif qStroika_Foundation_Common_Platform_MacOS
52 Platform::PP_CommandNumberMapping
53#elif qStroika_FeatureSupported_XWindows
54 Platform::Gtk_CommandNumberMapping
55#endif
56{
57public:
58 My_CMDNUM_MAPPING ()
59 {
60 AddAssociation (kCmdUndo, LedItView::kUndo_CmdID);
61 AddAssociation (kCmdRedo, LedItView::kRedo_CmdID);
62 AddAssociation (kCmdSelectAll, LedItView::kSelectAll_CmdID);
63 AddAssociation (kCmdCut, LedItView::kCut_CmdID);
64 AddAssociation (kCmdCopy, LedItView::kCopy_CmdID);
65 AddAssociation (kCmdPaste, LedItView::kPaste_CmdID);
66 AddAssociation (kCmdClear, LedItView::kClear_CmdID);
67 AddAssociation (kFindCmd, LedItView::kFind_CmdID);
68 AddAssociation (kFindAgainCmd, LedItView::kFindAgain_CmdID);
69 AddAssociation (kEnterFindStringCmd, LedItView::kEnterFindString_CmdID);
70 AddAssociation (kReplaceCmd, LedItView::kReplace_CmdID);
71 AddAssociation (kReplaceAgainCmd, LedItView::kReplaceAgain_CmdID);
72#if qIncludeBakedInDictionaries
73 // If we have no dictionaries - assume no spellcheck command should be enabled (mapped)
74 AddAssociation (kSpellCheckCmd, LedItView::kSpellCheck_CmdID);
75#endif
76 AddAssociation (kSelectWordCmd, LedItView::kSelectWord_CmdID);
77 AddAssociation (kSelectTextRowCmd, LedItView::kSelectTextRow_CmdID);
78 AddAssociation (kSelectParagraphCmd, LedItView::kSelectParagraph_CmdID);
79 AddAssociation (kSelectTableIntraCellAllCmd, LedItView::kSelectTableIntraCellAll_CmdID);
80 AddAssociation (kSelectTableCellCmd, LedItView::kSelectTableCell_CmdID);
81 AddAssociation (kSelectTableRowCmd, LedItView::kSelectTableRow_CmdID);
82 AddAssociation (kSelectTableColumnCmd, LedItView::kSelectTableColumn_CmdID);
83 AddAssociation (kSelectTableCmd, LedItView::kSelectTable_CmdID);
84
85 AddAssociation (kFontSize9Cmd, LedItView::kFontSize9_CmdID);
86 AddAssociation (kFontSize10Cmd, LedItView::kFontSize10_CmdID);
87 AddAssociation (kFontSize12Cmd, LedItView::kFontSize12_CmdID);
88 AddAssociation (kFontSize14Cmd, LedItView::kFontSize14_CmdID);
89 AddAssociation (kFontSize18Cmd, LedItView::kFontSize18_CmdID);
90 AddAssociation (kFontSize24Cmd, LedItView::kFontSize24_CmdID);
91 AddAssociation (kFontSize36Cmd, LedItView::kFontSize36_CmdID);
92 AddAssociation (kFontSize48Cmd, LedItView::kFontSize48_CmdID);
93 AddAssociation (kFontSize72Cmd, LedItView::kFontSize72_CmdID);
94#if qSupportOtherFontSizeDlg
95 AddAssociation (kFontSizeOtherCmd, LedItView::kFontSizeOther_CmdID);
96#endif
97 AddAssociation (kFontSizeSmallerCmd, LedItView::kFontSizeSmaller_CmdID);
98 AddAssociation (kFontSizeLargerCmd, LedItView::kFontSizeLarger_CmdID);
99
100 AddAssociation (kBlackColorCmd, LedItView::kFontColorBlack_CmdID);
101 AddAssociation (kMaroonColorCmd, LedItView::kFontColorMaroon_CmdID);
102 AddAssociation (kGreenColorCmd, LedItView::kFontColorGreen_CmdID);
103 AddAssociation (kOliveColorCmd, LedItView::kFontColorOlive_CmdID);
104 AddAssociation (kNavyColorCmd, LedItView::kFontColorNavy_CmdID);
105 AddAssociation (kPurpleColorCmd, LedItView::kFontColorPurple_CmdID);
106 AddAssociation (kTealColorCmd, LedItView::kFontColorTeal_CmdID);
107 AddAssociation (kGrayColorCmd, LedItView::kFontColorGray_CmdID);
108 AddAssociation (kSilverColorCmd, LedItView::kFontColorSilver_CmdID);
109 AddAssociation (kRedColorCmd, LedItView::kFontColorRed_CmdID);
110 AddAssociation (kLimeColorCmd, LedItView::kFontColorLime_CmdID);
111 AddAssociation (kYellowColorCmd, LedItView::kFontColorYellow_CmdID);
112 AddAssociation (kBlueColorCmd, LedItView::kFontColorBlue_CmdID);
113 AddAssociation (kFuchsiaColorCmd, LedItView::kFontColorFuchsia_CmdID);
114 AddAssociation (kAquaColorCmd, LedItView::kFontColorAqua_CmdID);
115 AddAssociation (kWhiteColorCmd, LedItView::kFontColorWhite_CmdID);
116 AddAssociation (kFontColorOtherCmd, LedItView::kFontColorOther_CmdID);
117
118 AddAssociation (kJustifyLeftCmd, LedItView::kJustifyLeft_CmdID);
119 AddAssociation (kJustifyCenterCmd, LedItView::kJustifyCenter_CmdID);
120 AddAssociation (kJustifyRightCmd, LedItView::kJustifyRight_CmdID);
121 AddAssociation (kJustifyFullCmd, LedItView::kJustifyFull_CmdID);
122
123#if qSupportParagraphSpacingDlg
124 AddAssociation (kParagraphSpacingCmd, LedItView::kParagraphSpacingCommand_CmdID);
125#endif
126#if qSupportParagraphIndentsDlg
127 AddAssociation (kParagraphIndentsCmd, LedItView::kParagraphIndentsCommand_CmdID);
128#endif
129
130 AddAssociation (kListStyle_NoneCmd, LedItView::kListStyle_None_CmdID);
131 AddAssociation (kListStyle_BulletCmd, LedItView::kListStyle_Bullet_CmdID);
132
133 AddAssociation (kIncreaseIndentCmd, LedItView::kIncreaseIndent_CmdID);
134 AddAssociation (kDecreaseIndentCmd, LedItView::kDecreaseIndent_CmdID);
135
136 AddRangeAssociation (kBaseFontNameCmd, kLastFontNameCmd, LedItView::kFontMenuFirst_CmdID, LedItView::kFontMenuLast_CmdID);
137
138 AddAssociation (kFontStylePlainCmd, LedItView::kFontStylePlain_CmdID);
139 AddAssociation (kFontStyleBoldCmd, LedItView::kFontStyleBold_CmdID);
140 AddAssociation (kFontStyleItalicCmd, LedItView::kFontStyleItalic_CmdID);
141 AddAssociation (kFontStyleUnderlineCmd, LedItView::kFontStyleUnderline_CmdID);
142#if qStroika_Foundation_Common_Platform_MacOS
143 AddAssociation (kFontStyleOutlineCmd, LedItView::kFontStyleOutline_CmdID);
144 AddAssociation (kFontStyleShadowCmd, LedItView::kFontStyleShadow_CmdID);
145 AddAssociation (kFontStyleCondensedCmd, LedItView::kFontStyleCondensed_CmdID);
146 AddAssociation (kFontStyleExtendedCmd, LedItView::kFontStyleExtended_CmdID);
147#endif
148#if qStroika_Foundation_Common_Platform_Windows
149 AddAssociation (kFontStyleStrikeoutCmd, LedItView::kFontStyleStrikeout_CmdID);
150#endif
151 AddAssociation (kSubScriptCmd, LedItView::kSubScriptCommand_CmdID);
152 AddAssociation (kSuperScriptCmd, LedItView::kSuperScriptCommand_CmdID);
153#if qStroika_Foundation_Common_Platform_Windows || qStroika_FeatureSupported_XWindows
154 AddAssociation (kChooseFontDialogCmd, LedItView::kChooseFontCommand_CmdID);
155#endif
156
157 AddAssociation (kInsertTableCmd, LedItView::kInsertTable_CmdID);
158 AddAssociation (kInsertTableRowAboveCmd, LedItView::kInsertTableRowAbove_CmdID);
159 AddAssociation (kInsertTableRowBelowCmd, LedItView::kInsertTableRowBelow_CmdID);
160 AddAssociation (kInsertTableColBeforeCmd, LedItView::kInsertTableColBefore_CmdID);
161 AddAssociation (kInsertTableColAfterCmd, LedItView::kInsertTableColAfter_CmdID);
162 AddAssociation (kInsertURLCmd, LedItView::kInsertURL_CmdID);
163#if qStroika_Foundation_Common_Platform_Windows
164 AddAssociation (kInsertSymbolCmd, LedItView::kInsertSymbol_CmdID);
165#endif
166
167 // AddAssociation (kPropertiesForSelectionCmd, LedItView::kSelectedEmbeddingProperties_CmdID);
168 AddRangeAssociation (kFirstSelectedEmbeddingCmd, kLastSelectedEmbeddingCmd, LedItView::kFirstSelectedEmbedding_CmdID,
169 LedItView::kLastSelectedEmbedding_CmdID);
170
171 AddAssociation (kHideSelectionCmd, LedItView::kHideSelection_CmdID);
172 AddAssociation (kUnHideSelectionCmd, LedItView::kUnHideSelection_CmdID);
173 AddAssociation (kRemoveTableRowsCmd, LedItView::kRemoveTableRows_CmdID);
174 AddAssociation (kRemoveTableColumnsCmd, LedItView::kRemoveTableColumns_CmdID);
175
176 AddAssociation (kShowHideParagraphGlyphsCmd, LedItView::kShowHideParagraphGlyphs_CmdID);
177 AddAssociation (kShowHideTabGlyphsCmd, LedItView::kShowHideTabGlyphs_CmdID);
178 AddAssociation (kShowHideSpaceGlyphsCmd, LedItView::kShowHideSpaceGlyphs_CmdID);
179
180#if qStroika_Foundation_Common_Platform_Windows
181 AddAssociation (IDC_FONTSIZE, IDC_FONTSIZE);
182 AddAssociation (IDC_FONTNAME, IDC_FONTNAME);
183#endif
184 }
185};
186My_CMDNUM_MAPPING sMy_CMDNUM_MAPPING;
187
188struct LedIt_DialogSupport : TextInteractor::DialogSupport, WordProcessor::DialogSupport {
189public:
190 using CommandNumber = TextInteractor::DialogSupport::CommandNumber;
191
192public:
193 LedIt_DialogSupport ()
194 {
195 TextInteractor::SetDialogSupport (this);
196 WordProcessor::SetDialogSupport (this);
197 }
198 ~LedIt_DialogSupport ()
199 {
200 WordProcessor::SetDialogSupport (NULL);
201 TextInteractor::SetDialogSupport (NULL);
202 }
203
204// TextInteractor::DialogSupport
205#if qSupportStdFindDlg
206public:
207 virtual void DisplayFindDialog (Led_tString* findText, const vector<Led_tString>& recentFindSuggestions, bool* wrapSearch,
208 bool* wholeWordSearch, bool* caseSensative, bool* pressedOK) override
209 {
210#if qStroika_Foundation_Common_Platform_MacOS
211 Led_StdDialogHelper_FindDialog findDialog;
212#elif qStroika_Foundation_Common_Platform_Windows
213 Led_StdDialogHelper_FindDialog findDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
214#elif qStroika_FeatureSupported_XWindows
215 Led_StdDialogHelper_FindDialog findDialog (GTK_WINDOW (LedItApplication::Get ().GetAppWindow ()));
216#endif
217
218 findDialog.fFindText = *findText;
219 findDialog.fRecentFindTextStrings = recentFindSuggestions;
220 findDialog.fWrapSearch = *wrapSearch;
221 findDialog.fWholeWordSearch = *wholeWordSearch;
222 findDialog.fCaseSensativeSearch = *caseSensative;
223
224 findDialog.DoModal ();
225
226 *findText = findDialog.fFindText;
227 *wrapSearch = findDialog.fWrapSearch;
228 *wholeWordSearch = findDialog.fWholeWordSearch;
229 *caseSensative = findDialog.fCaseSensativeSearch;
230 *pressedOK = findDialog.fPressedOK;
231 }
232#endif
233#if qSupportStdReplaceDlg
234public:
235 virtual ReplaceButtonPressed DisplayReplaceDialog (Led_tString* findText, const vector<Led_tString>& recentFindSuggestions,
236 Led_tString* replaceText, bool* wrapSearch, bool* wholeWordSearch, bool* caseSensative) override
237 {
238#if qStroika_Foundation_Common_Platform_MacOS
239 Led_StdDialogHelper_ReplaceDialog replaceDialog;
240#elif qStroika_Foundation_Common_Platform_Windows
241 Led_StdDialogHelper_ReplaceDialog replaceDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
242#elif qStroika_FeatureSupported_XWindows
243 Led_StdDialogHelper_ReplaceDialog replaceDialog (GTK_WINDOW (LedItApplication::Get ().GetAppWindow ()));
244#endif
245
246 replaceDialog.fFindText = *findText;
247 replaceDialog.fRecentFindTextStrings = recentFindSuggestions;
248 replaceDialog.fReplaceText = *replaceText;
249 replaceDialog.fWrapSearch = *wrapSearch;
250 replaceDialog.fWholeWordSearch = *wholeWordSearch;
251 replaceDialog.fCaseSensativeSearch = *caseSensative;
252
253 replaceDialog.DoModal ();
254
255 *findText = replaceDialog.fFindText;
256 *replaceText = replaceDialog.fReplaceText;
257 *wrapSearch = replaceDialog.fWrapSearch;
258 *wholeWordSearch = replaceDialog.fWholeWordSearch;
259 *caseSensative = replaceDialog.fCaseSensativeSearch;
260
261 switch (replaceDialog.fPressed) {
262 case Led_StdDialogHelper_ReplaceDialog::eCancel:
263 return eReplaceButton_Cancel;
264 case Led_StdDialogHelper_ReplaceDialog::eFind:
265 return eReplaceButton_Find;
266 case Led_StdDialogHelper_ReplaceDialog::eReplace:
267 return eReplaceButton_Replace;
268 case Led_StdDialogHelper_ReplaceDialog::eReplaceAll:
269 return eReplaceButton_ReplaceAll;
270 case Led_StdDialogHelper_ReplaceDialog::eReplaceAllInSelection:
271 return eReplaceButton_ReplaceAllInSelection;
272 }
273 Assert (false);
274 return eReplaceButton_Cancel;
275 }
276#endif
277#if qSupportStdSpellCheckDlg
278public:
279 virtual void DisplaySpellCheckDialog (SpellCheckDialogCallback& callback) override
280 {
281 Led_StdDialogHelper_SpellCheckDialog::CallbackDelegator<SpellCheckDialogCallback> delegator (callback);
282#if qStroika_Foundation_Common_Platform_MacOS
283 Led_StdDialogHelper_SpellCheckDialog spellCheckDialog (delegator);
284#elif qStroika_Foundation_Common_Platform_Windows
285 Led_StdDialogHelper_SpellCheckDialog spellCheckDialog (delegator, ::AfxGetResourceHandle (), ::GetActiveWindow ());
286#elif qStroika_FeatureSupported_XWindows
287 Led_StdDialogHelper_SpellCheckDialog spellCheckDialog (delegator, GTK_WINDOW (LedItApplication::Get ().GetAppWindow ()));
288#endif
289
290 spellCheckDialog.DoModal ();
291 }
292#endif
293
294 // WordProcessor::DialogSupport
295public:
296 virtual FontNameSpecifier CmdNumToFontName (CommandNumber cmdNum) override
297 {
298 Require (cmdNum >= WordProcessor::kFontMenuFirst_CmdID);
299 Require (cmdNum <= WordProcessor::kFontMenuLast_CmdID);
300#if qStroika_Foundation_Common_Platform_MacOS
301 static LMenu* fontMenu = LMenuBar::GetCurrentMenuBar ()->FetchMenu (cmd_FontMenu);
302 static vector<short> sFontIDMapCache; // OK to keep static cuz never changes during run of app
303
304 size_t idx = cmdNum - WordProcessor::kFontMenuFirst_CmdID;
305
306 // Pre-fill cache - at least to the cmd were looking for...
307 for (size_t i = sFontIDMapCache.size (); i <= idx; ++i) {
308 Str255 pFontName = {0};
309 UInt16 menuItem = fontMenu->IndexFromCommand (i + WordProcessor::kFontMenuFirst_CmdID);
310 ::GetMenuItemText (fontMenu->GetMacMenuH (), menuItem, pFontName);
311 short familyID = 0;
312 ::GetFNum (pFontName, &familyID);
313 sFontIDMapCache.push_back (familyID);
314 }
315 return sFontIDMapCache[idx];
316#elif qStroika_Foundation_Common_Platform_Windows
317 return LedItApplication::Get ().CmdNumToFontName (MFC_CommandNumberMapping::Get ().ReverseLookup (cmdNum)).c_str ();
318#elif qStroika_FeatureSupported_XWindows
319 const vector<SDKString>& fontNames = LedItApplication::Get ().fInstalledFonts.GetUsableFontNames ();
320 Led_Assert (cmdNum - LedItView::kFontMenuFirst_CmdID < fontNames.size ());
321 return (fontNames[cmdNum - LedItView::kFontMenuFirst_CmdID]);
322#endif
323 }
324#if qSupportOtherFontSizeDlg
325 virtual DistanceType PickOtherFontHeight (DistanceType origHeight) override
326 {
327#if qStroika_Foundation_Common_Platform_MacOS
328 Led_StdDialogHelper_OtherFontSizeDialog dlg;
329#elif qStroika_Foundation_Common_Platform_Windows
330 Led_StdDialogHelper_OtherFontSizeDialog dlg (::AfxGetResourceHandle (), ::GetActiveWindow ());
331#endif
332 dlg.InitValues (origHeight);
333 if (dlg.DoModal ()) {
334 return dlg.fFontSize_Result;
335 }
336 else {
337 return 0;
338 }
339 }
340#endif
341#if qSupportParagraphSpacingDlg
342 virtual bool PickNewParagraphLineSpacing (TWIPS* spaceBefore, bool* spaceBeforeValid, TWIPS* spaceAfter, bool* spaceAfterValid,
343 LineSpacing* lineSpacing, bool* lineSpacingValid) override
344 {
345#if qStroika_Foundation_Common_Platform_MacOS
346 Led_StdDialogHelper_ParagraphSpacingDialog dlg;
347#elif qStroika_Foundation_Common_Platform_Windows
348 Led_StdDialogHelper_ParagraphSpacingDialog dlg (::AfxGetResourceHandle (), ::GetActiveWindow ());
349#endif
350 dlg.InitValues (*spaceBefore, *spaceBeforeValid, *spaceAfter, *spaceAfterValid, *lineSpacing, *lineSpacingValid);
351
352 if (dlg.DoModal ()) {
353 *spaceBeforeValid = dlg.fSpaceBefore_Valid;
354 if (*spaceBeforeValid) {
355 *spaceBefore = dlg.fSpaceBefore_Result;
356 }
357 *spaceAfterValid = dlg.fSpaceAfter_Valid;
358 if (*spaceAfterValid) {
359 *spaceAfter = dlg.fSpaceAfter_Result;
360 }
361 *lineSpacingValid = dlg.fLineSpacing_Valid;
362 if (*lineSpacingValid) {
363 *lineSpacing = dlg.fLineSpacing_Result;
364 }
365 return true;
366 }
367 else {
368 return false;
369 }
370 }
371#endif
372#if qSupportParagraphIndentsDlg
373 virtual bool PickNewParagraphMarginsAndFirstIndent (TWIPS* leftMargin, bool* leftMarginValid, TWIPS* rightMargin,
374 bool* rightMarginValid, TWIPS* firstIndent, bool* firstIndentValid) override
375 {
376#if qStroika_Foundation_Common_Platform_MacOS
377 Led_StdDialogHelper_ParagraphIndentsDialog dlg;
378#elif qStroika_Foundation_Common_Platform_Windows
379 Led_StdDialogHelper_ParagraphIndentsDialog dlg (::AfxGetResourceHandle (), ::GetActiveWindow ());
380#endif
381 dlg.InitValues (*leftMargin, *leftMarginValid, *rightMargin, *rightMarginValid, *firstIndent, *firstIndentValid);
382 if (dlg.DoModal ()) {
383 *leftMarginValid = dlg.fLeftMargin_Valid;
384 if (*leftMarginValid) {
385 *leftMargin = dlg.fLeftMargin_Result;
386 }
387 *rightMarginValid = dlg.fRightMargin_Valid;
388 if (*rightMarginValid) {
389 *rightMargin = dlg.fRightMargin_Result;
390 }
391 *firstIndentValid = dlg.fFirstIndent_Valid;
392 if (*firstIndentValid) {
393 *firstIndent = dlg.fFirstIndent_Result;
394 }
395 return true;
396 }
397 else {
398 return false;
399 }
400 }
401#endif
402#if qStroika_FeatureSupported_XWindows
403 virtual bool PickOtherFontColor (Color* color) override
404 {
405 StdColorPickBox dlg (GTK_WINDOW (LedItApplication::Get ().GetAppWindow ()), *color);
406 dlg.DoModal ();
407 if (dlg.GetWasOK ()) {
408 *color = dlg.fColor;
409 return true;
410 }
411 return false;
412 }
413#endif
414#if qStroika_FeatureSupported_XWindows
415 virtual bool ChooseFont (IncrementalFontSpecification* font) override
416 {
417 StdFontPickBox dlg (GTK_WINDOW (LedItApplication::Get ().GetAppWindow ()), *font);
418 dlg.DoModal ();
419 if (dlg.GetWasOK ()) {
420 *font = dlg.fFont;
421 return true;
422 }
423 return false;
424 }
425#endif
426#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
427 virtual void ShowSimpleEmbeddingInfoDialog (const SDKString& embeddingTypeName) override
428 {
429// unknown embedding...
430#if qStroika_Foundation_Common_Platform_MacOS
431 Led_StdDialogHelper_UnknownEmbeddingInfoDialog infoDialog;
432#elif qStroika_Foundation_Common_Platform_Windows
433 Led_StdDialogHelper_UnknownEmbeddingInfoDialog infoDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
434#endif
435#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
436 infoDialog.fEmbeddingTypeName = embeddingTypeName;
437 (void)infoDialog.DoModal ();
438#endif
439 }
440#endif
441#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
442 virtual bool ShowURLEmbeddingInfoDialog (const SDKString& embeddingTypeName, SDKString* urlTitle, SDKString* urlValue) override
443 {
444#if qStroika_Foundation_Common_Platform_MacOS
445 Led_StdDialogHelper_URLXEmbeddingInfoDialog infoDialog;
446#elif qStroika_Foundation_Common_Platform_Windows
447 Led_StdDialogHelper_URLXEmbeddingInfoDialog infoDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
448#endif
449#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
450 infoDialog.fEmbeddingTypeName = embeddingTypeName;
451 infoDialog.fTitleText = *urlTitle;
452 infoDialog.fURLText = *urlValue;
453 if (infoDialog.DoModal ()) {
454 *urlTitle = infoDialog.fTitleText;
455 *urlValue = infoDialog.fURLText;
456 return true;
457 }
458 else {
459 return false;
460 }
461#else
462 return false;
463#endif
464 }
465#endif
466#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
467 virtual bool ShowAddURLEmbeddingInfoDialog (SDKString* urlTitle, SDKString* urlValue) override
468 {
469#if qStroika_Foundation_Common_Platform_MacOS
470 Led_StdDialogHelper_AddURLXEmbeddingInfoDialog infoDialog;
471#elif qStroika_Foundation_Common_Platform_Windows
472 Led_StdDialogHelper_AddURLXEmbeddingInfoDialog infoDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
473#endif
474#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
475 infoDialog.fTitleText = *urlTitle;
476 infoDialog.fURLText = *urlValue;
477 if (infoDialog.DoModal ()) {
478 *urlTitle = infoDialog.fTitleText;
479 *urlValue = infoDialog.fURLText;
480 return true;
481 }
482 else {
483 return false;
484 }
485#else
486 return false;
487#endif
488 }
489#endif
490#if qSupportAddNewTableDlg
491 bool AddNewTableDialog (size_t* nRows, size_t* nCols)
492 {
493 RequireNotNull (nRows);
494 RequireNotNull (nCols);
495#if qStroika_Foundation_Common_Platform_MacOS
496 Led_StdDialogHelper_AddNewTableDialog infoDialog;
497#elif qStroika_Foundation_Common_Platform_Windows
498 Led_StdDialogHelper_AddNewTableDialog infoDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
499#endif
500 infoDialog.fRows = *nRows;
501 infoDialog.fColumns = *nCols;
502 if (infoDialog.DoModal ()) {
503 *nRows = infoDialog.fRows;
504 *nCols = infoDialog.fColumns;
505 return true;
506 }
507 else {
508 return false;
509 }
510 }
511#endif
512#if qSupportEditTablePropertiesDlg
513 virtual bool EditTablePropertiesDialog (TableSelectionPropertiesInfo* tableProperties) override
514 {
515 RequireNotNull (tableProperties);
516
517 using DLGTYPE = Led_StdDialogHelper_EditTablePropertiesDialog;
518#if qStroika_Foundation_Common_Platform_MacOS
519 DLGTYPE infoDialog;
520#elif qStroika_Foundation_Common_Platform_Windows
521 DLGTYPE infoDialog (::AfxGetResourceHandle (), ::GetActiveWindow ());
522#endif
523 DLGTYPE::cvt<DLGTYPE::Info, TableSelectionPropertiesInfo> (&infoDialog.fInfo, *tableProperties);
524 if (infoDialog.DoModal ()) {
525 DLGTYPE::cvt<TableSelectionPropertiesInfo, DLGTYPE::Info> (tableProperties, infoDialog.fInfo);
526 return true;
527 }
528 else {
529 return false;
530 }
531 }
532#endif
533};
534static LedIt_DialogSupport sLedIt_DialogSupport;
535
536/*
537 ********************************************************************************
538 ************************************ LedItView *********************************
539 ********************************************************************************
540 */
541#if qStroika_Foundation_Common_Platform_Windows
542IMPLEMENT_DYNCREATE (LedItView, CView)
543
544DISABLE_COMPILER_MSC_WARNING_START (4407) // Not sure this is safe to ignore but I think it is due to qMFCRequiresCWndLeftmostBaseClass
545BEGIN_MESSAGE_MAP (LedItView, LedItView::inherited)
546ON_WM_SETFOCUS ()
547ON_WM_SIZE ()
548ON_WM_CONTEXTMENU ()
549ON_COMMAND (ID_OLE_INSERT_NEW, &OnInsertObject)
550ON_COMMAND (ID_CANCEL_EDIT_CNTR, &OnCancelEditCntr)
551ON_COMMAND (ID_CANCEL_EDIT_SRVR, &OnCancelEditSrvr)
552ON_COMMAND (ID_FILE_PRINT, &OnFilePrint)
553ON_COMMAND (ID_FILE_PRINT_DIRECT, &OnFilePrint)
554ON_NOTIFY (NM_RETURN, ID_VIEW_FORMATBAR, &OnBarReturn)
555END_MESSAGE_MAP ()
556DISABLE_COMPILER_MSC_WARNING_END (4407)
557#endif
558
559LedItView::LedItView (
560#if qStroika_FeatureSupported_XWindows
561 LedItDocument* owningDoc
562#endif
563 )
564 : inherited ()
565 , fWrapToWindow (Options{}.GetWrapToWindow ())
566{
567 SetSmartCutAndPasteMode (Options{}.GetSmartCutAndPaste ());
568
569 SetShowParagraphGlyphs (Options{}.GetShowParagraphGlyphs ());
570 SetShowTabGlyphs (Options{}.GetShowTabGlyphs ());
571 SetShowSpaceGlyphs (Options{}.GetShowSpaceGlyphs ());
572#if qStroika_Foundation_Common_Platform_MacOS
573 SetScrollBarType (h, fWrapToWindow ? eScrollBarNever : eScrollBarAsNeeded);
574 SetScrollBarType (v, eScrollBarAlways);
575#elif qStroika_Foundation_Common_Platform_Windows
576 SetScrollBarType (h, fWrapToWindow ? eScrollBarNever : eScrollBarAsNeeded);
577 SetScrollBarType (v, eScrollBarAlways);
578#elif qStroika_FeatureSupported_XWindows
579 SpecifyTextStore (&owningDoc->GetTextStore ());
580 SetStyleDatabase (owningDoc->GetStyleDatabase ());
581 SetParagraphDatabase (owningDoc->GetParagraphDatabase ());
582 SetHidableTextDatabase (owningDoc->GetHidableTextDatabase ());
583 //SetShowHiddenText (Options{}.GetShowHiddenText ());
584 SetCommandHandler (&owningDoc->GetCommandHandler ());
585 SetSpellCheckEngine (&LedItApplication::Get ().fSpellCheckEngine);
586#endif
587#if qStroika_Foundation_Common_Platform_MacOS || qStroika_Foundation_Common_Platform_Windows
588 SetUseSecondaryHilight (true);
589#endif
590#if qStroika_Foundation_Common_Platform_Windows
591 // SHOULD be supported on other platforms, but only Win32 for now...
592 SetDefaultWindowMargins (TWIPS_Rect (kLedItViewTopMargin, kLedItViewLHSMargin, kLedItViewBottomMargin - kLedItViewTopMargin,
593 kLedItViewRHSMargin - kLedItViewLHSMargin));
594#endif
595}
596
597LedItView::~LedItView ()
598{
599 SpecifyTextStore (NULL);
600 SetCommandHandler (NULL);
601 SetSpellCheckEngine (NULL);
602}
603
604#if qStroika_Foundation_Common_Platform_Windows
605void LedItView::OnInitialUpdate ()
606{
607 inherited::OnInitialUpdate ();
608 SpecifyTextStore (&GetDocument ().GetTextStore ());
609 SetStyleDatabase (GetDocument ().GetStyleDatabase ());
610 SetParagraphDatabase (GetDocument ().GetParagraphDatabase ());
611 SetHidableTextDatabase (GetDocument ().GetHidableTextDatabase ());
612 SetShowHiddenText (Options{}.GetShowHiddenText ());
613 SetCommandHandler (&GetDocument ().GetCommandHandler ());
614 SetSpellCheckEngine (LedItApplication::Get ().fSpellCheckEngine.get ());
615
616 {
617 // Don't let this change the docs IsModified flag
618 bool docModified = GetDocument ().IsModified ();
619 // For an empty doc - grab from the default, and otherwise grab from the document itself
620 if (GetEnd () == 0) {
621 SetEmptySelectionStyle (Options{}.GetDefaultNewDocFont ());
622 }
623 else {
624 SetEmptySelectionStyle ();
625 }
626 InvalidateAllCaches (); // under rare circumstances, the caches don't all get cleared without this...
627 GetDocument ().SetModifiedFlag (docModified);
628 }
629 Invariant ();
630}
631#endif
632
633#if qStroika_Foundation_Common_Platform_Windows
634bool LedItView::OnUpdateCommand (CommandUpdater* enabler)
635{
636 RequireNotNull (enabler);
637 if (inherited::OnUpdateCommand (enabler)) {
638 return true;
639 }
640 // See SPR#1462 - yet assure these items in the formatBar remain enabled...
641 switch (enabler->GetCmdID ()) {
642 case IDC_FONTSIZE: {
643 enabler->SetEnabled (true);
644 return true;
645 }
646 case IDC_FONTNAME: {
647 enabler->SetEnabled (true);
648 return true;
649 }
650 }
651 return false;
652}
653#endif
654
655void LedItView::SetWrapToWindow (bool wrapToWindow)
656{
657 if (fWrapToWindow != wrapToWindow) {
658 fWrapToWindow = wrapToWindow;
659 SetScrollBarType (h, fWrapToWindow ? eScrollBarNever : eScrollBarAsNeeded);
660 InvalidateAllCaches ();
661 InvalidateScrollBarParameters ();
662 Refresh ();
663 }
664}
665
666void LedItView::GetLayoutMargins (RowReference row, CoordinateType* lhs, CoordinateType* rhs) const
667{
668 inherited::GetLayoutMargins (row, lhs, rhs);
669 if (fWrapToWindow) {
670 // Make the layout width of each line (paragraph) equal to the windowrect. Ie, wrap to the
671 // edge of the window. NB: because of this choice, we must 'InvalidateAllCaches' when the
672 // WindowRect changes in our SetWindowRect() override.
673 if (rhs != NULL) {
674 *rhs = (max (GetWindowRect ().GetWidth (), DistanceType (1)));
675 }
676 }
677}
678
679void LedItView::SetWindowRect (const Led_Rect& windowRect)
680{
681 Led_Rect oldWindowRect = GetWindowRect ();
682 // Hook all changes in the window width, so we can invalidate the word-wrap info (see LedItView::GetLayoutWidth)
683 if (windowRect != oldWindowRect) {
684 // NB: call "WordWrappedTextImager::SetWindowRect() instead of base class textinteractor to avoid infinite recursion"
685 WordWrappedTextImager::SetWindowRect (windowRect);
686 if (fWrapToWindow and windowRect.GetSize () != oldWindowRect.GetSize ()) {
687 InvalidateAllCaches ();
688 }
689 }
690}
691
692#if qStroika_Foundation_Common_Platform_MacOS
693void LedItView::FindCommandStatus (CommandT inCommand, Boolean& outEnabled, Boolean& outUsesMark, UInt16& outMark, Str255 outName)
694{
695 outUsesMark = false;
696 switch (inCommand) {
697 case cmd_ListStyleMenu:
698 outEnabled = true;
699 break;
700 case cmd_FontMenu:
701 outEnabled = true;
702 break;
703 case cmd_SizeMenu:
704 outEnabled = true;
705 break;
706 case cmd_StyleMenu:
707 outEnabled = true;
708 break;
709 case cmd_ColorMenu:
710 outEnabled = true;
711 break;
712 case cmd_JustificationMenu:
713 outEnabled = true;
714 break;
715
716 default: {
717 inherited::FindCommandStatus (inCommand, outEnabled, outUsesMark, outMark, outName);
718 } break;
719 }
720}
721#endif
722
723#if qStroika_Foundation_Common_Platform_Windows
724void LedItView::OnContextMenu (CWnd* /*pWnd*/, CPoint pt)
725{
726 CMenu menu;
727 if (menu.LoadMenu (kContextMenu)) {
728 CMenu* popup = menu.GetSubMenu (0);
729 AssertNotNull (popup);
730 LedItApplication::Get ().FixupFontMenu (popup->GetSubMenu (16));
731 popup->TrackPopupMenu (TPM_LEFTALIGN | TPM_RIGHTBUTTON, pt.x, pt.y, ::AfxGetMainWnd ());
732 }
733}
734
735BOOL LedItView::IsSelected (const CObject* pDocItem) const
736{
737 // The implementation below is adequate if your selection consists of
738 // only LedItControlItem objects. To handle different selection
739 // mechanisms, the implementation here should be replaced.
740
741 // TODO: implement this function that tests for a selected OLE client item
742 return pDocItem == GetSoleSelectedOLEEmbedding ();
743}
744#endif
745
746IncrementalParagraphInfo LedItView::GetParaFormatSelection ()
747{
748 //COULD SPEED TWEEK THIS - LIKE I DID FOR fCachedCurSelJustificationUnique
750 StandardTabStopList tabstops;
751 if (GetStandardTabStopList (GetSelectionStart (), GetSelectionEnd (), &tabstops)) {
752 ipi.SetTabStopList (tabstops);
753 }
754 TWIPS lhsMargin = TWIPS{0};
755 TWIPS rhsMargin = TWIPS{0};
756 if (GetMargins (GetSelectionStart (), GetSelectionEnd (), &lhsMargin, &rhsMargin)) {
757 ipi.SetMargins (lhsMargin, rhsMargin);
758 }
759 TWIPS firstIndent = TWIPS{0};
760 if (GetFirstIndent (GetSelectionStart (), GetSelectionEnd (), &firstIndent)) {
761 ipi.SetFirstIndent (firstIndent);
762 }
763 return ipi;
764}
765
766void LedItView::SetParaFormatSelection (const IncrementalParagraphInfo& pf)
767{
768 if (pf.GetTabStopList_Valid ()) {
769 InteractiveSetStandardTabStopList (pf.GetTabStopList ());
770 }
771 if (pf.GetMargins_Valid () and pf.GetFirstIndent_Valid ()) {
772 InteractiveSetMarginsAndFirstIndent (pf.GetLeftMargin (), pf.GetRightMargin (), pf.GetFirstIndent ());
773 }
774 else {
775 if (pf.GetMargins_Valid ()) {
776 InteractiveSetMargins (pf.GetLeftMargin (), pf.GetRightMargin ());
777 }
778 if (pf.GetFirstIndent_Valid ()) {
779 InteractiveSetFirstIndent (pf.GetFirstIndent ());
780 }
781 }
782}
783
784void LedItView::OnShowHideGlyphCommand (CommandNumber cmdNum)
785{
786 inherited::OnShowHideGlyphCommand (cmdNum);
787
788 Options{}.SetShowParagraphGlyphs (GetShowParagraphGlyphs ());
789 Options{}.SetShowTabGlyphs (GetShowTabGlyphs ());
790 Options{}.SetShowSpaceGlyphs (GetShowSpaceGlyphs ());
791}
792
793LedItView::SearchParameters LedItView::GetSearchParameters () const
794{
795 return Options{}.GetSearchParameters ();
796}
797
798void LedItView::SetSearchParameters (const SearchParameters& sp)
799{
800 Options{}.SetSearchParameters (sp);
801}
802
803void LedItView::SetShowHiddenText (bool showHiddenText)
804{
805 if (showHiddenText) {
806 GetHidableTextDatabase ()->ShowAll ();
807 }
808 else {
809 GetHidableTextDatabase ()->HideAll ();
810 }
811}
812
813#if qStroika_Foundation_Common_Platform_Windows
814void LedItView::OnInsertObject ()
815{
816 // Invoke the standard Insert Object dialog box to obtain information
817 // for new LedItControlItem object.
818 COleInsertDialog dlg (IOF_SELECTCREATECONTROL | IOF_SHOWINSERTCONTROL | IOF_VERIFYSERVERSEXIST);
819 if (dlg.DoModal () != IDOK) {
820 return;
821 }
822
823 CWaitCursor busy;
824
825 LedItControlItem* pItem = NULL;
826 TRY
827 {
828 // Create new item connected to this document.
829 LedItDocument& doc = GetDocument ();
830 pItem = new LedItControlItem (&doc);
831 ASSERT_VALID (pItem);
832
833 dlg.m_io.dwFlags |= IOF_SELECTCREATENEW;
834 // Initialize the item from the dialog data.
835 if (!dlg.CreateItem (pItem)) {
836 Execution::Throw (DataExchange::BadFormatException::kThe);
837 }
838 ASSERT_VALID (pItem);
839
840 BreakInGroupedCommands ();
841 UndoableContextHelper context (*this, Led_SDK_TCHAROF ("Insert OLE Embedding"), false);
842 {
843 AddEmbedding (pItem, GetTextStore (), GetSelectionStart (), GetDocument ().GetStyleDatabase ().get ());
844 SetSelection (GetSelectionStart () + 1, GetSelectionStart () + 1);
845 }
846 context.CommandComplete ();
847 BreakInGroupedCommands ();
848
849 // If item created from class list (not from file) then launch
850 // the server to edit the item.
851 if (dlg.GetSelectionType () == COleInsertDialog::createNewItem) {
852 pItem->DoVerb (OLEIVERB_SHOW, this);
853 }
854
855 ASSERT_VALID (pItem);
856
857 doc.UpdateAllViews (NULL);
858 }
859 CATCH (CException, e)
860 {
861 if (pItem != NULL) {
862 ASSERT_VALID (pItem);
863 pItem->Delete ();
864 }
865 AfxMessageBox (IDP_FAILED_TO_CREATE);
866 }
867 END_CATCH
868}
869
870// The following command handler provides the standard keyboard
871// user interface to cancel an in-place editing session. Here,
872// the container (not the server) causes the deactivation.
873void LedItView::OnCancelEditCntr ()
874{
875 // Close any in-place active item on this view.
876 COleClientItem* pActiveItem = GetDocument ().GetInPlaceActiveItem (this);
877 if (pActiveItem != NULL) {
878 pActiveItem->Close ();
879 }
880 ASSERT (GetDocument ().GetInPlaceActiveItem (this) == NULL);
881}
882
883// Special handling of OnSetFocus and OnSize are required for a container
884// when an object is being edited in-place.
885void LedItView::OnSetFocus (CWnd* pOldWnd)
886{
887 COleClientItem* pActiveItem = GetDocument ().GetInPlaceActiveItem (this);
888 if (pActiveItem != NULL && pActiveItem->GetItemState () == COleClientItem::activeUIState) {
889 // need to set focus to this item if it is in the same view
890 CWnd* pWnd = pActiveItem->GetInPlaceWindow ();
891 if (pWnd != NULL) {
892 pWnd->SetFocus (); // don't call the base class
893 return;
894 }
895 }
896 inherited::OnSetFocus (pOldWnd);
897}
898
899void LedItView::OnSize (UINT nType, int cx, int cy)
900{
901 inherited::OnSize (nType, cx, cy);
902
903 // ajust any active OLE embeddings, as needed
904 COleClientItem* pActiveItem = GetDocument ().GetInPlaceActiveItem (this);
905 if (pActiveItem != NULL) {
906 pActiveItem->SetItemRects ();
907 }
908}
909
910void LedItView::OnCancelEditSrvr ()
911{
912 GetDocument ().OnDeactivateUI (FALSE);
913}
914#endif
915
916#if qStroika_Foundation_Common_Platform_Windows
917LedItControlItem* LedItView::GetSoleSelectedOLEEmbedding () const
918{
919 return dynamic_cast<LedItControlItem*> (GetSoleSelectedEmbedding ());
920}
921
922void LedItView::OnBarReturn (NMHDR*, LRESULT*)
923{
924 // When we return from doing stuff in format bar, reset focus to our edit view. Try it without and
925 // you'll see how awkward it is...
926 SetFocus ();
927}
928
929#ifdef _DEBUG
930void LedItView::AssertValid () const
931{
932 inherited::AssertValid ();
933}
934
935void LedItView::Dump (CDumpContext& dc) const
936{
937 inherited::Dump (dc);
938}
939
940LedItDocument& LedItView::GetDocument () const // non-debug version is inline
941{
942 ASSERT (m_pDocument->IsKindOf (RUNTIME_CLASS (LedItDocument)));
943 ASSERT_VALID (m_pDocument);
944 return *(LedItDocument*)m_pDocument;
945}
946#endif //_DEBUG
947#endif
#define AssertNotNull(p)
Definition Assertions.h:333
#define RequireNotNull(p)
Definition Assertions.h:347