IASS: Re-define Text suppression for TextEdit

The current version suppressed text for Objects
in edit mode for the paint in the view since that
text is painted/visualized by the EditEngine/Overlay
while it is being edited, so that would be displayed
twice - and in different states.
That is correct, but e.g. also suppressed display
for e.g. an opened second Window for the Document or
in a running SlideShow.
The mechanism uses embedding the Text in case it gets
edited to a simple Primitive that then can be
suppressed by the view rendering it. It decomposed
to empty, thus to visualize it a renderer had to
actively identify and process it.
I now turnedd this around - it is a normal
GroupPrimitive2D and decomposes to the text content,
so will be visualized by all renderers that do not
actively suppress it. To actively suppress it I added
a get/setTextEditActive marker to ViewInformation2D
that will be used by the ObjectContactOfPageView
to signal exactly that and to suppress in the pixel
based VCLRenderer in that case.
This is important e.g. for 2nd view window, but also
for PDF export with active TextEdit (yes, happens)
and SlideShow.
There was also support missing for an up-to-now
empty/new object (no text yet) so that text from the
active TextEdit was not provided, corrected that.

Change-Id: I0d8befdb023028d78ce341091331e9a83a0173bd
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163773
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
diff --git a/drawinglayer/source/geometry/viewinformation2d.cxx b/drawinglayer/source/geometry/viewinformation2d.cxx
index d238c9b..50c7c43 100644
--- a/drawinglayer/source/geometry/viewinformation2d.cxx
+++ b/drawinglayer/source/geometry/viewinformation2d.cxx
@@ -90,6 +90,12 @@ protected:
    // color to use for automatic color
    Color maAutoColor;

    // a hint that the View that is being painted has an active TextEdit. This
    // is important for handling of TextHierarchyEditPrimitive2D to suppress
    // the text for objects in TextEdit - the text is visualized by the
    // active EditEngine/Outliner overlay, so it would be double visualized
    bool mbTextEditActive;

    // allow to reduce DisplayQuality (e.g. sw 3d fallback renderer for interactions)
    bool mbReducedDisplayQuality : 1;

@@ -110,6 +116,7 @@ public:
        , mxVisualizedPage()
        , mfViewTime(0.0)
        , maAutoColor(COL_AUTO)
        , mbTextEditActive(false)
        , mbReducedDisplayQuality(false)
        , mbUseAntiAliasing(ViewInformation2D::getGlobalAntiAliasing())
        , mbPixelSnapHairline(mbUseAntiAliasing && bForwardPixelSnapHairline)
@@ -197,6 +204,9 @@ public:
    Color getAutoColor() const { return maAutoColor; }
    void setAutoColor(Color aNew) { maAutoColor = aNew; }

    bool getTextEditActive() const { return mbTextEditActive; }
    void setTextEditActive(bool bNew) { mbTextEditActive = bNew; }

    bool getReducedDisplayQuality() const { return mbReducedDisplayQuality; }
    void setReducedDisplayQuality(bool bNew) { mbReducedDisplayQuality = bNew; }

@@ -213,6 +223,7 @@ public:
                && maViewport == rCandidate.maViewport
                && mxVisualizedPage == rCandidate.mxVisualizedPage
                && mfViewTime == rCandidate.mfViewTime && maAutoColor == rCandidate.maAutoColor
                && mbTextEditActive == rCandidate.mbTextEditActive
                && mbReducedDisplayQuality == rCandidate.mbReducedDisplayQuality
                && mbUseAntiAliasing == rCandidate.mbUseAntiAliasing
                && mbPixelSnapHairline == rCandidate.mbPixelSnapHairline);
