Stroika Library 3.0d16
 
Loading...
Searching...
No Matches
StandardStyledTextInteractor.h
1/*
2 * Copyright(c) Sophist Solutions, Inc. 1990-2025. All rights reserved
3 */
4#ifndef _Stroika_Frameworks_Led_StandardStyledTextInteractor_h_
5#define _Stroika_Frameworks_Led_StandardStyledTextInteractor_h_ 1
6
7#include "Stroika/Frameworks/StroikaPreComp.h"
8
9/*
10@MODULE: StandardStyledTextInteractor
11@DESCRIPTION:
12 <p>Combine the functionality of @'TextInteractor', and @'StandardStyledTextImager', and add a bunch of
13 related functionality (which only makes sense when you have both of these features).</p>
14
15 */
16
17#include "StandardStyledTextImager.h"
18#include "TextInteractor.h"
19
20#include "StyledTextIO/StyledTextIO.h"
21
22namespace Stroika::Frameworks::Led {
23
24 /*
25 @CONFIGVAR: qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
26 @DESCRIPTION: <p>This format isn't terribly useful right now. It may become much more useful in future versions, if I decide
27 to rewrite it, to make it much faster than RTF. Then I may use it internally more.</p>
28 <p>It should cause little harm being turned on, but some people (SPR#0810) have requested the ability to
29 have this code stripped out.</p>
30 <p>Turn ON by default.</p>
31 */
32#define qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor 0
33#ifndef qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
34#define qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor 1
35#endif
36
37#if qStroika_FeatureSupported_XWindows
38 extern Led_ClipFormat kLedPrivateClipFormat;
39 extern Led_ClipFormat kRTFClipFormat;
40 extern Led_ClipFormat kHTMLClipFormat;
41#else
42 extern const Led_ClipFormat kLedPrivateClipFormat;
43 extern const Led_ClipFormat kRTFClipFormat;
44 extern const Led_ClipFormat kHTMLClipFormat;
45#endif
46
47 /**
48 * <p>This is a writer source stream which talks to a StandardStyledTextImager and/or WordProcessor
49 * class. It knows about StyleDatabases, and ParagraphDatabases, and gets content from them for the
50 * output writer class.</p>
51 */
52 class StandardStyledTextIOSrcStream : public virtual StyledTextIO::StyledTextIOWriter::SrcStream {
53 private:
54 using inherited = StyledTextIO::StyledTextIOWriter::SrcStream;
55
56 public:
57 StandardStyledTextIOSrcStream (TextStore* textStore, const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
58 size_t selectionStart = 0, size_t selectionEnd = kBadIndex);
59#if qStroika_Frameworks_Led_SupportGDI
60 StandardStyledTextIOSrcStream (StandardStyledTextImager* textImager, size_t selectionStart = 0, size_t selectionEnd = kBadIndex);
61#endif
62
63 public:
64 virtual size_t readNTChars (Led_tChar* intoBuf, size_t maxTChars) override;
65 virtual size_t current_offset () const override;
66 virtual void seek_to (size_t to) override;
67 virtual size_t GetTotalTextLength () const override;
68 virtual vector<StyledInfoSummaryRecord> GetStyleInfo (size_t from, size_t len) const override;
69#if qStroika_Frameworks_Led_SupportGDI
70 virtual vector<SimpleEmbeddedObjectStyleMarker*> CollectAllEmbeddingMarkersInRange (size_t from, size_t to) const override;
71#endif
72 virtual Table* GetTableAt (size_t at) const override;
73 virtual void SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed) const override;
74 virtual size_t GetEmbeddingMarkerPosOffset () const override;
75
76 public:
77 nonvirtual size_t GetCurOffset () const;
78 nonvirtual size_t GetSelStart () const;
79 nonvirtual size_t GetSelEnd () const;
80
81 private:
82 TextStore* fTextStore;
83 shared_ptr<AbstractStyleDatabaseRep> fStyleRunDatabase;
84 size_t fCurOffset;
85 size_t fSelStart;
86 size_t fSelEnd;
87 };
88
89 /**
90 * <p>This is a writer sink stream which talks to a StandardStyledTextImager and/or WordProcessor
91 * class. It knows about StyleDatabases, and ParagraphDatabases, and writes content to them from the
92 * input reader class.</p>
93 */
94 class StandardStyledTextIOSinkStream : public virtual StyledTextIO::StyledTextIOReader::SinkStream {
95 private:
96 using inherited = StyledTextIO::StyledTextIOReader::SinkStream;
97
98 public:
99 StandardStyledTextIOSinkStream (TextStore* textStore, const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase, size_t insertionStart = 0);
101
102 public:
103 // if fontSpec is nullptr, use default. Probably later we will return and update the fontspec with
104 // ApplyStyle
105 virtual size_t current_offset () const override;
106 virtual void AppendText (const Led_tChar* text, size_t nTChars, const FontSpecification* fontSpec) override;
107 virtual void ApplyStyle (size_t from, size_t to, const vector<StyledInfoSummaryRecord>& styleRuns) override;
108 virtual FontSpecification GetDefaultFontSpec () const override;
109#if qStroika_Frameworks_Led_SupportGDI
110 virtual void InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding, size_t at) override;
111 virtual void AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding) override;
112#endif
113 virtual void AppendSoftLineBreak () override;
114 virtual void InsertMarker (Marker* m, size_t at, size_t length, MarkerOwner* markerOwner) override;
115 virtual void Flush () override;
116
117 public:
118 nonvirtual size_t GetInsertionStart () const;
119 nonvirtual void SetInsertionStart (size_t insertionStart);
120 nonvirtual size_t GetOriginalStart () const;
121 nonvirtual size_t GetCachedTextSize () const;
122
123 protected:
124 nonvirtual const vector<Led_tChar>& GetCachedText () const;
125
126 protected:
127 nonvirtual TextStore& GetTextStore () const;
128 nonvirtual shared_ptr<AbstractStyleDatabaseRep> GetStyleDatabase () const;
129
130 protected:
131 nonvirtual void PushContext (TextStore* ts, const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase, size_t insertionStart);
132 nonvirtual void PopContext ();
133
134 private:
135 struct Context {
136 TextStore* fTextStore;
137 shared_ptr<AbstractStyleDatabaseRep> fStyleRunDatabase;
138 size_t fOriginalStart;
139 size_t fInsertionStart;
140 };
141 vector<Context> fSavedContexts;
142
143 private:
144 TextStore* fTextStore{nullptr};
145 shared_ptr<AbstractStyleDatabaseRep> fStyleRunDatabase{nullptr};
146 size_t fOriginalStart{0};
147 size_t fInsertionStart{0};
148 vector<StyledInfoSummaryRecord> fSavedStyleInfo{};
149 vector<Led_tChar> fCachedText{};
150 };
151
152#if qStroika_Frameworks_Led_SupportGDI
153 class SimpleEmbeddedObjectStyleMarker;
154
155 DISABLE_COMPILER_MSC_WARNING_START (4250) // inherits via dominance warning
156 /*
157 @CLASS: StandardStyledTextInteractor
158 @BASES: virtual @'TextInteractor', @'StandardStyledTextImager'
159 @DESCRIPTION:
160 <p>Simple mixin of StandardStyledTextImager and TextInteractor.</p>
161 <p>Since this class is designed to make easier implementing a standard font/stylerun
162 type editor, we will OVERRIDE SetDefaultFont() and re-interpret it to mean
163 setting the font for the current selection of text, or for the nullptr selection,
164 just as with Apples TE.</p>
165 <p>NB: We considered using @'InteractorImagerMixinHelper<IMAGER>' template as base-class helper.
166 But it didn't help. We do too many overrides it doesn't, so it doesn't help much. And then
167 later mixing together two subclasses of InteractorImagerMixinHelper (like for word processor)
168 requires disambiguating stuff in InteractorImagerMixinHelper itself (like Draw).
169 Just not worth much. -- LGP 970707.</p>
170 */
171 class StandardStyledTextInteractor : public virtual TextInteractor, public StandardStyledTextImager {
172 private:
173 using inherited = void*; // prevent accidental references to this name in subclasses to base class name
174 protected:
175 StandardStyledTextInteractor ();
176
177 public:
178 virtual ~StandardStyledTextInteractor () = default;
179
180 public:
181 struct CommandNames;
182
183 // This class builds commands with command names. The UI may wish to change these
184 // names (eg. to customize for particular languages, etc)
185 // Just patch these strings here, and commands will be created with these names.
186 // (These names appear in text of undo menu item)
187 public:
188 static const CommandNames& GetCommandNames ();
189 static void SetCommandNames (const CommandNames& cmdNames);
190 static CommandNames MakeDefaultCommandNames ();
191
192 private:
193 static CommandNames sCommandNames;
194
195 protected:
196 virtual void HookLosingTextStore () override;
197 nonvirtual void HookLosingTextStore_ ();
198 virtual void HookGainedNewTextStore () override;
199 nonvirtual void HookGainedNewTextStore_ ();
200
201 public:
202 virtual void SetDefaultFont (const IncrementalFontSpecification& defaultFont) override;
203
204 public:
205 virtual void InteractiveSetFont (const IncrementalFontSpecification& defaultFont);
206
207 public:
208 virtual IncrementalFontSpecification GetContinuousStyleInfo (size_t from, size_t nTChars) const override;
209
210 public:
211 virtual void DidUpdateText (const UpdateInfo& updateInfo) noexcept override;
212
213 public:
214 virtual bool ShouldEnablePasteCommand () const override;
215 virtual bool CanAcceptFlavor (Led_ClipFormat clipFormat) const override;
216
217 public:
218 class StyledTextFlavorPackageInternalizer;
219 class StyledTextFlavorPackageExternalizer;
220
221 protected:
222 virtual void HookStyleDatabaseChanged () override;
223
224 protected:
225 virtual shared_ptr<FlavorPackageInternalizer> MakeDefaultInternalizer () override;
226 virtual shared_ptr<FlavorPackageExternalizer> MakeDefaultExternalizer () override;
227
228 protected:
229 virtual bool ProcessSimpleClick (Led_Point clickedAt, unsigned clickCount, bool extendSelection, size_t* dragAnchor) override;
230 virtual void WhileSimpleMouseTracking (Led_Point newMousePos, size_t dragAnchor) override;
231
232 public:
233 virtual void InteractiveReplace (const Led_tChar* withWhat, size_t withWhatCharCount, UpdateMode updateMode = eDefaultUpdate) override;
234 virtual void SetSelection (size_t start, size_t end) override;
235#if qUsingMemberNameToOverloadInWithUsingBug
236 void SetSelection (size_t start, size_t end, TextInteractor::UpdateMode updateMode)
237 {
238 TextInteractor::SetSelection (start, end, updateMode);
239 }
240#else
241 using TextInteractor::SetSelection;
242#endif
243 protected:
244 virtual bool InteractiveReplaceEarlyPostReplaceHook (size_t withWhatCharCount) override;
245 nonvirtual void SetSelection_ (size_t start, size_t end); // simply refills fEmptySelectionStyle
246 private:
247 bool fEmptySelectionStyleSuppressMode;
248 FontSpecification fEmptySelectionStyle;
249
250 public:
251 nonvirtual FontSpecification GetEmptySelectionStyle () const;
252 nonvirtual void SetEmptySelectionStyle ();
253 nonvirtual void SetEmptySelectionStyle (FontSpecification newEmptyFontSpec);
254
255 public:
256 nonvirtual vector<SimpleEmbeddedObjectStyleMarker*> CollectAllEmbeddingMarkersInRange (size_t from, size_t to) const;
257
258 protected:
259 virtual InteractiveReplaceCommand::SavedTextRep* InteractiveUndoHelperMakeTextRep (size_t regionStart, size_t regionEnd,
260 size_t selStart, size_t selEnd) override;
261
262 public:
263 class EmptySelStyleTextRep;
264 friend class EmptySelStyleTextRep;
265 };
266 DISABLE_COMPILER_MSC_WARNING_END (4250) // inherits via dominance warning
267
268 /*
269 @CLASS: StandardStyledTextInteractor::CommandNames
270 @DESCRIPTION: <p>Command names for each of the user-visible commands produced by the @'TextInteractor' module.
271 This name is used used in the constructed Undo command name, as
272 in, "Undo Change Font". You can replace this name with whatever you like.
273 You change this value with @'StandardStyledTextInteractor::SetCommandNames'.</p>
274 <p> The point of this is to allow for different UI-language localizations,
275 without having to change Led itself.</p>
276 <p>See also @'TextInteractor::GetCommandNames'.</p>
277 <p>See also @'TextInteractor::CommandNames'.</p>
278 */
279 struct StandardStyledTextInteractor::CommandNames {
280 SDKString fFontChangeCommandName;
281 };
282
283 /*
284 @CLASS: StandardStyledTextInteractor::StyledTextFlavorPackageInternalizer
285 @BASES: virtual @'FlavorPackageInternalizer'
286 @DESCRIPTION: <p>Add RTF, Led_Native, and SingleSelectedEmbedding support.</p>
287 */
288 class StandardStyledTextInteractor::StyledTextFlavorPackageInternalizer : public virtual FlavorPackageInternalizer {
289 private:
290 using inherited = FlavorPackageInternalizer;
291
292 public:
293 StyledTextFlavorPackageInternalizer (TextStore& ts, const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase);
294
295 public:
296 virtual bool InternalizeBestFlavor (ReaderFlavorPackage& flavorPackage, size_t from, size_t to) override;
297
298 public:
299 virtual void InternalizeFlavor_FILEGuessFormatsFromName (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
300 optional<CodePage> suggestedCodePage) override;
301 virtual void InternalizeFlavor_FILEGuessFormatsFromStartOfData (Led_ClipFormat* suggestedClipFormat, optional<CodePage> suggestedCodePage,
302 const byte* fileStart, const byte* fileEnd) override;
303
304 public:
305#if qStroika_Foundation_Common_Platform_MacOS
306 virtual bool InternalizeFlavor_STYLAndTEXT (ReaderFlavorPackage& flavorPackage, size_t from, size_t to);
307#endif
308#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
309 virtual bool InternalizeFlavor_Native (ReaderFlavorPackage& flavorPackage, size_t from, size_t to);
310#endif
311 virtual bool InternalizeFlavor_RTF (ReaderFlavorPackage& flavorPackage, size_t from, size_t to);
312 virtual bool InternalizeFlavor_HTML (ReaderFlavorPackage& flavorPackage, size_t from, size_t to);
313 virtual bool InternalizeFlavor_OtherRegisteredEmbedding (ReaderFlavorPackage& flavorPackage, size_t from, size_t to);
314
315 public:
316 virtual StandardStyledTextIOSinkStream* mkStandardStyledTextIOSinkStream (size_t insertionStart);
317
318 protected:
319 shared_ptr<AbstractStyleDatabaseRep> fStyleDatabase;
320 };
321
322 /*
323 @CLASS: StandardStyledTextInteractor::StyledTextFlavorPackageExternalizer
324 @BASES: virtual @'FlavorPackageExternalizer'
325 @DESCRIPTION: <p>Add RTF, Led_Native, and SingleSelectedEmbedding support.</p>
326 */
327 class StandardStyledTextInteractor::StyledTextFlavorPackageExternalizer : public virtual FlavorPackageExternalizer {
328 private:
329 using inherited = FlavorPackageExternalizer;
330
331 public:
332 StyledTextFlavorPackageExternalizer (TextStore& ts, const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase);
333
334 public:
335 virtual void ExternalizeFlavors (WriterFlavorPackage& flavorPackage, size_t from, size_t to) override;
336 virtual void ExternalizeBestFlavor (WriterFlavorPackage& flavorPackage, size_t from, size_t to) override;
337
338 public:
339#if qStroika_Foundation_Common_Platform_MacOS
340 nonvirtual void ExternalizeFlavor_STYL (WriterFlavorPackage& flavorPackage, size_t from, size_t to);
341#endif
342#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
343 nonvirtual void ExternalizeFlavor_Native (WriterFlavorPackage& flavorPackage, size_t from, size_t to);
344#endif
345 nonvirtual void ExternalizeFlavor_RTF (WriterFlavorPackage& flavorPackage, size_t from, size_t to);
346 nonvirtual void ExternalizeFlavor_SingleSelectedEmbedding (WriterFlavorPackage& flavorPackage, SimpleEmbeddedObjectStyleMarker* embedding);
347
348 protected:
349 virtual StandardStyledTextIOSrcStream* mkStandardStyledTextIOSrcStream (size_t selectionStart, size_t selectionEnd);
350
351 protected:
352 shared_ptr<AbstractStyleDatabaseRep> fStyleDatabase;
353 };
354
355 /*
356 @CLASS: StandardStyledTextInteractor::EmptySelStyleTextRep
357 @BASES: @'InteractiveReplaceCommand::SavedTextRep'
358 @DESCRIPTION:
359 */
360 class StandardStyledTextInteractor::EmptySelStyleTextRep : public InteractiveReplaceCommand::SavedTextRep {
361 private:
362 using inherited = InteractiveReplaceCommand::SavedTextRep;
363
364 public:
365 EmptySelStyleTextRep (StandardStyledTextInteractor* interactor, size_t selStart, size_t selEnd);
366
367 public:
368 virtual size_t GetLength () const override;
369 virtual void InsertSelf (TextInteractor* interactor, size_t at, size_t nBytesToOverwrite) override;
370
371 private:
372 FontSpecification fSavedStyle;
373 };
374#endif
375
376}
377
378/*
379 ********************************************************************************
380 ***************************** Implementation Details ***************************
381 ********************************************************************************
382 */
383#include "StandardStyledTextInteractor.inl"
384
385#endif /*_Stroika_Frameworks_Led_StandardStyledTextInteractor_h_*/