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 qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
16#include "Stroika/Frameworks/Led/StyledTextIO/Led_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_Foundation_Common_Platform_MacOS
318const Led_ClipFormat Led::kLedPrivateClipFormat =
'LedP';
319const Led_ClipFormat Led::kRTFClipFormat =
'RTF ';
320const Led_ClipFormat Led::kHTMLClipFormat =
'HTML';
321#elif qStroika_Foundation_Common_Platform_Windows
322const TCHAR kLedPrivateClipTypeName[] = _T (
"Led Rich Text Format");
323const Led_ClipFormat Led::kLedPrivateClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kLedPrivateClipTypeName));
324const TCHAR kRTFClipTypeName[] = _T (
"Rich Text Format");
325const Led_ClipFormat Led::kRTFClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kRTFClipTypeName));
326const TCHAR kHTMLClipTypeName[] = _T (
"HTML");
327const Led_ClipFormat Led::kHTMLClipFormat =
static_cast<Led_ClipFormat
> (::RegisterClipboardFormat (kHTMLClipTypeName));
328#elif qStroika_FeatureSupported_XWindows
331Led_ClipFormat kLedPrivateClipFormat = 0;
332Led_ClipFormat kRTFClipFormat = 0;
333Led_ClipFormat kHTMLClipFormat = 0;
341StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::sCommandNames = StandardStyledTextInteractor::MakeDefaultCommandNames ();
343StandardStyledTextInteractor::StandardStyledTextInteractor ()
344 : fEmptySelectionStyleSuppressMode (false)
345 , fEmptySelectionStyle (GetStaticDefaultFont ())
349StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::MakeDefaultCommandNames ()
351 StandardStyledTextInteractor::CommandNames cmdNames;
352 cmdNames.fFontChangeCommandName = Led_SDK_TCHAROF (
"Font Change");
356void StandardStyledTextInteractor::HookLosingTextStore ()
358 TextInteractor::HookLosingTextStore ();
359 StandardStyledTextImager::HookLosingTextStore ();
360 HookLosingTextStore_ ();
363void StandardStyledTextInteractor::HookLosingTextStore_ ()
366 vector<SimpleEmbeddedObjectStyleMarker*> embeddings = CollectAllEmbeddingMarkersInRange (0, GetLength ());
367 for (
size_t i = 0; i < embeddings.size (); ++i) {
368 SimpleEmbeddedObjectStyleMarker* e = embeddings[i];
370 DISABLE_COMPILER_MSC_WARNING_START (28182)
371 if (e->GetOwner () == this) {
372 PeekAtTextStore ()->RemoveMarker (e);
375 DISABLE_COMPILER_MSC_WARNING_END (28182)
379void StandardStyledTextInteractor::HookGainedNewTextStore ()
381 TextInteractor::HookGainedNewTextStore ();
382 StandardStyledTextImager::HookGainedNewTextStore ();
383 HookGainedNewTextStore_ ();
386void StandardStyledTextInteractor::HookGainedNewTextStore_ ()
397void StandardStyledTextInteractor::SetDefaultFont (
const IncrementalFontSpecification& defaultFont)
399 size_t selStart = GetSelectionStart ();
400 size_t selEnd = GetSelectionEnd ();
401 if (selStart == selEnd) {
402 size_t selLength = selEnd - selStart;
404 newEmptySelectionStyle.MergeIn (defaultFont);
405 SetStyleInfo (selStart, selLength, defaultFont);
406 SetEmptySelectionStyle (newEmptySelectionStyle);
409 StandardStyledTextImager::SetDefaultFont (defaultFont);
426void StandardStyledTextInteractor::InteractiveSetFont (
const IncrementalFontSpecification& defaultFont)
428 InteractiveModeUpdater iuMode (*
this);
431 BreakInGroupedCommands ();
433 UndoableContextHelper undoContext (*
this, GetCommandNames ().fFontChangeCommandName,
false);
442 size_t selLength = undoContext.GetUndoRegionEnd () - undoContext.GetUndoRegionStart ();
444 newEmptySelectionStyle.MergeIn (defaultFont);
445 SetStyleInfo (undoContext.GetUndoRegionStart (), selLength, defaultFont);
446 SetEmptySelectionStyle (newEmptySelectionStyle);
449 undoContext.CommandComplete ();
452IncrementalFontSpecification StandardStyledTextInteractor::GetContinuousStyleInfo (
size_t from,
size_t nTChars)
const
454 if (nTChars == 0 and from == GetSelectionStart ()) {
455 vector<StyledInfoSummaryRecord> summaryInfo;
456 summaryInfo.push_back (StyledInfoSummaryRecord (fEmptySelectionStyle, 0));
457 return (GetContinuousStyleInfo_ (summaryInfo));
460 return StandardStyledTextImager::GetContinuousStyleInfo (from, nTChars);
464void StandardStyledTextInteractor::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
466 TextInteractor::DidUpdateText (updateInfo);
467 StandardStyledTextImager::DidUpdateText (updateInfo);
476bool StandardStyledTextInteractor::ShouldEnablePasteCommand ()
const
478 if (TextInteractor::ShouldEnablePasteCommand ()) {
481 if (Led_ClipboardObjectAcquire::FormatAvailable (kLedPrivateClipFormat)) {
484 if (Led_ClipboardObjectAcquire::FormatAvailable (kRTFClipFormat)) {
488 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
489 for (
size_t i = 0; i < types.size (); ++i) {
490 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
491 bool clipAvailForAll =
true;
492 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
493 if (not Led_ClipboardObjectAcquire::FormatAvailable (assoc.GetIthFormat (j))) {
494 clipAvailForAll =
false;
498 if (clipAvailForAll) {
505bool StandardStyledTextInteractor::CanAcceptFlavor (Led_ClipFormat clipFormat)
const
507 if (TextInteractor::CanAcceptFlavor (clipFormat)) {
510 if (clipFormat == kLedPrivateClipFormat) {
513 if (clipFormat == kRTFClipFormat) {
517 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
518 for (
size_t i = 0; i < types.size (); ++i) {
519 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
524 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
525 if (assoc.GetIthFormat (j) == clipFormat) {
533void StandardStyledTextInteractor::HookStyleDatabaseChanged ()
535 StandardStyledTextImager::HookStyleDatabaseChanged ();
536 if (PeekAtTextStore () !=
nullptr) {
538 SetExternalizer (MakeDefaultExternalizer ());
539 SetInternalizer (MakeDefaultInternalizer ());
543shared_ptr<FlavorPackageInternalizer> StandardStyledTextInteractor::MakeDefaultInternalizer ()
545 return MakeSharedPtr<StyledTextFlavorPackageInternalizer> (GetTextStore (), GetStyleDatabase ());
548shared_ptr<FlavorPackageExternalizer> StandardStyledTextInteractor::MakeDefaultExternalizer ()
550 return MakeSharedPtr<StyledTextFlavorPackageExternalizer> (GetTextStore (), GetStyleDatabase ());
558bool StandardStyledTextInteractor::ProcessSimpleClick (Led_Point clickedAt,
unsigned clickCount,
bool extendSelection,
size_t* dragAnchor)
561 size_t clickedOnChar = GetCharAtWindowLocation (clickedAt);
562 Led_Rect charRect = GetCharWindowLocation (clickedOnChar);
570 Led_Rect tstClickRect = charRect;
571 const DistanceType kHMargin = 3;
572 tstClickRect.left += kHMargin;
573 tstClickRect.right -= kHMargin;
575 if (tstClickRect.Contains (clickedAt)) {
576 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
577 Assert (embeddingList.size () == 0 or embeddingList.size () == 1);
579 if (embeddingList.size () == 1) {
580 SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
581 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
582 switch (clickCount) {
584 if (not extendSelection) {
585 SetSelection (clickedOnChar, clickedOnChar + 1);
587 if (clickCount == 1) {
590 *dragAnchor = clickedOnChar;
592 return embedding->HandleClick (clickedAt, 1);
598 if (not extendSelection) {
599 SetSelection (clickedOnChar, clickedOnChar + 1);
601 if (clickCount == 1) {
604 *dragAnchor = clickedOnChar;
606 return embedding->HandleClick (clickedAt, 2);
616 return TextInteractor::ProcessSimpleClick (clickedAt, clickCount, extendSelection, dragAnchor);
619void StandardStyledTextInteractor::WhileSimpleMouseTracking (Led_Point newMousePos,
size_t dragAnchor)
621 size_t clickedOnChar = GetCharAtWindowLocation (newMousePos);
622 size_t oldSelStart = GetSelectionStart ();
623 size_t oldSelEnd = GetSelectionEnd ();
630 if ((clickedOnChar == dragAnchor or clickedOnChar + 1 == dragAnchor) and (oldSelEnd - oldSelStart == 1)) {
631 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
632 if (embeddingList.size () == 1) {
633 [[maybe_unused]] SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
634 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
638 TextInteractor::WhileSimpleMouseTracking (newMousePos, dragAnchor);
641void StandardStyledTextInteractor::InteractiveReplace (
const Led_tChar* withWhat,
size_t withWhatCharCount, UpdateMode updateMode)
643 UpdateMode useUpdateMode = updateMode == eImmediateUpdate ? eDelayedUpdate : updateMode;
644 Assert (not fEmptySelectionStyleSuppressMode);
645 fEmptySelectionStyleSuppressMode =
true;
647 TextInteractor::InteractiveReplace (withWhat, withWhatCharCount, useUpdateMode);
648 fEmptySelectionStyleSuppressMode =
false;
651 fEmptySelectionStyleSuppressMode =
false;
654 if (updateMode == eImmediateUpdate) {
659void StandardStyledTextInteractor::SetSelection (
size_t start,
size_t end)
661 bool changed = (GetSelectionStart () != start) or (GetSelectionEnd () != end);
662 TextInteractor::SetSelection (start, end);
664 StandardStyledTextInteractor::SetSelection_ (start, end);
668void StandardStyledTextInteractor::SetSelection_ ([[maybe_unused]]
size_t start, [[maybe_unused]]
size_t end)
672 Require (start == GetSelectionStart ());
673 Require (end == GetSelectionEnd ());
674 if (not fEmptySelectionStyleSuppressMode) {
675 SetEmptySelectionStyle ();
688 return fEmptySelectionStyle;
697void StandardStyledTextInteractor::SetEmptySelectionStyle ()
701 GetSelection (&start, &end);
702 if (fLeftSideOfSelectionInteresting) {
703 if (start < GetTextStore ().GetEnd ()) {
704 fEmptySelectionStyle = GetStyleInfo (start);
708 fEmptySelectionStyle = GetStyleInfo (FindPreviousCharacter (end));
710 if (end == GetEnd ()) {
711 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
724void StandardStyledTextInteractor::SetEmptySelectionStyle (
FontSpecification newEmptyFontSpec)
726 if (fEmptySelectionStyle != newEmptyFontSpec) {
736 GetSelection (&selStart, &selEnd);
737 if (selStart == selEnd) {
740 TextStore::SimpleUpdater updater (GetTextStore (), selStart, selEnd,
false);
741 fEmptySelectionStyle = newEmptyFontSpec;
743 if (selEnd == GetEnd ()) {
744 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
750bool StandardStyledTextInteractor::InteractiveReplaceEarlyPostReplaceHook (
size_t withWhatCharCount)
752 Assert (GetSelectionStart () >= withWhatCharCount);
753 if (withWhatCharCount == 1) {
756 size_t charAt = FindPreviousCharacter (GetSelectionStart ());
758 if (prevStyle != fEmptySelectionStyle) {
759 SetStyleInfo (charAt, withWhatCharCount, IncrementalFontSpecification (fEmptySelectionStyle));
766vector<SimpleEmbeddedObjectStyleMarker*> StandardStyledTextInteractor::CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const
775 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> result;
776 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, result);
777 return result.fResult;
780InteractiveReplaceCommand::SavedTextRep* StandardStyledTextInteractor::InteractiveUndoHelperMakeTextRep (
size_t regionStart,
size_t regionEnd,
781 size_t selStart,
size_t selEnd)
783 if (regionStart == regionEnd) {
785 return new EmptySelStyleTextRep{
this, selStart, selEnd};
788 return TextInteractor::InteractiveUndoHelperMakeTextRep (regionStart, regionEnd, selStart, selEnd);
797using StyledTextFlavorPackageInternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageInternalizer;
798StyledTextFlavorPackageInternalizer::StyledTextFlavorPackageInternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
800 , fStyleDatabase (styleDatabase)
804void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromName (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
805 optional<CodePage> suggestedCodePage)
807 inherited::InternalizeFlavor_FILEGuessFormatsFromName (fileName, suggestedClipFormat, suggestedCodePage);
809#if qStroika_Foundation_Common_Platform_MacOS
812#elif qStroika_Foundation_Common_Platform_Windows
813 if (suggestedClipFormat !=
nullptr and *suggestedClipFormat == kBadClipFormat) {
814 TCHAR drive[_MAX_DRIVE];
816 TCHAR fname[_MAX_FNAME];
818 ::_tsplitpath_s (fileName.native ().c_str (), drive, dir, fname, ext);
819 if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".rtf")) == 0) {
820 *suggestedClipFormat = kRTFClipFormat;
822 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".htm")) == 0) {
823 *suggestedClipFormat = kHTMLClipFormat;
825 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".html")) == 0) {
826 *suggestedClipFormat = kHTMLClipFormat;
828 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".led")) == 0) {
829 *suggestedClipFormat = kLedPrivateClipFormat;
835void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromStartOfData (Led_ClipFormat* suggestedClipFormat,
836 optional<CodePage> suggestedCodePage,
837 const byte* fileStart,
const byte* fileEnd)
839 inherited::InternalizeFlavor_FILEGuessFormatsFromStartOfData (suggestedClipFormat, suggestedCodePage, fileStart, fileEnd);
840 if (suggestedClipFormat !=
nullptr) {
841 if (*suggestedClipFormat == kBadClipFormat) {
843 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
844 StyledTextIOReader_RTF reader (&source,
nullptr);
845 if (reader.QuickLookAppearsToBeRightFormat ()) {
846 *suggestedClipFormat = kRTFClipFormat;
852 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
853 StyledTextIOReader_HTML reader (&source,
nullptr);
854 if (reader.QuickLookAppearsToBeRightFormat ()) {
855 *suggestedClipFormat = kHTMLClipFormat;
860#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
862 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
863 StyledTextIOReader_LedNativeFileFormat reader (&source,
nullptr);
864 if (reader.QuickLookAppearsToBeRightFormat ()) {
865 *suggestedClipFormat = kLedPrivateClipFormat;
874bool StyledTextFlavorPackageInternalizer::InternalizeBestFlavor (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
876 Require (from <= GetTextStore ().GetEnd ());
877 Require (to <= GetTextStore ().GetEnd ());
878 Require (from <= to);
880 if (InternalizeFlavor_RTF (flavorPackage, from, to)) {
883 else if (InternalizeFlavor_HTML (flavorPackage, from, to)) {
886#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
887 else if (InternalizeFlavor_Native (flavorPackage, from, to)) {
891#if qStroika_Foundation_Common_Platform_Windows
898 else if (flavorPackage.GetFlavorAvailable (CF_DIB) and InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
902 else if (InternalizeFlavor_FILE (flavorPackage, from, to)) {
905 else if (InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
908#if qStroika_Foundation_Common_Platform_MacOS
909 else if (InternalizeFlavor_STYLAndTEXT (flavorPackage, from, to)) {
913 else if (InternalizeFlavor_TEXT (flavorPackage, from, to)) {
919#if qStroika_Foundation_Common_Platform_MacOS
920bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_STYLAndTEXT (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
922 size_t pasteStart = from;
923 size_t pasteEnd = to;
924 Assert (pasteEnd >= pasteStart);
926 TempMarker newSel (GetTextStore (), pasteStart + 1, pasteStart + 1);
927 if (inherited::InternalizeFlavor_TEXT (flavorPackage, pasteStart, pasteEnd)) {
928 if (flavorPackage.GetFlavorAvailable (
'styl')) {
931 length = flavorPackage.ReadFlavorData (
'styl', length, buf);
932 Assert (newSel.GetStart () >= pasteStart + 1);
933 size_t pasteEndXXX = newSel.GetStart () - 1;
934 Assert (pasteEndXXX >= pasteStart);
935 StScrpRec* styleRecords =
reinterpret_cast<StScrpRec*
> (
static_cast<char*
> (buf));
936 vector<StyledInfoSummaryRecord> ledStyleInfo = StandardStyledTextImager::Convert (styleRecords->scrpStyleTab, styleRecords->scrpNStyles);
937 fStyleDatabase->SetStyleInfo (pasteStart, pasteEndXXX - pasteStart, ledStyleInfo);
948#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
949bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_Native (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
951 if (flavorPackage.GetFlavorAvailable (kLedPrivateClipFormat)) {
952 size_t length = flavorPackage.
GetFlavorSize (kLedPrivateClipFormat);
954 length = flavorPackage.ReadFlavorData (kLedPrivateClipFormat, length, buf);
958 Assert (end >= start);
960 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
963 StyledTextIOSrcStream_Memory source (buf, length);
964 unique_ptr<StandardStyledTextIOSinkStream> sink (mkStandardStyledTextIOSinkStream (start));
965 StyledTextIOReader_LedNativeFileFormat textReader (&source, sink.get ());
977bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_RTF (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
979 if (flavorPackage.GetFlavorAvailable (kRTFClipFormat)) {
980 size_t length = flavorPackage.
GetFlavorSize (kRTFClipFormat);
987 length = flavorPackage.ReadFlavorData (kRTFClipFormat, length, buf.data ());
991 Assert (end >= start);
993 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
996 StyledTextIOSrcStream_Memory source{buf.data (), length};
997 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
998 StyledTextIOReader_RTF textReader{&source, sink.get ()};
1009bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_HTML (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
1011 if (flavorPackage.GetFlavorAvailable (kHTMLClipFormat)) {
1012 size_t length = flavorPackage.
GetFlavorSize (kHTMLClipFormat);
1014 length = flavorPackage.ReadFlavorData (kHTMLClipFormat, length, buf.data ());
1016 size_t start = from;
1018 Assert (end >= start);
1020 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
1023 StyledTextIOSrcStream_Memory source{buf.data (), length};
1024 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
1025 StyledTextIOReader_HTML textReader{&source, sink.get ()};
1036bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_OtherRegisteredEmbedding (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
1038 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
1039 for (
size_t i = 0; i < types.size (); ++i) {
1040 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
1041 bool clipAvailForAll = (assoc.fFormatTagCount != 0);
1042 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
1043 if (not flavorPackage.GetFlavorAvailable (assoc.GetIthFormat (j))) {
1044 clipAvailForAll =
false;
1048 if (clipAvailForAll) {
1049 SimpleEmbeddedObjectStyleMarker* objMarker = (assoc.fReadFromFlavorPackage) (flavorPackage);
1051 size_t pasteStart = from;
1052 size_t pasteEnd = to;
1053 Assert (pasteEnd >= pasteStart);
1055 GetTextStore ().Replace (pasteStart, pasteEnd, &kEmbeddingSentinelChar, 1);
1059 TextStore::SimpleUpdater updater (GetTextStore (), pasteStart, pasteStart + 1);
1060 GetTextStore ().AddMarker (objMarker, pasteStart, 1, fStyleDatabase.get ());
1086using StyledTextFlavorPackageExternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageExternalizer;
1087StyledTextFlavorPackageExternalizer::StyledTextFlavorPackageExternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
1089 , fStyleDatabase (styleDatabase)
1093void StyledTextFlavorPackageExternalizer::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1095 size_t start = from;
1097 Require (start >= 0);
1098 Require (end <= GetTextStore ().GetEnd ());
1099 Require (start <= end);
1107 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> embeddings;
1108 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, embeddings);
1109 if ((embeddings.fResult.size () == 1) and (start + 1 == end)) {
1114 ExternalizeFlavor_SingleSelectedEmbedding (flavorPackage, embeddings.fResult[0]);
1128 ExternalizeFlavor_RTF (flavorPackage, start, end);
1130 ExternalizeFlavor_TEXT (flavorPackage, start, end);
1132#if qStroika_Foundation_Common_Platform_MacOS
1133 ExternalizeFlavor_STYL (flavorPackage, start, end);
1137void StyledTextFlavorPackageExternalizer::ExternalizeBestFlavor (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1139 ExternalizeFlavor_RTF (flavorPackage, from, to);
1142#if qStroika_Foundation_Common_Platform_MacOS
1143void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_STYL (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1145 Require (from <= to);
1146 Require (to <= GetTextStore ().GetEnd ());
1147 size_t length = to - from;
1149 vector<StyledInfoSummaryRecord> ledStyleRuns = fStyleDatabase->GetStyleInfo (from, length);
1150 size_t nStyleRuns = ledStyleRuns.size ();
1152 Assert (offsetof (StScrpRec, scrpStyleTab) ==
sizeof (
short));
1154 size_t nBytes =
sizeof (short) + nStyleRuns *
sizeof (ScrpSTElement);
1156 StScrpPtr stylePtr = (StScrpPtr)(
char*)buf;
1158 stylePtr->scrpNStyles = nStyleRuns;
1159 StandardStyledTextImager::Convert (ledStyleRuns, stylePtr->scrpStyleTab);
1160 flavorPackage.AddFlavorData (
'styl', nBytes, stylePtr);
1164#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
1165void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_Native (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1167 Require (from <= to);
1168 Require (to <= GetTextStore ().GetEnd ());
1169 unique_ptr<StandardStyledTextIOSrcStream> source (mkStandardStyledTextIOSrcStream (from, to));
1170 StyledTextIOWriterSinkStream_Memory sink;
1171 StyledTextIOWriter_LedNativeFileFormat textWriter (source.get (), &sink);
1172 textWriter.Write ();
1173 flavorPackage.AddFlavorData (kLedPrivateClipFormat, sink.GetLength (), sink.PeekAtData ());
1177void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_RTF (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1179 Require (from <= to);
1180 Require (to <= GetTextStore ().GetEnd ());
1181 unique_ptr<StandardStyledTextIOSrcStream> source{mkStandardStyledTextIOSrcStream (from, to)};
1182 StyledTextIOWriterSinkStream_Memory sink;
1183 StyledTextIOWriter_RTF textWriter{source.get (), &sink};
1184 textWriter.Write ();
1185 flavorPackage.AddFlavorData (kRTFClipFormat, sink.GetLength (), sink.PeekAtData ());
1188void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_SingleSelectedEmbedding (
WriterFlavorPackage& flavorPackage,
1189 SimpleEmbeddedObjectStyleMarker* embedding)
1192 embedding->ExternalizeFlavors (flavorPackage);
1201StandardStyledTextIOSrcStream* StyledTextFlavorPackageExternalizer::mkStandardStyledTextIOSrcStream (
size_t selectionStart,
size_t selectionEnd)
1211using EmptySelStyleTextRep = StandardStyledTextInteractor::EmptySelStyleTextRep;
1213EmptySelStyleTextRep::EmptySelStyleTextRep (StandardStyledTextInteractor* interactor,
size_t selStart,
size_t selEnd)
1214 : inherited{selStart, selEnd}
1215 , fSavedStyle{interactor->fEmptySelectionStyle}
1219size_t EmptySelStyleTextRep::GetLength ()
const
1224void EmptySelStyleTextRep::InsertSelf (TextInteractor* interactor,
size_t at,
size_t nBytesToOverwrite)
1227 interactor->Replace (at, at + nBytesToOverwrite, LED_TCHAR_OF (
""), 0);
1229 StandardStyledTextInteractor* si =
dynamic_cast<StandardStyledTextInteractor*
> (interactor);
1232 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)
identical to builtin C++ 'throw' except that it does helpful, type dependent DbgTrace() messages firs...