@@ -353,6 +364,16 @@ Color ViewInformation2D::getAutoColor() const { return mpViewInformation2D->getA

void ViewInformation2D::setAutoColor(Color aNew) { mpViewInformation2D->setAutoColor(aNew); }

bool ViewInformation2D::getTextEditActive() const
{
    return mpViewInformation2D->getTextEditActive();
}

void ViewInformation2D::setTextEditActive(bool bNew)
{
    mpViewInformation2D->setTextEditActive(bNew);
}

bool ViewInformation2D::getPixelSnapHairline() const
{
    return mpViewInformation2D->getPixelSnapHairline();
diff --git a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
index 93cb4e4..172e8c7 100644
--- a/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/texthierarchyprimitive2d.cxx
@@ -137,8 +137,7 @@ namespace drawinglayer::primitive2d


        TextHierarchyEditPrimitive2D::TextHierarchyEditPrimitive2D(Primitive2DContainer&& aContent)
        :   BasePrimitive2D()
        ,   maContent(std::move(aContent))
        :   GroupPrimitive2D(std::move(aContent))
        {
        }

diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index 570451c..4dc3397 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -890,20 +890,6 @@ void VclMetafileProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimi
                static_cast<const primitive2d::StructureTagPrimitive2D&>(rCandidate));
            break;
        }
        case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D:
        {
            // This primitive is created if a text edit is active and contains it's
            // current content, not from model data itself.
            // Pixel renderers need to suppress that content, it gets displayed by the active
            // TextEdit in the EditView. Suppression is done by decomposing to nothing.
            // MetaFile renderers have to show it, so that the edited text is part of the
            // MetaFile, e.g. needed for presentation previews and exports.
            // So take action here and process it's content:
            // Note: Former error was #i97628#
            process(static_cast<const primitive2d::TextHierarchyEditPrimitive2D&>(rCandidate)
                        .getContent());
            break;
        }
        case PRIMITIVE2D_ID_EPSPRIMITIVE2D:
        {
            RenderEpsPrimitive2D(static_cast<const primitive2d::EpsPrimitive2D&>(rCandidate));
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index ba6f37a..21939efa 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -339,6 +339,17 @@ void VclPixelProcessor2D::processBasePrimitive2D(const primitive2d::BasePrimitiv
            processInvertPrimitive2D(rCandidate);
            break;
        }
        case PRIMITIVE2D_ID_TEXTHIERARCHYEDITPRIMITIVE2D:
        {
            // check if TextEdit is active
            if (getViewInformation2D().getTextEditActive())
                // suppress text display
                break;

            // visualize text
            process(rCandidate);
            break;
        }
        case PRIMITIVE2D_ID_EPSPRIMITIVE2D:
        {
            RenderEpsPrimitive2D(static_cast<const primitive2d::EpsPrimitive2D&>(rCandidate));
diff --git a/include/drawinglayer/geometry/viewinformation2d.hxx b/include/drawinglayer/geometry/viewinformation2d.hxx
index 79b0701..db54aac 100644
--- a/include/drawinglayer/geometry/viewinformation2d.hxx
+++ b/include/drawinglayer/geometry/viewinformation2d.hxx
@@ -163,6 +163,9 @@ public:
    Color getAutoColor() const;
    void setAutoColor(Color aNew);

    bool getTextEditActive() const;
    void setTextEditActive(bool bNew);

    static void setGlobalAntiAliasing(bool bAntiAliasing, bool bTemporary);
    static bool getGlobalAntiAliasing();
    static void forwardPixelSnapHairline(bool bPixelSnapHairline);
diff --git a/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx b/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
index da388d9..dee2823 100644
--- a/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
+++ b/include/drawinglayer/primitive2d/texthierarchyprimitive2d.hxx
@@ -159,28 +159,19 @@ namespace drawinglayer::primitive2d
            separate from other text data since some renderers need to suppress
            this output due to painting the edited text in e.g. an
            OutlinerEditView in the active text edit control.
            Deriving now from BasePrimitive2D to turn around functionality:
            This will decompose to nothing -> suppress. In renderers that need to
            visualize it (only VclMetafileProcessor2D for now), it needs
            to be detected and used (see there).
            Doing it this way around since we will potentially have many
            pixel renderers and only one MetafileProcessor, so it will
            be one action less to support (and to potentially forget about )
            in these implementations.
            It is derived from GroupPrimitive2D so decomposes to the contained
            Text, thus it will get displayed everywhere except a renderer
            checks for this Primitive and suppresses it actively. Remember that
            this is also important e.g. for PDF export - if the object is in
            edit mode, we need to include the most current text from EditEngine/
            Outliner to that export
         */
        class DRAWINGLAYER_DLLPUBLIC TextHierarchyEditPrimitive2D final : public BasePrimitive2D
        class DRAWINGLAYER_DLLPUBLIC TextHierarchyEditPrimitive2D final : public GroupPrimitive2D
        {
        private:
            /// the content
            Primitive2DContainer                             maContent;

        public:
            /// constructor
            explicit TextHierarchyEditPrimitive2D(Primitive2DContainer&& aContent);

            /// data read access
            const Primitive2DContainer& getContent() const { return maContent; }

            /// provide unique ID
            virtual sal_uInt32 getPrimitive2DID() const override;
        };
diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx
index 79842eb..148b7b2 100644
--- a/svx/source/sdr/contact/objectcontactofpageview.cxx
+++ b/svx/source/sdr/contact/objectcontactofpageview.cxx
@@ -221,6 +221,8 @@ namespace sdr::contact
            aNewViewInformation2D.setViewTime(fCurrentTime);
            if (const SfxViewShell* pViewShell = SfxViewShell::Current())
                aNewViewInformation2D.setAutoColor(pViewShell->GetColorConfigColor(svtools::DOCCOLOR));
            if (static_cast<SdrPaintView&>(mrPageWindow.GetPageView().GetView()).IsTextEdit())
                aNewViewInformation2D.setTextEditActive(true);
            updateViewInformation2D(aNewViewInformation2D);

            drawinglayer::primitive2d::Primitive2DContainer xPrimitiveSequence;
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 81a854f..5e34d50 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -529,40 +529,39 @@ namespace drawinglayer::primitive2d
            // Save chaining attributes
            bool bChainable = rTextObj.IsChainable();

            // get OutlinerParaObject
            std::optional<OutlinerParaObject> aOutlinerParaObject;

            // 1st try to get from rText
            if(rText.GetOutlinerParaObject())
            {
                // added TextEdit text suppression
                bool bInEditMode(false);
                aOutlinerParaObject.emplace(*rText.GetOutlinerParaObject());
            }

                if(rText.GetObject().getTextCount() > 1)
                {
                    bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText;
                }
                else
                {
                    bInEditMode = rTextObj.IsInEditMode();
                }
            // added TextEdit text suppression - check if rText is in EditMode
            bool bInEditMode(false);

                OutlinerParaObject aOutlinerParaObject(*rText.GetOutlinerParaObject());
            if(rText.GetObject().getTextCount() > 1)
            {
                bInEditMode = rTextObj.IsInEditMode() && rText.GetObject().getActiveText() == &rText;
            }
            else
            {
                bInEditMode = rTextObj.IsInEditMode();
            }

                if(bInEditMode)
                {
                    std::optional<OutlinerParaObject> pTempObj = rTextObj.CreateEditOutlinerParaObject();
            if(bInEditMode)
            {
                // if yes, try to get OutlinerParaObject from active TextEdit
                std::optional<OutlinerParaObject> aTextEditOutlinerParaObject(rTextObj.CreateEditOutlinerParaObject());

                    if(pTempObj)
                    {
                        aOutlinerParaObject = *pTempObj;
                    }
                    else
                    {
                        // #i100537#
                        // CreateEditOutlinerParaObject() returning no object does not mean that
                        // text edit mode is not active. Do not reset the flag here
                        // bInEditMode = false;
                    }
                }
                if (aTextEditOutlinerParaObject)
                    // if we got one, prefer text from active TextEdit
                    aOutlinerParaObject = aTextEditOutlinerParaObject;
            }

            if(aOutlinerParaObject)
            {
                const SdrTextAniKind eAniKind(rTextObj.GetTextAniKind());

                // #i107346#
@@ -571,7 +570,7 @@ namespace drawinglayer::primitive2d

                return attribute::SdrTextAttribute(
                    rText,
                    aOutlinerParaObject,
                    *aOutlinerParaObject,
                    rSet.Get(XATTR_FORMTXTSTYLE).GetValue(),
                    pLeft ? *pLeft : rTextObj.GetTextLeftDistance(),
                    pUpper ? *pUpper : rTextObj.GetTextUpperDistance(),