4#include "Stroika/Frameworks/StroikaPreComp.h"
6#include "Stroika/Foundation/DataExchange/BadFormatException.h"
9#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
10#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_HTML.h"
11#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_RTF.h"
13#include "StandardStyledTextInteractor.h"
15#if qStroika_Frameworks_Led_IncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
16#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_LedNative.h"
23using Memory::MakeSharedPtr;
25using namespace Stroika::Frameworks;
26using namespace Stroika::Frameworks::Led;
27using namespace Stroika::Frameworks::Led::StyledTextIO;
34StandardStyledTextIOSrcStream::StandardStyledTextIOSrcStream (TextStore* textStore,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
35 size_t selectionStart,
size_t selectionEnd)
36 : fTextStore (textStore)
37 , fStyleRunDatabase (textStyleDatabase)
38 , fCurOffset (selectionStart)
39 , fSelStart (selectionStart)
40 , fSelEnd (selectionEnd)
43 Require (textStyleDatabase.get () !=
nullptr);
44 Require (fSelStart >= 0);
45 Require (fSelEnd >= 0);
46 fSelEnd = min (fSelEnd, textStore->GetEnd ());
49#if qStroika_Frameworks_Led_SupportGDI
50StandardStyledTextIOSrcStream::StandardStyledTextIOSrcStream (StandardStyledTextImager* textImager,
size_t selectionStart,
size_t selectionEnd)
56size_t StandardStyledTextIOSrcStream::readNTChars (Led_tChar* intoBuf,
size_t maxTChars)
59 size_t bytesToRead = min (maxTChars, fSelEnd - fCurOffset);
60 Assert (bytesToRead <= maxTChars);
61 fTextStore->CopyOut (fCurOffset, bytesToRead, intoBuf);
62 fCurOffset += bytesToRead;
66size_t StandardStyledTextIOSrcStream::current_offset ()
const
68 return fCurOffset - fSelStart;
71void StandardStyledTextIOSrcStream::seek_to (
size_t to)
75 to = min (to, fSelEnd);
77 Ensure (fCurOffset >= fSelStart);
78 Ensure (fCurOffset <= fSelEnd);
81size_t StandardStyledTextIOSrcStream::GetTotalTextLength ()
const
83 Assert (fSelEnd >= fSelStart);
84 return (fSelEnd - fSelStart);
87vector<StyledInfoSummaryRecord> StandardStyledTextIOSrcStream::GetStyleInfo (
size_t from,
size_t len)
const
89 size_t effectiveFrom = from + fSelStart;
90#if qStroika_Foundation_Debug_AssertionsChecked
91 size_t effectiveTo = effectiveFrom + len;
93 Require (effectiveFrom >= fSelStart);
94 Require (effectiveFrom <= fSelEnd);
95#if qStroika_Foundation_Debug_AssertionsChecked
96 Require (effectiveTo >= fSelStart);
97 Require (effectiveTo <= fSelEnd);
99 return fStyleRunDatabase->GetStyleInfo (effectiveFrom, len);
102#if qStroika_Frameworks_Led_SupportGDI
103vector<SimpleEmbeddedObjectStyleMarker*> StandardStyledTextIOSrcStream::CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const
105 size_t effectiveFrom = from + fSelStart;
106 size_t effectiveTo = to + fSelStart;
107 Require (effectiveFrom >= fSelStart);
108 Require (effectiveFrom <= fSelEnd);
109 Require (effectiveTo >= fSelStart);
110 Require (effectiveTo <= fSelEnd);
112 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> result;
114 fTextStore->CollectAllMarkersInRangeInto (effectiveFrom, effectiveTo, TextStore::kAnyMarkerOwner, result);
115 return result.fResult;
119StandardStyledTextIOSrcStream::Table* StandardStyledTextIOSrcStream::GetTableAt (
size_t )
const
124void StandardStyledTextIOSrcStream::SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed)
const
126 if (fontNames !=
nullptr or colorsUsed !=
nullptr) {
127 size_t totalTextLength = GetTotalTextLength ();
128 vector<StyledInfoSummaryRecord> styleRuns;
129 if (totalTextLength != 0) {
130 styleRuns = GetStyleInfo (0, totalTextLength);
132 for (
auto i = styleRuns.begin (); i != styleRuns.end (); ++i) {
133 if (fontNames !=
nullptr) {
134 fontNames->insert ((*i).GetFontName ());
136 if (colorsUsed !=
nullptr) {
137 colorsUsed->insert ((*i).GetTextColor ());
143size_t StandardStyledTextIOSrcStream::GetEmbeddingMarkerPosOffset ()
const
153StandardStyledTextIOSinkStream::StandardStyledTextIOSinkStream (TextStore* textStore,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
154 size_t insertionStart)
155 : fTextStore{textStore}
156 , fStyleRunDatabase{textStyleDatabase}
157 , fOriginalStart{insertionStart}
158 , fInsertionStart{insertionStart}
161 Require (textStyleDatabase.get () !=
nullptr);
164StandardStyledTextIOSinkStream::~StandardStyledTextIOSinkStream ()
174size_t StandardStyledTextIOSinkStream::current_offset ()
const
176 return fInsertionStart - fOriginalStart;
179void StandardStyledTextIOSinkStream::AppendText (
const Led_tChar* text,
size_t nTChars,
const FontSpecification* fontSpec)
186 fCachedText.insert (fCachedText.end (), text, text + nTChars);
193 if (fontSpec ==
nullptr) {
194 if (fSavedStyleInfo.size () == 0) {
195 fSavedStyleInfo.push_back (StyledInfoSummaryRecord (fStyleRunDatabase->GetStyleInfo (fOriginalStart, 0)[0], nTChars));
198 fSavedStyleInfo.back ().fLength += nTChars;
202 fSavedStyleInfo.push_back (StyledInfoSummaryRecord (*fontSpec, nTChars));
205 fInsertionStart += nTChars;
208void StandardStyledTextIOSinkStream::ApplyStyle (
size_t from,
size_t to,
const vector<StyledInfoSummaryRecord>& styleRuns)
210 Require (from <= to);
211 if (GetCachedTextSize () != 0) {
214 fStyleRunDatabase->SetStyleInfo (fOriginalStart + from, to - from, styleRuns);
219 return GetStaticDefaultFont ();
222#if qStroika_Frameworks_Led_SupportGDI
223void StandardStyledTextIOSinkStream::InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding,
size_t at)
226 if (GetCachedTextSize () != 0) {
229 size_t effectiveFrom = fOriginalStart + at;
230 Led_tChar testSentinel;
232 fTextStore->CopyOut (effectiveFrom, 1, &testSentinel);
233 if (testSentinel != kEmbeddingSentinelChar) {
236 Stroika::Frameworks::Led::InsertEmbeddingForExistingSentinel (embedding, *fTextStore, effectiveFrom, fStyleRunDatabase.get ());
239void StandardStyledTextIOSinkStream::AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding)
243 if (GetCachedTextSize () != 0) {
246 AddEmbedding (embedding, *fTextStore, fInsertionStart, fStyleRunDatabase.get ());
251void StandardStyledTextIOSinkStream::AppendSoftLineBreak ()
254 AppendText (LED_TCHAR_OF (
"\n"), 1,
nullptr);
257void StandardStyledTextIOSinkStream::InsertMarker (Marker* m,
size_t at,
size_t length,
MarkerOwner* markerOwner)
259 Require (at <= current_offset ());
263 if (GetCachedTextSize () != 0) {
267 TextStore::SimpleUpdater u (*fTextStore, fOriginalStart + at, fOriginalStart + at + length);
268 fTextStore->AddMarker (m, fOriginalStart + at, length, markerOwner);
272void StandardStyledTextIOSinkStream::Flush ()
274 if (GetCachedTextSize () != 0) {
276 size_t dataSize = fCachedText.size ();
277 size_t whereToInsert = fInsertionStart - dataSize;
278 fTextStore->Replace (whereToInsert, whereToInsert, Traversal::Iterator2Pointer (fCachedText.begin ()), dataSize);
279 fCachedText.clear ();
282 fStyleRunDatabase->SetStyleInfo (whereToInsert, dataSize, fSavedStyleInfo.size (), Traversal::Iterator2Pointer (fSavedStyleInfo.begin ()));
283 fSavedStyleInfo.clear ();
285 Ensure (fSavedStyleInfo.size () == 0);
288void StandardStyledTextIOSinkStream::PushContext (TextStore* ts,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
size_t insertionStart)
290 Require (GetCachedTextSize () == 0);
293 c.fTextStore = fTextStore;
294 c.fStyleRunDatabase = fStyleRunDatabase;
295 c.fInsertionStart = fInsertionStart;
296 c.fOriginalStart = fOriginalStart;
297 fSavedContexts.push_back (c);
299 fStyleRunDatabase = textStyleDatabase;
300 fInsertionStart = insertionStart;
301 fOriginalStart = insertionStart;
304void StandardStyledTextIOSinkStream::PopContext ()
306 Require (GetCachedTextSize () == 0);
307 Require (not fSavedContexts.empty ());
308 fTextStore = fSavedContexts.back ().fTextStore;
309 fStyleRunDatabase = fSavedContexts.back ().fStyleRunDatabase;
310 fInsertionStart = fSavedContexts.back ().fInsertionStart;
311 fOriginalStart = fSavedContexts.back ().fOriginalStart;
312 fSavedContexts.pop_back ();
315#if qStroika_Frameworks_Led_SupportGDI
317#if qStroika_Platform_Windows
318const TCHAR kLedPrivateClipTypeName[] = _T (
"Led Rich Text Format");
319const Led_ClipFormat Led::kLedPrivateClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kLedPrivateClipTypeName));
320const TCHAR kRTFClipTypeName[] = _T (
"Rich Text Format");
321const Led_ClipFormat Led::kRTFClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kRTFClipTypeName));
322const TCHAR kHTMLClipTypeName[] = _T (
"HTML");
323const Led_ClipFormat Led::kHTMLClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kHTMLClipTypeName));
331StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::sCommandNames = StandardStyledTextInteractor::MakeDefaultCommandNames ();
333StandardStyledTextInteractor::StandardStyledTextInteractor ()
334 : fEmptySelectionStyleSuppressMode (false)
335 , fEmptySelectionStyle (GetStaticDefaultFont ())
339StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::MakeDefaultCommandNames ()
341 StandardStyledTextInteractor::CommandNames cmdNames;
342 cmdNames.fFontChangeCommandName = Led_SDK_TCHAROF (
"Font Change");
346void StandardStyledTextInteractor::HookLosingTextStore ()
348 TextInteractor::HookLosingTextStore ();
349 StandardStyledTextImager::HookLosingTextStore ();
350 HookLosingTextStore_ ();
353void StandardStyledTextInteractor::HookLosingTextStore_ ()
356 vector<SimpleEmbeddedObjectStyleMarker*> embeddings = CollectAllEmbeddingMarkersInRange (0, GetLength ());
357 for (
size_t i = 0; i < embeddings.size (); ++i) {
358 SimpleEmbeddedObjectStyleMarker* e = embeddings[i];
360 DISABLE_COMPILER_MSC_WARNING_START (28182)
361 if (e->GetOwner () == this) {
362 PeekAtTextStore ()->RemoveMarker (e);
365 DISABLE_COMPILER_MSC_WARNING_END (28182)
369void StandardStyledTextInteractor::HookGainedNewTextStore ()
371 TextInteractor::HookGainedNewTextStore ();
372 StandardStyledTextImager::HookGainedNewTextStore ();
373 HookGainedNewTextStore_ ();
376void StandardStyledTextInteractor::HookGainedNewTextStore_ ()
387void StandardStyledTextInteractor::SetDefaultFont (
const IncrementalFontSpecification& defaultFont)
389 size_t selStart = GetSelectionStart ();
390 size_t selEnd = GetSelectionEnd ();
391 if (selStart == selEnd) {
392 size_t selLength = selEnd - selStart;
394 newEmptySelectionStyle.MergeIn (defaultFont);
395 SetStyleInfo (selStart, selLength, defaultFont);
396 SetEmptySelectionStyle (newEmptySelectionStyle);
399 StandardStyledTextImager::SetDefaultFont (defaultFont);
416void StandardStyledTextInteractor::InteractiveSetFont (
const IncrementalFontSpecification& defaultFont)
418 InteractiveModeUpdater iuMode (*
this);
421 BreakInGroupedCommands ();
423 UndoableContextHelper undoContext (*
this, GetCommandNames ().fFontChangeCommandName,
false);
432 size_t selLength = undoContext.GetUndoRegionEnd () - undoContext.GetUndoRegionStart ();
434 newEmptySelectionStyle.MergeIn (defaultFont);
435 SetStyleInfo (undoContext.GetUndoRegionStart (), selLength, defaultFont);
436 SetEmptySelectionStyle (newEmptySelectionStyle);
439 undoContext.CommandComplete ();
442IncrementalFontSpecification StandardStyledTextInteractor::GetContinuousStyleInfo (
size_t from,
size_t nTChars)
const
444 if (nTChars == 0 and from == GetSelectionStart ()) {
445 vector<StyledInfoSummaryRecord> summaryInfo;
446 summaryInfo.push_back (StyledInfoSummaryRecord (fEmptySelectionStyle, 0));
447 return (GetContinuousStyleInfo_ (summaryInfo));
450 return StandardStyledTextImager::GetContinuousStyleInfo (from, nTChars);
454void StandardStyledTextInteractor::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
456 TextInteractor::DidUpdateText (updateInfo);
457 StandardStyledTextImager::DidUpdateText (updateInfo);
466bool StandardStyledTextInteractor::ShouldEnablePasteCommand ()
const
468 if (TextInteractor::ShouldEnablePasteCommand ()) {
471 if (Led_ClipboardObjectAcquire::FormatAvailable (kLedPrivateClipFormat)) {
474 if (Led_ClipboardObjectAcquire::FormatAvailable (kRTFClipFormat)) {
478 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
479 for (
size_t i = 0; i < types.size (); ++i) {
480 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
481 bool clipAvailForAll =
true;
482 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
483 if (not Led_ClipboardObjectAcquire::FormatAvailable (assoc.GetIthFormat (j))) {
484 clipAvailForAll =
false;
488 if (clipAvailForAll) {
495bool StandardStyledTextInteractor::CanAcceptFlavor (Led_ClipFormat clipFormat)
const
497 if (TextInteractor::CanAcceptFlavor (clipFormat)) {
500 if (clipFormat == kLedPrivateClipFormat) {
503 if (clipFormat == kRTFClipFormat) {
507 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
508 for (
size_t i = 0; i < types.size (); ++i) {
509 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
514 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
515 if (assoc.GetIthFormat (j) == clipFormat) {
523void StandardStyledTextInteractor::HookStyleDatabaseChanged ()
525 StandardStyledTextImager::HookStyleDatabaseChanged ();
526 if (PeekAtTextStore () !=
nullptr) {
528 SetExternalizer (MakeDefaultExternalizer ());
529 SetInternalizer (MakeDefaultInternalizer ());
533shared_ptr<FlavorPackageInternalizer> StandardStyledTextInteractor::MakeDefaultInternalizer ()
535 return MakeSharedPtr<StyledTextFlavorPackageInternalizer> (GetTextStore (), GetStyleDatabase ());
538shared_ptr<FlavorPackageExternalizer> StandardStyledTextInteractor::MakeDefaultExternalizer ()
540 return MakeSharedPtr<StyledTextFlavorPackageExternalizer> (GetTextStore (), GetStyleDatabase ());
548bool StandardStyledTextInteractor::ProcessSimpleClick (Led_Point clickedAt,
unsigned clickCount,
bool extendSelection,
size_t* dragAnchor)
551 size_t clickedOnChar = GetCharAtWindowLocation (clickedAt);
552 Led_Rect charRect = GetCharWindowLocation (clickedOnChar);
560 Led_Rect tstClickRect = charRect;
561 const DistanceType kHMargin = 3;
562 tstClickRect.left += kHMargin;
563 tstClickRect.right -= kHMargin;
565 if (tstClickRect.Contains (clickedAt)) {
566 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
567 Assert (embeddingList.size () == 0 or embeddingList.size () == 1);
569 if (embeddingList.size () == 1) {
570 SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
571 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
572 switch (clickCount) {
574 if (not extendSelection) {
575 SetSelection (clickedOnChar, clickedOnChar + 1);
577 if (clickCount == 1) {
580 *dragAnchor = clickedOnChar;
582 return embedding->HandleClick (clickedAt, 1);
588 if (not extendSelection) {
589 SetSelection (clickedOnChar, clickedOnChar + 1);
591 if (clickCount == 1) {
594 *dragAnchor = clickedOnChar;
596 return embedding->HandleClick (clickedAt, 2);
606 return TextInteractor::ProcessSimpleClick (clickedAt, clickCount, extendSelection, dragAnchor);
609void StandardStyledTextInteractor::WhileSimpleMouseTracking (Led_Point newMousePos,
size_t dragAnchor)
611 size_t clickedOnChar = GetCharAtWindowLocation (newMousePos);
612 size_t oldSelStart = GetSelectionStart ();
613 size_t oldSelEnd = GetSelectionEnd ();
620 if ((clickedOnChar == dragAnchor or clickedOnChar + 1 == dragAnchor) and (oldSelEnd - oldSelStart == 1)) {
621 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
622 if (embeddingList.size () == 1) {
623 [[maybe_unused]] SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
624 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
628 TextInteractor::WhileSimpleMouseTracking (newMousePos, dragAnchor);
631void StandardStyledTextInteractor::InteractiveReplace (
const Led_tChar* withWhat,
size_t withWhatCharCount, UpdateMode updateMode)
633 UpdateMode useUpdateMode = updateMode == eImmediateUpdate ? eDelayedUpdate : updateMode;
634 Assert (not fEmptySelectionStyleSuppressMode);
635 fEmptySelectionStyleSuppressMode =
true;
637 TextInteractor::InteractiveReplace (withWhat, withWhatCharCount, useUpdateMode);
638 fEmptySelectionStyleSuppressMode =
false;
641 fEmptySelectionStyleSuppressMode =
false;
644 if (updateMode == eImmediateUpdate) {
649void StandardStyledTextInteractor::SetSelection (
size_t start,
size_t end)
651 bool changed = (GetSelectionStart () != start) or (GetSelectionEnd () != end);
652 TextInteractor::SetSelection (start, end);
654 StandardStyledTextInteractor::SetSelection_ (start, end);
658void StandardStyledTextInteractor::SetSelection_ ([[maybe_unused]]
size_t start, [[maybe_unused]]
size_t end)
662 Require (start == GetSelectionStart ());
663 Require (end == GetSelectionEnd ());
664 if (not fEmptySelectionStyleSuppressMode) {
665 SetEmptySelectionStyle ();
678 return fEmptySelectionStyle;
687void StandardStyledTextInteractor::SetEmptySelectionStyle ()
691 GetSelection (&start, &end);
692 if (fLeftSideOfSelectionInteresting) {
693 if (start < GetTextStore ().GetEnd ()) {
694 fEmptySelectionStyle = GetStyleInfo (start);
698 fEmptySelectionStyle = GetStyleInfo (FindPreviousCharacter (end));
700 if (end == GetEnd ()) {
701 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
714void StandardStyledTextInteractor::SetEmptySelectionStyle (
FontSpecification newEmptyFontSpec)
716 if (fEmptySelectionStyle != newEmptyFontSpec) {
726 GetSelection (&selStart, &selEnd);
727 if (selStart == selEnd) {
730 TextStore::SimpleUpdater updater (GetTextStore (), selStart, selEnd,
false);
731 fEmptySelectionStyle = newEmptyFontSpec;
733 if (selEnd == GetEnd ()) {
734 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
740bool StandardStyledTextInteractor::InteractiveReplaceEarlyPostReplaceHook (
size_t withWhatCharCount)
742 Assert (GetSelectionStart () >= withWhatCharCount);
743 if (withWhatCharCount == 1) {
746 size_t charAt = FindPreviousCharacter (GetSelectionStart ());
748 if (prevStyle != fEmptySelectionStyle) {
749 SetStyleInfo (charAt, withWhatCharCount, IncrementalFontSpecification (fEmptySelectionStyle));
756vector<SimpleEmbeddedObjectStyleMarker*> StandardStyledTextInteractor::CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const
765 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> result;
766 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, result);
767 return result.fResult;
770InteractiveReplaceCommand::SavedTextRep* StandardStyledTextInteractor::InteractiveUndoHelperMakeTextRep (
size_t regionStart,
size_t regionEnd,
771 size_t selStart,
size_t selEnd)
773 if (regionStart == regionEnd) {
775 return new EmptySelStyleTextRep{
this, selStart, selEnd};
778 return TextInteractor::InteractiveUndoHelperMakeTextRep (regionStart, regionEnd, selStart, selEnd);
787using StyledTextFlavorPackageInternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageInternalizer;
788StyledTextFlavorPackageInternalizer::StyledTextFlavorPackageInternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
790 , fStyleDatabase (styleDatabase)
794void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromName (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
795 optional<CodePage> suggestedCodePage)
797 inherited::InternalizeFlavor_FILEGuessFormatsFromName (fileName, suggestedClipFormat, suggestedCodePage);
799#if qStroika_Platform_Windows
800 if (suggestedClipFormat !=
nullptr and *suggestedClipFormat == kBadClipFormat) {
801 TCHAR drive[_MAX_DRIVE];
803 TCHAR fname[_MAX_FNAME];
805 ::_tsplitpath_s (fileName.native ().c_str (), drive, dir, fname, ext);
806 if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".rtf")) == 0) {
807 *suggestedClipFormat = kRTFClipFormat;
809 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".htm")) == 0) {
810 *suggestedClipFormat = kHTMLClipFormat;
812 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".html")) == 0) {
813 *suggestedClipFormat = kHTMLClipFormat;
815 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".led")) == 0) {
816 *suggestedClipFormat = kLedPrivateClipFormat;
822void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromStartOfData (Led_ClipFormat* suggestedClipFormat,
823 optional<CodePage> suggestedCodePage,
824 const byte* fileStart,
const byte* fileEnd)
826 inherited::InternalizeFlavor_FILEGuessFormatsFromStartOfData (suggestedClipFormat, suggestedCodePage, fileStart, fileEnd);
827 if (suggestedClipFormat !=
nullptr) {
828 if (*suggestedClipFormat == kBadClipFormat) {
830 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
831 StyledTextIOReader_RTF reader (&source,
nullptr);
832 if (reader.QuickLookAppearsToBeRightFormat ()) {
833 *suggestedClipFormat = kRTFClipFormat;
839 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
840 StyledTextIOReader_HTML reader (&source,
nullptr);
841 if (reader.QuickLookAppearsToBeRightFormat ()) {
842 *suggestedClipFormat = kHTMLClipFormat;
847#if qStroika_Frameworks_Led_IncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
849 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
850 StyledTextIOReader_LedNativeFileFormat reader (&source,
nullptr);
851 if (reader.QuickLookAppearsToBeRightFormat ()) {
852 *suggestedClipFormat = kLedPrivateClipFormat;
861bool StyledTextFlavorPackageInternalizer::InternalizeBestFlavor (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
863 Require (from <= GetTextStore ().GetEnd ());
864 Require (to <= GetTextStore ().GetEnd ());
865 Require (from <= to);
867 if (InternalizeFlavor_RTF (flavorPackage, from, to)) {
870 else if (InternalizeFlavor_HTML (flavorPackage, from, to)) {
873#if qStroika_Frameworks_Led_IncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
874 else if (InternalizeFlavor_Native (flavorPackage, from, to)) {
878#if qStroika_Platform_Windows
885 else if (flavorPackage.GetFlavorAvailable (CF_DIB) and InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
889 else if (InternalizeFlavor_FILE (flavorPackage, from, to)) {
892 else if (InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
895 else if (InternalizeFlavor_TEXT (flavorPackage, from, to)) {
901#if qStroika_Frameworks_Led_IncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
902bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_Native (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
904 if (flavorPackage.GetFlavorAvailable (kLedPrivateClipFormat)) {
905 size_t length = flavorPackage.
GetFlavorSize (kLedPrivateClipFormat);
907 length = flavorPackage.ReadFlavorData (kLedPrivateClipFormat, length, buf);
911 Assert (end >= start);
913 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
916 StyledTextIOSrcStream_Memory source (buf, length);
917 unique_ptr<StandardStyledTextIOSinkStream> sink (mkStandardStyledTextIOSinkStream (start));
918 StyledTextIOReader_LedNativeFileFormat textReader (&source, sink.get ());
930bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_RTF (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
932 if (flavorPackage.GetFlavorAvailable (kRTFClipFormat)) {
933 size_t length = flavorPackage.
GetFlavorSize (kRTFClipFormat);
940 length = flavorPackage.ReadFlavorData (kRTFClipFormat, length, buf.data ());
944 Assert (end >= start);
946 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
949 StyledTextIOSrcStream_Memory source{buf.data (), length};
950 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
951 StyledTextIOReader_RTF textReader{&source, sink.get ()};
962bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_HTML (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
964 if (flavorPackage.GetFlavorAvailable (kHTMLClipFormat)) {
965 size_t length = flavorPackage.
GetFlavorSize (kHTMLClipFormat);
967 length = flavorPackage.ReadFlavorData (kHTMLClipFormat, length, buf.data ());
971 Assert (end >= start);
973 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
976 StyledTextIOSrcStream_Memory source{buf.data (), length};
977 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
978 StyledTextIOReader_HTML textReader{&source, sink.get ()};
989bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_OtherRegisteredEmbedding (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
991 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
992 for (
size_t i = 0; i < types.size (); ++i) {
993 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
994 bool clipAvailForAll = (assoc.fFormatTagCount != 0);
995 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
996 if (not flavorPackage.GetFlavorAvailable (assoc.GetIthFormat (j))) {
997 clipAvailForAll =
false;
1001 if (clipAvailForAll) {
1002 SimpleEmbeddedObjectStyleMarker* objMarker = (assoc.fReadFromFlavorPackage) (flavorPackage);
1004 size_t pasteStart = from;
1005 size_t pasteEnd = to;
1006 Assert (pasteEnd >= pasteStart);
1008 GetTextStore ().Replace (pasteStart, pasteEnd, &kEmbeddingSentinelChar, 1);
1012 TextStore::SimpleUpdater updater (GetTextStore (), pasteStart, pasteStart + 1);
1013 GetTextStore ().AddMarker (objMarker, pasteStart, 1, fStyleDatabase.get ());
1039using StyledTextFlavorPackageExternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageExternalizer;
1040StyledTextFlavorPackageExternalizer::StyledTextFlavorPackageExternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
1042 , fStyleDatabase (styleDatabase)
1046void StyledTextFlavorPackageExternalizer::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1048 size_t start = from;
1050 Require (start >= 0);
1051 Require (end <= GetTextStore ().GetEnd ());
1052 Require (start <= end);
1060 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> embeddings;
1061 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, embeddings);
1062 if ((embeddings.fResult.size () == 1) and (start + 1 == end)) {
1067 ExternalizeFlavor_SingleSelectedEmbedding (flavorPackage, embeddings.fResult[0]);
1081 ExternalizeFlavor_RTF (flavorPackage, start, end);
1083 ExternalizeFlavor_TEXT (flavorPackage, start, end);
1086void StyledTextFlavorPackageExternalizer::ExternalizeBestFlavor (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1088 ExternalizeFlavor_RTF (flavorPackage, from, to);
1091#if qStroika_Frameworks_Led_IncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
1092void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_Native (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1094 Require (from <= to);
1095 Require (to <= GetTextStore ().GetEnd ());
1096 unique_ptr<StandardStyledTextIOSrcStream> source (mkStandardStyledTextIOSrcStream (from, to));
1097 StyledTextIOWriterSinkStream_Memory sink;
1098 StyledTextIOWriter_LedNativeFileFormat textWriter (source.get (), &sink);
1099 textWriter.Write ();
1100 flavorPackage.AddFlavorData (kLedPrivateClipFormat, sink.GetLength (), sink.PeekAtData ());
1104void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_RTF (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1106 Require (from <= to);
1107 Require (to <= GetTextStore ().GetEnd ());
1108 unique_ptr<StandardStyledTextIOSrcStream> source{mkStandardStyledTextIOSrcStream (from, to)};
1109 StyledTextIOWriterSinkStream_Memory sink;
1110 StyledTextIOWriter_RTF textWriter{source.get (), &sink};
1111 textWriter.Write ();
1112 flavorPackage.AddFlavorData (kRTFClipFormat, sink.GetLength (), sink.PeekAtData ());
1115void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_SingleSelectedEmbedding (
WriterFlavorPackage& flavorPackage,
1116 SimpleEmbeddedObjectStyleMarker* embedding)
1119 embedding->ExternalizeFlavors (flavorPackage);
1128StandardStyledTextIOSrcStream* StyledTextFlavorPackageExternalizer::mkStandardStyledTextIOSrcStream (
size_t selectionStart,
size_t selectionEnd)
1138using EmptySelStyleTextRep = StandardStyledTextInteractor::EmptySelStyleTextRep;
1140EmptySelStyleTextRep::EmptySelStyleTextRep (StandardStyledTextInteractor* interactor,
size_t selStart,
size_t selEnd)
1141 : inherited{selStart, selEnd}
1142 , fSavedStyle{interactor->fEmptySelectionStyle}
1146size_t EmptySelStyleTextRep::GetLength ()
const
1151void EmptySelStyleTextRep::InsertSelf (TextInteractor* interactor,
size_t at,
size_t nBytesToOverwrite)
1154 interactor->Replace (at, at + nBytesToOverwrite, LED_TCHAR_OF (
""), 0);
1156 StandardStyledTextInteractor* si =
dynamic_cast<StandardStyledTextInteractor*
> (interactor);
1159 si->SetEmptySelectionStyle (fSavedStyle);
#define RequireNotNull(p)
#define AssertMember(p, c)
Logically halfway between std::array and std::vector; Smart 'direct memory array' - which when needed...
virtual size_t GetFlavorSize(Led_ClipFormat clipFormat) const =0
void Throw(T &&e2Throw)
like the builtin C++ 'throw', but stamps in the current Activity context and does helpful,...