4#include "Stroika/Frameworks/StroikaPreComp.h"
6#include "Stroika/Foundation/DataExchange/BadFormatException.h"
8#include "Stroika/Frameworks/Led/StyledTextEmbeddedObjects.h"
9#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_HTML.h"
10#include "Stroika/Frameworks/Led/StyledTextIO/StyledTextIO_RTF.h"
12#include "StandardStyledTextInteractor.h"
14#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
15#include "Stroika/Frameworks/Led/StyledTextIO/Led_StyledTextIO_LedNative.h"
21using namespace Stroika::Frameworks;
22using namespace Stroika::Frameworks::Led;
23using namespace Stroika::Frameworks::Led::StyledTextIO;
30StandardStyledTextIOSrcStream::StandardStyledTextIOSrcStream (TextStore* textStore,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
31 size_t selectionStart,
size_t selectionEnd)
32 : fTextStore (textStore)
33 , fStyleRunDatabase (textStyleDatabase)
34 , fCurOffset (selectionStart)
35 , fSelStart (selectionStart)
36 , fSelEnd (selectionEnd)
39 Require (textStyleDatabase.get () !=
nullptr);
40 Require (fSelStart >= 0);
41 Require (fSelEnd >= 0);
42 fSelEnd = min (fSelEnd, textStore->GetEnd ());
45#if qStroika_Frameworks_Led_SupportGDI
46StandardStyledTextIOSrcStream::StandardStyledTextIOSrcStream (StandardStyledTextImager* textImager,
size_t selectionStart,
size_t selectionEnd)
52size_t StandardStyledTextIOSrcStream::readNTChars (Led_tChar* intoBuf,
size_t maxTChars)
55 size_t bytesToRead = min (maxTChars, fSelEnd - fCurOffset);
56 Assert (bytesToRead <= maxTChars);
57 fTextStore->CopyOut (fCurOffset, bytesToRead, intoBuf);
58 fCurOffset += bytesToRead;
62size_t StandardStyledTextIOSrcStream::current_offset ()
const
64 return fCurOffset - fSelStart;
67void StandardStyledTextIOSrcStream::seek_to (
size_t to)
71 to = min (to, fSelEnd);
73 Ensure (fCurOffset >= fSelStart);
74 Ensure (fCurOffset <= fSelEnd);
77size_t StandardStyledTextIOSrcStream::GetTotalTextLength ()
const
79 Assert (fSelEnd >= fSelStart);
80 return (fSelEnd - fSelStart);
83vector<StyledInfoSummaryRecord> StandardStyledTextIOSrcStream::GetStyleInfo (
size_t from,
size_t len)
const
85 size_t effectiveFrom = from + fSelStart;
86#if qStroika_Foundation_Debug_AssertionsChecked
87 size_t effectiveTo = effectiveFrom + len;
89 Require (effectiveFrom >= fSelStart);
90 Require (effectiveFrom <= fSelEnd);
91#if qStroika_Foundation_Debug_AssertionsChecked
92 Require (effectiveTo >= fSelStart);
93 Require (effectiveTo <= fSelEnd);
95 return fStyleRunDatabase->GetStyleInfo (effectiveFrom, len);
98#if qStroika_Frameworks_Led_SupportGDI
99vector<SimpleEmbeddedObjectStyleMarker*> StandardStyledTextIOSrcStream::CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const
101 size_t effectiveFrom = from + fSelStart;
102 size_t effectiveTo = to + fSelStart;
103 Require (effectiveFrom >= fSelStart);
104 Require (effectiveFrom <= fSelEnd);
105 Require (effectiveTo >= fSelStart);
106 Require (effectiveTo <= fSelEnd);
108 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> result;
110 fTextStore->CollectAllMarkersInRangeInto (effectiveFrom, effectiveTo, TextStore::kAnyMarkerOwner, result);
111 return result.fResult;
115StandardStyledTextIOSrcStream::Table* StandardStyledTextIOSrcStream::GetTableAt (
size_t )
const
120void StandardStyledTextIOSrcStream::SummarizeFontAndColorTable (set<SDKString>* fontNames, set<Color>* colorsUsed)
const
122 if (fontNames !=
nullptr or colorsUsed !=
nullptr) {
123 size_t totalTextLength = GetTotalTextLength ();
124 vector<StyledInfoSummaryRecord> styleRuns;
125 if (totalTextLength != 0) {
126 styleRuns = GetStyleInfo (0, totalTextLength);
128 for (
auto i = styleRuns.begin (); i != styleRuns.end (); ++i) {
129 if (fontNames !=
nullptr) {
130 fontNames->insert ((*i).GetFontName ());
132 if (colorsUsed !=
nullptr) {
133 colorsUsed->insert ((*i).GetTextColor ());
139size_t StandardStyledTextIOSrcStream::GetEmbeddingMarkerPosOffset ()
const
149StandardStyledTextIOSinkStream::StandardStyledTextIOSinkStream (TextStore* textStore,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
150 size_t insertionStart)
151 : fTextStore{textStore}
152 , fStyleRunDatabase{textStyleDatabase}
153 , fOriginalStart{insertionStart}
154 , fInsertionStart{insertionStart}
157 Require (textStyleDatabase.get () !=
nullptr);
160StandardStyledTextIOSinkStream::~StandardStyledTextIOSinkStream ()
170size_t StandardStyledTextIOSinkStream::current_offset ()
const
172 return fInsertionStart - fOriginalStart;
175void StandardStyledTextIOSinkStream::AppendText (
const Led_tChar* text,
size_t nTChars,
const FontSpecification* fontSpec)
182 fCachedText.insert (fCachedText.end (), text, text + nTChars);
189 if (fontSpec ==
nullptr) {
190 if (fSavedStyleInfo.size () == 0) {
191 fSavedStyleInfo.push_back (StyledInfoSummaryRecord (fStyleRunDatabase->GetStyleInfo (fOriginalStart, 0)[0], nTChars));
194 fSavedStyleInfo.back ().fLength += nTChars;
198 fSavedStyleInfo.push_back (StyledInfoSummaryRecord (*fontSpec, nTChars));
201 fInsertionStart += nTChars;
204void StandardStyledTextIOSinkStream::ApplyStyle (
size_t from,
size_t to,
const vector<StyledInfoSummaryRecord>& styleRuns)
206 Require (from <= to);
207 if (GetCachedTextSize () != 0) {
210 fStyleRunDatabase->SetStyleInfo (fOriginalStart + from, to - from, styleRuns);
215 return GetStaticDefaultFont ();
218#if qStroika_Frameworks_Led_SupportGDI
219void StandardStyledTextIOSinkStream::InsertEmbeddingForExistingSentinel (SimpleEmbeddedObjectStyleMarker* embedding,
size_t at)
222 if (GetCachedTextSize () != 0) {
225 size_t effectiveFrom = fOriginalStart + at;
226 Led_tChar testSentinel;
228 fTextStore->CopyOut (effectiveFrom, 1, &testSentinel);
229 if (testSentinel != kEmbeddingSentinelChar) {
232 Stroika::Frameworks::Led::InsertEmbeddingForExistingSentinel (embedding, *fTextStore, effectiveFrom, fStyleRunDatabase.get ());
235void StandardStyledTextIOSinkStream::AppendEmbedding (SimpleEmbeddedObjectStyleMarker* embedding)
239 if (GetCachedTextSize () != 0) {
242 AddEmbedding (embedding, *fTextStore, fInsertionStart, fStyleRunDatabase.get ());
247void StandardStyledTextIOSinkStream::AppendSoftLineBreak ()
250 AppendText (LED_TCHAR_OF (
"\n"), 1,
nullptr);
253void StandardStyledTextIOSinkStream::InsertMarker (Marker* m,
size_t at,
size_t length,
MarkerOwner* markerOwner)
255 Require (at <= current_offset ());
259 if (GetCachedTextSize () != 0) {
263 TextStore::SimpleUpdater u (*fTextStore, fOriginalStart + at, fOriginalStart + at + length);
264 fTextStore->AddMarker (m, fOriginalStart + at, length, markerOwner);
268void StandardStyledTextIOSinkStream::Flush ()
270 if (GetCachedTextSize () != 0) {
272 size_t dataSize = fCachedText.size ();
273 size_t whereToInsert = fInsertionStart - dataSize;
274 fTextStore->Replace (whereToInsert, whereToInsert, Traversal::Iterator2Pointer (fCachedText.begin ()), dataSize);
275 fCachedText.clear ();
278 fStyleRunDatabase->SetStyleInfo (whereToInsert, dataSize, fSavedStyleInfo.size (), Traversal::Iterator2Pointer (fSavedStyleInfo.begin ()));
279 fSavedStyleInfo.clear ();
281 Ensure (fSavedStyleInfo.size () == 0);
284void StandardStyledTextIOSinkStream::PushContext (TextStore* ts,
const shared_ptr<AbstractStyleDatabaseRep>& textStyleDatabase,
size_t insertionStart)
286 Require (GetCachedTextSize () == 0);
289 c.fTextStore = fTextStore;
290 c.fStyleRunDatabase = fStyleRunDatabase;
291 c.fInsertionStart = fInsertionStart;
292 c.fOriginalStart = fOriginalStart;
293 fSavedContexts.push_back (c);
295 fStyleRunDatabase = textStyleDatabase;
296 fInsertionStart = insertionStart;
297 fOriginalStart = insertionStart;
300void StandardStyledTextIOSinkStream::PopContext ()
302 Require (GetCachedTextSize () == 0);
303 Require (not fSavedContexts.empty ());
304 fTextStore = fSavedContexts.back ().fTextStore;
305 fStyleRunDatabase = fSavedContexts.back ().fStyleRunDatabase;
306 fInsertionStart = fSavedContexts.back ().fInsertionStart;
307 fOriginalStart = fSavedContexts.back ().fOriginalStart;
308 fSavedContexts.pop_back ();
311#if qStroika_Frameworks_Led_SupportGDI
313#if qStroika_Foundation_Common_Platform_MacOS
314const Led_ClipFormat Led::kLedPrivateClipFormat =
'LedP';
315const Led_ClipFormat Led::kRTFClipFormat =
'RTF ';
316const Led_ClipFormat Led::kHTMLClipFormat =
'HTML';
317#elif qStroika_Foundation_Common_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));
324#elif qStroika_FeatureSupported_XWindows
327Led_ClipFormat kLedPrivateClipFormat = 0;
328Led_ClipFormat kRTFClipFormat = 0;
329Led_ClipFormat kHTMLClipFormat = 0;
337StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::sCommandNames = StandardStyledTextInteractor::MakeDefaultCommandNames ();
339StandardStyledTextInteractor::StandardStyledTextInteractor ()
340 : fEmptySelectionStyleSuppressMode (false)
341 , fEmptySelectionStyle (GetStaticDefaultFont ())
345StandardStyledTextInteractor::CommandNames StandardStyledTextInteractor::MakeDefaultCommandNames ()
347 StandardStyledTextInteractor::CommandNames cmdNames;
348 cmdNames.fFontChangeCommandName = Led_SDK_TCHAROF (
"Font Change");
352void StandardStyledTextInteractor::HookLosingTextStore ()
354 TextInteractor::HookLosingTextStore ();
355 StandardStyledTextImager::HookLosingTextStore ();
356 HookLosingTextStore_ ();
359void StandardStyledTextInteractor::HookLosingTextStore_ ()
362 vector<SimpleEmbeddedObjectStyleMarker*> embeddings = CollectAllEmbeddingMarkersInRange (0, GetLength ());
363 for (
size_t i = 0; i < embeddings.size (); ++i) {
364 SimpleEmbeddedObjectStyleMarker* e = embeddings[i];
366 DISABLE_COMPILER_MSC_WARNING_START (28182)
367 if (e->GetOwner () == this) {
368 PeekAtTextStore ()->RemoveMarker (e);
371 DISABLE_COMPILER_MSC_WARNING_END (28182)
375void StandardStyledTextInteractor::HookGainedNewTextStore ()
377 TextInteractor::HookGainedNewTextStore ();
378 StandardStyledTextImager::HookGainedNewTextStore ();
379 HookGainedNewTextStore_ ();
382void StandardStyledTextInteractor::HookGainedNewTextStore_ ()
393void StandardStyledTextInteractor::SetDefaultFont (
const IncrementalFontSpecification& defaultFont)
395 size_t selStart = GetSelectionStart ();
396 size_t selEnd = GetSelectionEnd ();
397 if (selStart == selEnd) {
398 size_t selLength = selEnd - selStart;
400 newEmptySelectionStyle.MergeIn (defaultFont);
401 SetStyleInfo (selStart, selLength, defaultFont);
402 SetEmptySelectionStyle (newEmptySelectionStyle);
405 StandardStyledTextImager::SetDefaultFont (defaultFont);
422void StandardStyledTextInteractor::InteractiveSetFont (
const IncrementalFontSpecification& defaultFont)
424 InteractiveModeUpdater iuMode (*
this);
427 BreakInGroupedCommands ();
429 UndoableContextHelper undoContext (*
this, GetCommandNames ().fFontChangeCommandName,
false);
438 size_t selLength = undoContext.GetUndoRegionEnd () - undoContext.GetUndoRegionStart ();
440 newEmptySelectionStyle.MergeIn (defaultFont);
441 SetStyleInfo (undoContext.GetUndoRegionStart (), selLength, defaultFont);
442 SetEmptySelectionStyle (newEmptySelectionStyle);
445 undoContext.CommandComplete ();
448IncrementalFontSpecification StandardStyledTextInteractor::GetContinuousStyleInfo (
size_t from,
size_t nTChars)
const
450 if (nTChars == 0 and from == GetSelectionStart ()) {
451 vector<StyledInfoSummaryRecord> summaryInfo;
452 summaryInfo.push_back (StyledInfoSummaryRecord (fEmptySelectionStyle, 0));
453 return (GetContinuousStyleInfo_ (summaryInfo));
456 return StandardStyledTextImager::GetContinuousStyleInfo (from, nTChars);
460void StandardStyledTextInteractor::DidUpdateText (
const UpdateInfo& updateInfo)
noexcept
462 TextInteractor::DidUpdateText (updateInfo);
463 StandardStyledTextImager::DidUpdateText (updateInfo);
472bool StandardStyledTextInteractor::ShouldEnablePasteCommand ()
const
474 if (TextInteractor::ShouldEnablePasteCommand ()) {
477 if (Led_ClipboardObjectAcquire::FormatAvailable (kLedPrivateClipFormat)) {
480 if (Led_ClipboardObjectAcquire::FormatAvailable (kRTFClipFormat)) {
484 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
485 for (
size_t i = 0; i < types.size (); ++i) {
486 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
487 bool clipAvailForAll =
true;
488 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
489 if (not Led_ClipboardObjectAcquire::FormatAvailable (assoc.GetIthFormat (j))) {
490 clipAvailForAll =
false;
494 if (clipAvailForAll) {
501bool StandardStyledTextInteractor::CanAcceptFlavor (Led_ClipFormat clipFormat)
const
503 if (TextInteractor::CanAcceptFlavor (clipFormat)) {
506 if (clipFormat == kLedPrivateClipFormat) {
509 if (clipFormat == kRTFClipFormat) {
513 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
514 for (
size_t i = 0; i < types.size (); ++i) {
515 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
520 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
521 if (assoc.GetIthFormat (j) == clipFormat) {
529void StandardStyledTextInteractor::HookStyleDatabaseChanged ()
531 StandardStyledTextImager::HookStyleDatabaseChanged ();
532 if (PeekAtTextStore () !=
nullptr) {
534 SetExternalizer (MakeDefaultExternalizer ());
535 SetInternalizer (MakeDefaultInternalizer ());
539shared_ptr<FlavorPackageInternalizer> StandardStyledTextInteractor::MakeDefaultInternalizer ()
541 return make_shared<StyledTextFlavorPackageInternalizer> (GetTextStore (), GetStyleDatabase ());
544shared_ptr<FlavorPackageExternalizer> StandardStyledTextInteractor::MakeDefaultExternalizer ()
546 return make_shared<StyledTextFlavorPackageExternalizer> (GetTextStore (), GetStyleDatabase ());
554bool StandardStyledTextInteractor::ProcessSimpleClick (Led_Point clickedAt,
unsigned clickCount,
bool extendSelection,
size_t* dragAnchor)
557 size_t clickedOnChar = GetCharAtWindowLocation (clickedAt);
558 Led_Rect charRect = GetCharWindowLocation (clickedOnChar);
566 Led_Rect tstClickRect = charRect;
567 const DistanceType kHMargin = 3;
568 tstClickRect.left += kHMargin;
569 tstClickRect.right -= kHMargin;
571 if (tstClickRect.Contains (clickedAt)) {
572 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
573 Assert (embeddingList.size () == 0 or embeddingList.size () == 1);
575 if (embeddingList.size () == 1) {
576 SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
577 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
578 switch (clickCount) {
580 if (not extendSelection) {
581 SetSelection (clickedOnChar, clickedOnChar + 1);
583 if (clickCount == 1) {
586 *dragAnchor = clickedOnChar;
588 return embedding->HandleClick (clickedAt, 1);
594 if (not extendSelection) {
595 SetSelection (clickedOnChar, clickedOnChar + 1);
597 if (clickCount == 1) {
600 *dragAnchor = clickedOnChar;
602 return embedding->HandleClick (clickedAt, 2);
612 return TextInteractor::ProcessSimpleClick (clickedAt, clickCount, extendSelection, dragAnchor);
615void StandardStyledTextInteractor::WhileSimpleMouseTracking (Led_Point newMousePos,
size_t dragAnchor)
617 size_t clickedOnChar = GetCharAtWindowLocation (newMousePos);
618 size_t oldSelStart = GetSelectionStart ();
619 size_t oldSelEnd = GetSelectionEnd ();
626 if ((clickedOnChar == dragAnchor or clickedOnChar + 1 == dragAnchor) and (oldSelEnd - oldSelStart == 1)) {
627 vector<SimpleEmbeddedObjectStyleMarker*> embeddingList = CollectAllEmbeddingMarkersInRange (clickedOnChar, clickedOnChar + 1);
628 if (embeddingList.size () == 1) {
629 [[maybe_unused]] SimpleEmbeddedObjectStyleMarker* embedding = embeddingList[0];
630 AssertMember (embedding, SimpleEmbeddedObjectStyleMarker);
634 TextInteractor::WhileSimpleMouseTracking (newMousePos, dragAnchor);
637void StandardStyledTextInteractor::InteractiveReplace (
const Led_tChar* withWhat,
size_t withWhatCharCount, UpdateMode updateMode)
639 UpdateMode useUpdateMode = updateMode == eImmediateUpdate ? eDelayedUpdate : updateMode;
640 Assert (not fEmptySelectionStyleSuppressMode);
641 fEmptySelectionStyleSuppressMode =
true;
643 TextInteractor::InteractiveReplace (withWhat, withWhatCharCount, useUpdateMode);
644 fEmptySelectionStyleSuppressMode =
false;
647 fEmptySelectionStyleSuppressMode =
false;
650 if (updateMode == eImmediateUpdate) {
655void StandardStyledTextInteractor::SetSelection (
size_t start,
size_t end)
657 bool changed = (GetSelectionStart () != start) or (GetSelectionEnd () != end);
658 TextInteractor::SetSelection (start, end);
660 StandardStyledTextInteractor::SetSelection_ (start, end);
664void StandardStyledTextInteractor::SetSelection_ ([[maybe_unused]]
size_t start, [[maybe_unused]]
size_t end)
668 Require (start == GetSelectionStart ());
669 Require (end == GetSelectionEnd ());
670 if (not fEmptySelectionStyleSuppressMode) {
671 SetEmptySelectionStyle ();
684 return fEmptySelectionStyle;
693void StandardStyledTextInteractor::SetEmptySelectionStyle ()
697 GetSelection (&start, &end);
698 if (fLeftSideOfSelectionInteresting) {
699 if (start < GetTextStore ().GetEnd ()) {
700 fEmptySelectionStyle = GetStyleInfo (start);
704 fEmptySelectionStyle = GetStyleInfo (FindPreviousCharacter (end));
706 if (end == GetEnd ()) {
707 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
720void StandardStyledTextInteractor::SetEmptySelectionStyle (
FontSpecification newEmptyFontSpec)
722 if (fEmptySelectionStyle != newEmptyFontSpec) {
732 GetSelection (&selStart, &selEnd);
733 if (selStart == selEnd) {
736 TextStore::SimpleUpdater updater (GetTextStore (), selStart, selEnd,
false);
737 fEmptySelectionStyle = newEmptyFontSpec;
739 if (selEnd == GetEnd ()) {
740 SetStyleInfo (GetEnd (), 1, fEmptySelectionStyle);
746bool StandardStyledTextInteractor::InteractiveReplaceEarlyPostReplaceHook (
size_t withWhatCharCount)
748 Assert (GetSelectionStart () >= withWhatCharCount);
749 if (withWhatCharCount == 1) {
752 size_t charAt = FindPreviousCharacter (GetSelectionStart ());
754 if (prevStyle != fEmptySelectionStyle) {
755 SetStyleInfo (charAt, withWhatCharCount, IncrementalFontSpecification (fEmptySelectionStyle));
762vector<SimpleEmbeddedObjectStyleMarker*> StandardStyledTextInteractor::CollectAllEmbeddingMarkersInRange (
size_t from,
size_t to)
const
771 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> result;
772 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, result);
773 return result.fResult;
776InteractiveReplaceCommand::SavedTextRep* StandardStyledTextInteractor::InteractiveUndoHelperMakeTextRep (
size_t regionStart,
size_t regionEnd,
777 size_t selStart,
size_t selEnd)
779 if (regionStart == regionEnd) {
781 return new EmptySelStyleTextRep{
this, selStart, selEnd};
784 return TextInteractor::InteractiveUndoHelperMakeTextRep (regionStart, regionEnd, selStart, selEnd);
793using StyledTextFlavorPackageInternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageInternalizer;
794StyledTextFlavorPackageInternalizer::StyledTextFlavorPackageInternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
796 , fStyleDatabase (styleDatabase)
800void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromName (filesystem::path fileName, Led_ClipFormat* suggestedClipFormat,
801 optional<CodePage> suggestedCodePage)
803 inherited::InternalizeFlavor_FILEGuessFormatsFromName (fileName, suggestedClipFormat, suggestedCodePage);
805#if qStroika_Foundation_Common_Platform_MacOS
808#elif qStroika_Foundation_Common_Platform_Windows
809 if (suggestedClipFormat !=
nullptr and *suggestedClipFormat == kBadClipFormat) {
810 TCHAR drive[_MAX_DRIVE];
812 TCHAR fname[_MAX_FNAME];
814 ::_tsplitpath_s (fileName.native ().c_str (), drive, dir, fname, ext);
815 if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".rtf")) == 0) {
816 *suggestedClipFormat = kRTFClipFormat;
818 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".htm")) == 0) {
819 *suggestedClipFormat = kHTMLClipFormat;
821 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".html")) == 0) {
822 *suggestedClipFormat = kHTMLClipFormat;
824 else if (::_tcsicmp (ext, Led_SDK_TCHAROF (
".led")) == 0) {
825 *suggestedClipFormat = kLedPrivateClipFormat;
831void StyledTextFlavorPackageInternalizer::InternalizeFlavor_FILEGuessFormatsFromStartOfData (Led_ClipFormat* suggestedClipFormat,
832 optional<CodePage> suggestedCodePage,
833 const byte* fileStart,
const byte* fileEnd)
835 inherited::InternalizeFlavor_FILEGuessFormatsFromStartOfData (suggestedClipFormat, suggestedCodePage, fileStart, fileEnd);
836 if (suggestedClipFormat !=
nullptr) {
837 if (*suggestedClipFormat == kBadClipFormat) {
839 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
840 StyledTextIOReader_RTF reader (&source,
nullptr);
841 if (reader.QuickLookAppearsToBeRightFormat ()) {
842 *suggestedClipFormat = kRTFClipFormat;
848 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
849 StyledTextIOReader_HTML reader (&source,
nullptr);
850 if (reader.QuickLookAppearsToBeRightFormat ()) {
851 *suggestedClipFormat = kHTMLClipFormat;
856#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
858 StyledTextIOSrcStream_Memory source (fileStart, fileEnd - fileStart);
859 StyledTextIOReader_LedNativeFileFormat reader (&source,
nullptr);
860 if (reader.QuickLookAppearsToBeRightFormat ()) {
861 *suggestedClipFormat = kLedPrivateClipFormat;
870bool StyledTextFlavorPackageInternalizer::InternalizeBestFlavor (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
872 Require (from <= GetTextStore ().GetEnd ());
873 Require (to <= GetTextStore ().GetEnd ());
874 Require (from <= to);
876 if (InternalizeFlavor_RTF (flavorPackage, from, to)) {
879 else if (InternalizeFlavor_HTML (flavorPackage, from, to)) {
882#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
883 else if (InternalizeFlavor_Native (flavorPackage, from, to)) {
887#if qStroika_Foundation_Common_Platform_Windows
894 else if (flavorPackage.GetFlavorAvailable (CF_DIB) and InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
898 else if (InternalizeFlavor_FILE (flavorPackage, from, to)) {
901 else if (InternalizeFlavor_OtherRegisteredEmbedding (flavorPackage, from, to)) {
904#if qStroika_Foundation_Common_Platform_MacOS
905 else if (InternalizeFlavor_STYLAndTEXT (flavorPackage, from, to)) {
909 else if (InternalizeFlavor_TEXT (flavorPackage, from, to)) {
915#if qStroika_Foundation_Common_Platform_MacOS
916bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_STYLAndTEXT (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
918 size_t pasteStart = from;
919 size_t pasteEnd = to;
920 Assert (pasteEnd >= pasteStart);
922 TempMarker newSel (GetTextStore (), pasteStart + 1, pasteStart + 1);
923 if (inherited::InternalizeFlavor_TEXT (flavorPackage, pasteStart, pasteEnd)) {
924 if (flavorPackage.GetFlavorAvailable (
'styl')) {
927 length = flavorPackage.ReadFlavorData (
'styl', length, buf);
928 Assert (newSel.GetStart () >= pasteStart + 1);
929 size_t pasteEndXXX = newSel.GetStart () - 1;
930 Assert (pasteEndXXX >= pasteStart);
931 StScrpRec* styleRecords =
reinterpret_cast<StScrpRec*
> (
static_cast<char*
> (buf));
932 vector<StyledInfoSummaryRecord> ledStyleInfo = StandardStyledTextImager::Convert (styleRecords->scrpStyleTab, styleRecords->scrpNStyles);
933 fStyleDatabase->SetStyleInfo (pasteStart, pasteEndXXX - pasteStart, ledStyleInfo);
944#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
945bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_Native (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
947 if (flavorPackage.GetFlavorAvailable (kLedPrivateClipFormat)) {
948 size_t length = flavorPackage.
GetFlavorSize (kLedPrivateClipFormat);
950 length = flavorPackage.ReadFlavorData (kLedPrivateClipFormat, length, buf);
954 Assert (end >= start);
956 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
959 StyledTextIOSrcStream_Memory source (buf, length);
960 unique_ptr<StandardStyledTextIOSinkStream> sink (mkStandardStyledTextIOSinkStream (start));
961 StyledTextIOReader_LedNativeFileFormat textReader (&source, sink.get ());
973bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_RTF (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
975 if (flavorPackage.GetFlavorAvailable (kRTFClipFormat)) {
976 size_t length = flavorPackage.
GetFlavorSize (kRTFClipFormat);
983 length = flavorPackage.ReadFlavorData (kRTFClipFormat, length, buf.data ());
987 Assert (end >= start);
989 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
992 StyledTextIOSrcStream_Memory source{buf.data (), length};
993 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
994 StyledTextIOReader_RTF textReader{&source, sink.get ()};
1005bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_HTML (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
1007 if (flavorPackage.GetFlavorAvailable (kHTMLClipFormat)) {
1008 size_t length = flavorPackage.
GetFlavorSize (kHTMLClipFormat);
1010 length = flavorPackage.ReadFlavorData (kHTMLClipFormat, length, buf.data ());
1012 size_t start = from;
1014 Assert (end >= start);
1016 GetTextStore ().Replace (start, end, LED_TCHAR_OF (
""), 0);
1019 StyledTextIOSrcStream_Memory source{buf.data (), length};
1020 unique_ptr<StandardStyledTextIOSinkStream> sink{mkStandardStyledTextIOSinkStream (start)};
1021 StyledTextIOReader_HTML textReader{&source, sink.get ()};
1032bool StyledTextFlavorPackageInternalizer::InternalizeFlavor_OtherRegisteredEmbedding (
ReaderFlavorPackage& flavorPackage,
size_t from,
size_t to)
1034 const vector<EmbeddedObjectCreatorRegistry::Assoc>& types = EmbeddedObjectCreatorRegistry::Get ().GetAssocList ();
1035 for (
size_t i = 0; i < types.size (); ++i) {
1036 EmbeddedObjectCreatorRegistry::Assoc assoc = types[i];
1037 bool clipAvailForAll = (assoc.fFormatTagCount != 0);
1038 for (
size_t j = 0; j < assoc.fFormatTagCount; ++j) {
1039 if (not flavorPackage.GetFlavorAvailable (assoc.GetIthFormat (j))) {
1040 clipAvailForAll =
false;
1044 if (clipAvailForAll) {
1045 SimpleEmbeddedObjectStyleMarker* objMarker = (assoc.fReadFromFlavorPackage) (flavorPackage);
1047 size_t pasteStart = from;
1048 size_t pasteEnd = to;
1049 Assert (pasteEnd >= pasteStart);
1051 GetTextStore ().Replace (pasteStart, pasteEnd, &kEmbeddingSentinelChar, 1);
1055 TextStore::SimpleUpdater updater (GetTextStore (), pasteStart, pasteStart + 1);
1056 GetTextStore ().AddMarker (objMarker, pasteStart, 1, fStyleDatabase.get ());
1082using StyledTextFlavorPackageExternalizer = StandardStyledTextInteractor::StyledTextFlavorPackageExternalizer;
1083StyledTextFlavorPackageExternalizer::StyledTextFlavorPackageExternalizer (TextStore& ts,
const shared_ptr<AbstractStyleDatabaseRep>& styleDatabase)
1085 , fStyleDatabase (styleDatabase)
1089void StyledTextFlavorPackageExternalizer::ExternalizeFlavors (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1091 size_t start = from;
1093 Require (start >= 0);
1094 Require (end <= GetTextStore ().GetEnd ());
1095 Require (start <= end);
1103 MarkersOfATypeMarkerSink2Vector<SimpleEmbeddedObjectStyleMarker> embeddings;
1104 GetTextStore ().CollectAllMarkersInRangeInto (from, to, TextStore::kAnyMarkerOwner, embeddings);
1105 if ((embeddings.fResult.size () == 1) and (start + 1 == end)) {
1110 ExternalizeFlavor_SingleSelectedEmbedding (flavorPackage, embeddings.fResult[0]);
1124 ExternalizeFlavor_RTF (flavorPackage, start, end);
1126 ExternalizeFlavor_TEXT (flavorPackage, start, end);
1128#if qStroika_Foundation_Common_Platform_MacOS
1129 ExternalizeFlavor_STYL (flavorPackage, start, end);
1133void StyledTextFlavorPackageExternalizer::ExternalizeBestFlavor (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1135 ExternalizeFlavor_RTF (flavorPackage, from, to);
1138#if qStroika_Foundation_Common_Platform_MacOS
1139void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_STYL (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1141 Require (from <= to);
1142 Require (to <= GetTextStore ().GetEnd ());
1143 size_t length = to - from;
1145 vector<StyledInfoSummaryRecord> ledStyleRuns = fStyleDatabase->GetStyleInfo (from, length);
1146 size_t nStyleRuns = ledStyleRuns.size ();
1148 Assert (offsetof (StScrpRec, scrpStyleTab) ==
sizeof (
short));
1150 size_t nBytes =
sizeof (short) + nStyleRuns *
sizeof (ScrpSTElement);
1152 StScrpPtr stylePtr = (StScrpPtr)(
char*)buf;
1154 stylePtr->scrpNStyles = nStyleRuns;
1155 StandardStyledTextImager::Convert (ledStyleRuns, stylePtr->scrpStyleTab);
1156 flavorPackage.AddFlavorData (
'styl', nBytes, stylePtr);
1160#if qIncludeLedNativeFileFormatSupportInStandardStyledTextInteractor
1161void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_Native (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1163 Require (from <= to);
1164 Require (to <= GetTextStore ().GetEnd ());
1165 unique_ptr<StandardStyledTextIOSrcStream> source (mkStandardStyledTextIOSrcStream (from, to));
1166 StyledTextIOWriterSinkStream_Memory sink;
1167 StyledTextIOWriter_LedNativeFileFormat textWriter (source.get (), &sink);
1168 textWriter.Write ();
1169 flavorPackage.AddFlavorData (kLedPrivateClipFormat, sink.GetLength (), sink.PeekAtData ());
1173void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_RTF (
WriterFlavorPackage& flavorPackage,
size_t from,
size_t to)
1175 Require (from <= to);
1176 Require (to <= GetTextStore ().GetEnd ());
1177 unique_ptr<StandardStyledTextIOSrcStream> source{mkStandardStyledTextIOSrcStream (from, to)};
1178 StyledTextIOWriterSinkStream_Memory sink;
1179 StyledTextIOWriter_RTF textWriter{source.get (), &sink};
1180 textWriter.Write ();
1181 flavorPackage.AddFlavorData (kRTFClipFormat, sink.GetLength (), sink.PeekAtData ());
1184void StyledTextFlavorPackageExternalizer::ExternalizeFlavor_SingleSelectedEmbedding (
WriterFlavorPackage& flavorPackage,
1185 SimpleEmbeddedObjectStyleMarker* embedding)
1188 embedding->ExternalizeFlavors (flavorPackage);
1197StandardStyledTextIOSrcStream* StyledTextFlavorPackageExternalizer::mkStandardStyledTextIOSrcStream (
size_t selectionStart,
size_t selectionEnd)
1207using EmptySelStyleTextRep = StandardStyledTextInteractor::EmptySelStyleTextRep;
1209EmptySelStyleTextRep::EmptySelStyleTextRep (StandardStyledTextInteractor* interactor,
size_t selStart,
size_t selEnd)
1210 : inherited{selStart, selEnd}
1211 , fSavedStyle{interactor->fEmptySelectionStyle}
1215size_t EmptySelStyleTextRep::GetLength ()
const
1220void EmptySelStyleTextRep::InsertSelf (TextInteractor* interactor,
size_t at,
size_t nBytesToOverwrite)
1223 interactor->Replace (at, at + nBytesToOverwrite, LED_TCHAR_OF (
""), 0);
1225 StandardStyledTextInteractor* si =
dynamic_cast<StandardStyledTextInteractor*
> (interactor);
1228 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...