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