editeng/inc/outleeng.hxx                      |    5 +++++
 editeng/source/editeng/impedit3.cxx           |   20 ++++++++++++++++++++
 editeng/source/outliner/outleeng.cxx          |   12 +++++++++++-
 editeng/source/outliner/outlin2.cxx           |    2 +-
 editeng/source/outliner/outliner.cxx          |    2 +-
 editeng/source/outliner/outlvw.cxx            |    2 +-
 include/editeng/outliner.hxx                  |    4 ++++
 include/svx/compatflags.hxx                   |    1 +
 include/svx/svdoutl.hxx                       |    5 +++++
 sd/qa/unit/data/odp/tdf148966-withflag.odp    |binary
 sd/qa/unit/data/odp/tdf148966-withoutflag.odp |binary
 sd/qa/unit/data/pptx/tdf148966.pptx           |binary
 sd/qa/unit/layout-tests.cxx                   |   26 ++++++++++++++++++++++++++
 sd/source/ui/docshell/docshel4.cxx            |    3 +++
 solenv/clang-format/excludelist               |    2 +-
 svx/source/svdraw/svdmodel.cxx                |   17 +++++++++++++++++
 svx/source/svdraw/svdoutl.cxx                 |   12 ++++++++++++
 17 files changed, 108 insertions(+), 5 deletions(-)

New commits:
commit 3130211151c8a3596f1834a5297692a96458b368
Author:     Sarper Akdemir <sarper.akde...@collabora.com>
AuthorDate: Tue Feb 21 02:34:33 2023 +0300
Commit:     Andras Timar <andras.ti...@collabora.com>
CommitDate: Sun Mar 12 21:43:48 2023 +0000

    tdf#148966: pptx: workaround for multiline fields followed by linebreaks
    
    In Impress after fields that span multiple lines, a
    linebreak is already forced. (PowerPoint doesn't have such
    behaviour)
    
    Therefore if the imported pptx file has a line break after
    the multiline field - Impress ends up displaying an extra
    line break.
    
    This patch implements ignoring of a linebreak that follows
    after a multiline field during paint (when not in EditMode),
    using a compatibility flag. (IgnoreBreakAfterMultilineField)
    
    Change-Id: I1e6772424cc0eead06b53d104b06820038a81ea1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147408
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148334
    Reviewed-by: Andras Timar <andras.ti...@collabora.com>
    Tested-by: Andras Timar <andras.ti...@collabora.com>

diff --git a/editeng/source/outliner/outleeng.hxx b/editeng/inc/outleeng.hxx
similarity index 96%
rename from editeng/source/outliner/outleeng.hxx
rename to editeng/inc/outleeng.hxx
index d19b54eba06a..449b5ca44ce8 100644
--- a/editeng/source/outliner/outleeng.hxx
+++ b/editeng/inc/outleeng.hxx
@@ -21,6 +21,8 @@
 #include <editeng/outliner.hxx>
 #include <editeng/editeng.hxx>
 
+enum class SdrCompatibilityFlag;
+
 typedef std::vector<EENotify> NotifyList;
 
 class OutlinerEditEng : public EditEngine
@@ -75,6 +77,9 @@ public:
 
     virtual tools::Rectangle   GetBulletArea( sal_Int32 nPara ) override;
 
+    /// @returns state of the SdrCompatibilityFlag
+    std::optional<bool> GetCompatFlag(SdrCompatibilityFlag eFlag) const;
+
        virtual void        SetParaAttribs( sal_Int32 nPara, const SfxItemSet& 
rSet ) override;
 
     // belongs into class Outliner, move there before incompatible update!
diff --git a/editeng/source/editeng/impedit3.cxx 
b/editeng/source/editeng/impedit3.cxx
index 3191b7a874e7..376d1df7ad13 100644
--- a/editeng/source/editeng/impedit3.cxx
+++ b/editeng/source/editeng/impedit3.cxx
@@ -24,6 +24,7 @@
 #include <vcl/settings.hxx>
 #include <vcl/window.hxx>
 
+#include <editeng/outliner.hxx>
 #include <editeng/tstpitem.hxx>
 #include <editeng/lspcitem.hxx>
 #include <editeng/flditem.hxx>
@@ -44,11 +45,14 @@
 #include <editeng/scriptspaceitem.hxx>
 #include <editeng/charscaleitem.hxx>
 #include <editeng/numitem.hxx>
+#include <outleeng.hxx>
 
 #include <svtools/colorcfg.hxx>
 #include <svl/ctloptions.hxx>
 #include <svl/asiancfg.hxx>
 
+#include <svx/compatflags.hxx>
+
 #include <editeng/hngpnctitem.hxx>
 #include <editeng/forbiddencharacterstable.hxx>
 
@@ -3606,6 +3610,22 @@ void ImpEditEngine::Paint( OutputDevice& rOutDev, 
tools::Rectangle aClipRect, Po
                                             nTextStart = *curIt;
                                             nTextLen = nTextLen - nTextStart;
                                             bParsingFields = false;
+
+                                            if (nLine + 1 < nLines)
+                                            {
+                                                // tdf#148966 don't paint the 
line break following a
+                                                // multiline field based on a 
compat flag
+                                                OutlinerEditEng* pOutlEditEng{ 
dynamic_cast<OutlinerEditEng*>(pEditEngine) };
+                                                if (pOutlEditEng
+                                                    && 
pOutlEditEng->GetCompatFlag(SdrCompatibilityFlag::IgnoreBreakAfterMultilineField)
+                                                           .value_or(false))
+                                                {
+                                                    int nStartNextLine = 
pPortion->GetLines()[nLine + 1].GetStartPortion();
+                                                    const TextPortion& 
rNextTextPortion = pPortion->GetTextPortions()[nStartNextLine];
+                                                    if 
(rNextTextPortion.GetKind() == PortionKind::LINEBREAK)
+                                                        ++nLine; //ignore the 
following linebreak
+                                                }
+                                            }
                                         }
                                     }
 
diff --git a/editeng/source/outliner/outleeng.cxx 
b/editeng/source/outliner/outleeng.cxx
index 275636b6581e..0a7f8aef28de 100644
--- a/editeng/source/outliner/outleeng.cxx
+++ b/editeng/source/outliner/outleeng.cxx
@@ -21,9 +21,10 @@
 #include <editeng/eerdll.hxx>
 
 #include <editeng/outliner.hxx>
-#include "outleeng.hxx"
+#include <outleeng.hxx>
 #include "paralist.hxx"
 #include <editeng/editrids.hrc>
+#include <optional>
 #include <svl/itemset.hxx>
 #include <editeng/editstat.hxx>
 #include "outlundo.hxx"
@@ -69,6 +70,15 @@ tools::Rectangle OutlinerEditEng::GetBulletArea( sal_Int32 
nPara )
     return aBulletArea;
 }
 
+std::optional<bool> OutlinerEditEng::GetCompatFlag(SdrCompatibilityFlag eFlag) 
const
+{
+    if(pOwner)
+    {
+        return pOwner->GetCompatFlag(eFlag);
+    }
+    return {};
+}
+
 void OutlinerEditEng::ParagraphInserted( sal_Int32 nNewParagraph )
 {
     pOwner->ParagraphInserted( nNewParagraph );
diff --git a/editeng/source/outliner/outlin2.cxx 
b/editeng/source/outliner/outlin2.cxx
index 68b1d0fb802e..013c680df152 100644
--- a/editeng/source/outliner/outlin2.cxx
+++ b/editeng/source/outliner/outlin2.cxx
@@ -30,7 +30,7 @@
 
 #include <editeng/outliner.hxx>
 #include "paralist.hxx"
-#include "outleeng.hxx"
+#include <outleeng.hxx>
 #include <editeng/editstat.hxx>
 
 
diff --git a/editeng/source/outliner/outliner.cxx 
b/editeng/source/outliner/outliner.cxx
index 84097ae2a14b..fa0e7958ce79 100644
--- a/editeng/source/outliner/outliner.cxx
+++ b/editeng/source/outliner/outliner.cxx
@@ -30,7 +30,7 @@
 #include <editeng/outliner.hxx>
 #include "paralist.hxx"
 #include <editeng/outlobj.hxx>
-#include "outleeng.hxx"
+#include <outleeng.hxx>
 #include "outlundo.hxx"
 #include <editeng/eeitem.hxx>
 #include <editeng/editstat.hxx>
diff --git a/editeng/source/outliner/outlvw.cxx 
b/editeng/source/outliner/outlvw.cxx
index d5f426abbf53..705b5e10b06b 100644
--- a/editeng/source/outliner/outlvw.cxx
+++ b/editeng/source/outliner/outlvw.cxx
@@ -30,7 +30,7 @@
 #include <i18nlangtag/languagetag.hxx>
 
 #include <editeng/outliner.hxx>
-#include "outleeng.hxx"
+#include <outleeng.hxx>
 #include "paralist.hxx"
 #include "outlundo.hxx"
 #include <editeng/outlobj.hxx>
diff --git a/include/editeng/outliner.hxx b/include/editeng/outliner.hxx
index aa2cad367c26..bee57d13bca8 100644
--- a/include/editeng/outliner.hxx
+++ b/include/editeng/outliner.hxx
@@ -77,6 +77,7 @@ class SvxFieldData;
 enum class PointerStyle;
 class SvxNumRule;
 enum class TextRotation;
+enum class SdrCompatibilityFlag;
 
 namespace com::sun::star::linguistic2 {
     class XSpellChecker1;
@@ -987,6 +988,9 @@ public:
 
     // convenient method to determine the bullets/numbering status for all 
paragraphs
     sal_Int32 GetBulletsNumberingStatus() const;
+
+    // overriden in SdrOutliner
+    virtual std::optional<bool> GetCompatFlag(SdrCompatibilityFlag /*eFlag*/) 
const { return {}; };
 };
 
 #endif
diff --git a/include/svx/compatflags.hxx b/include/svx/compatflags.hxx
index 6a53c756ebd8..f7d021f17bf7 100644
--- a/include/svx/compatflags.hxx
+++ b/include/svx/compatflags.hxx
@@ -13,6 +13,7 @@ enum class SdrCompatibilityFlag
     AnchoredTextOverflowLegacy, ///< for tdf#99729
     LegacySingleLineFontwork, ///< for tdf#148000
     ConnectorUseSnapRect, ///< for tdf#149756
+    IgnoreBreakAfterMultilineField, ///< for tdf#148966
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s 
cinkeys+=0=break: */
diff --git a/include/svx/svdoutl.hxx b/include/svx/svdoutl.hxx
index b9768b72c45a..2a78fd6b2e47 100644
--- a/include/svx/svdoutl.hxx
+++ b/include/svx/svdoutl.hxx
@@ -20,11 +20,13 @@
 #pragma once
 
 #include <editeng/outliner.hxx>
+#include <optional>
 #include <svx/svxdllapi.h>
 #include <unotools/weakref.hxx>
 
 class SdrTextObj;
 class SdrPage;
+enum class SdrCompatibilityFlag;
 
 class SVXCORE_DLLPUBLIC SdrOutliner : public Outliner
 {
@@ -45,6 +47,9 @@ public:
     virtual OUString CalcFieldValue(const SvxFieldItem& rField, sal_Int32 
nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& 
rpFldColor) override;
 
     bool hasEditViewCallbacks() const;
+
+    /// @returns state of the SdrCompatibilityFlag
+    virtual std::optional<bool> GetCompatFlag(SdrCompatibilityFlag eFlag) 
const override;
 };
 
 
diff --git a/sd/qa/unit/data/odp/tdf148966-withflag.odp 
b/sd/qa/unit/data/odp/tdf148966-withflag.odp
new file mode 100644
index 000000000000..7ba89b1c8eb2
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf148966-withflag.odp differ
diff --git a/sd/qa/unit/data/odp/tdf148966-withoutflag.odp 
b/sd/qa/unit/data/odp/tdf148966-withoutflag.odp
new file mode 100644
index 000000000000..fdc2c2523b0c
Binary files /dev/null and b/sd/qa/unit/data/odp/tdf148966-withoutflag.odp 
differ
diff --git a/sd/qa/unit/data/pptx/tdf148966.pptx 
b/sd/qa/unit/data/pptx/tdf148966.pptx
new file mode 100644
index 000000000000..d6c77f912596
Binary files /dev/null and b/sd/qa/unit/data/pptx/tdf148966.pptx differ
diff --git a/sd/qa/unit/layout-tests.cxx b/sd/qa/unit/layout-tests.cxx
index 36293f2dcfe2..e401f2d0822b 100644
--- a/sd/qa/unit/layout-tests.cxx
+++ b/sd/qa/unit/layout-tests.cxx
@@ -314,6 +314,32 @@ CPPUNIT_TEST_FIXTURE(SdLayoutTest, 
testFitToFrameTextFitting)
 #endif
 }
 
+CPPUNIT_TEST_FIXTURE(SdLayoutTest, testTdf148966)
+{
+    // Test related to IgnoreBreakAfterMultilineField compatibility flag.
+    {
+        xmlDocUniquePtr pXmlDoc = load("pptx/tdf148966.pptx");
+        // Without the accompanying fix, would fail with:
+        // - Expected: 5952
+        // - Actual  : 7814
+        // i.e. Line break after multiline field should have been ignored.
+        assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", 
"5952");
+    }
+    {
+        xmlDocUniquePtr pXmlDoc = load("odp/tdf148966-withflag.odp");
+        // Without the accompanying fix, would fail with:
+        // - Expected: 5952
+        // - Actual  : 7814
+        // i.e. When IgnoreBreakAfterMultilineField flag is set, line break
+        // after multiline field should have been ignored.
+        assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", 
"5952");
+    }
+    {
+        xmlDocUniquePtr pXmlDoc = load("odp/tdf148966-withoutflag.odp");
+        assertXPath(pXmlDoc, "/metafile/push[1]/push[1]/textarray[3]", "y", 
"7814");
+    }
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/docshell/docshel4.cxx 
b/sd/source/ui/docshell/docshel4.cxx
index 2c1b87f9979c..dea4c4595681 100644
--- a/sd/source/ui/docshell/docshel4.cxx
+++ b/sd/source/ui/docshell/docshel4.cxx
@@ -409,6 +409,9 @@ bool DrawDocShell::ImportFrom(SfxMedium &rMedium,
         // The Libreoffice uses bounding rectangle of connected shapes but
         // MSO uses snap rectangle when calculate the edge track.
         
mpDoc->SetCompatibilityFlag(SdrCompatibilityFlag::ConnectorUseSnapRect, true);
+
+        // compatibility flag for tdf#148966
+        
mpDoc->SetCompatibilityFlag(SdrCompatibilityFlag::IgnoreBreakAfterMultilineField,
 true);
     }
 
     if (aFilterName == "Impress MS PowerPoint 2007 XML" ||
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index db1e6f7e4a7f..5e770abc8a1f 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -3397,6 +3397,7 @@ editeng/inc/editattr.hxx
 editeng/inc/editdoc.hxx
 editeng/inc/edtspell.hxx
 editeng/inc/eerdll2.hxx
+editeng/inc/outleeng.hxx
 editeng/inc/unomodel.hxx
 editeng/qa/items/borderline_test.cxx
 editeng/qa/lookuptree/lookuptree_test.cxx
@@ -3475,7 +3476,6 @@ editeng/source/misc/swafopt.cxx
 editeng/source/misc/txtrange.cxx
 editeng/source/misc/unolingu.cxx
 editeng/source/outliner/outleeng.cxx
-editeng/source/outliner/outleeng.hxx
 editeng/source/outliner/outlin2.cxx
 editeng/source/outliner/outliner.cxx
 editeng/source/outliner/outlobj.cxx
diff --git a/svx/source/svdraw/svdmodel.cxx b/svx/source/svdraw/svdmodel.cxx
index 7b72fad64c66..3a8fcf1a141a 100644
--- a/svx/source/svdraw/svdmodel.cxx
+++ b/svx/source/svdraw/svdmodel.cxx
@@ -86,6 +86,7 @@ struct SdrModelImpl
     bool mbAnchoredTextOverflowLegacy; // tdf#99729 compatibility flag
     bool mbLegacySingleLineFontwork;   // tdf#148000 compatibility flag
     bool mbConnectorUseSnapRect;       // tdf#149756 compatibility flag
+    bool mbIgnoreBreakAfterMultilineField; ///< tdf#148966 compatibility flag
     std::unique_ptr<model::Theme> mpTheme;
 
     SdrModelImpl()
@@ -94,6 +95,7 @@ struct SdrModelImpl
         , mbAnchoredTextOverflowLegacy(false)
         , mbLegacySingleLineFontwork(false)
         , mbConnectorUseSnapRect(false)
+        , mbIgnoreBreakAfterMultilineField(false)
     {}
 };
 
@@ -1729,6 +1731,9 @@ void SdrModel::SetCompatibilityFlag(SdrCompatibilityFlag 
eFlag, bool bEnabled)
         case SdrCompatibilityFlag::ConnectorUseSnapRect:
             mpImpl->mbConnectorUseSnapRect = bEnabled;
             break;
+        case SdrCompatibilityFlag::IgnoreBreakAfterMultilineField:
+            mpImpl->mbIgnoreBreakAfterMultilineField = bEnabled;
+            break;
     }
 }
 
@@ -1742,6 +1747,8 @@ bool SdrModel::GetCompatibilityFlag(SdrCompatibilityFlag 
eFlag) const
             return mpImpl->mbLegacySingleLineFontwork;
         case SdrCompatibilityFlag::ConnectorUseSnapRect:
             return mpImpl->mbConnectorUseSnapRect;
+        case SdrCompatibilityFlag::IgnoreBreakAfterMultilineField:
+            return mpImpl->mbIgnoreBreakAfterMultilineField;
         default:
             return false;
     }
@@ -1824,6 +1831,14 @@ void SdrModel::ReadUserDataSequenceValue(const 
beans::PropertyValue* pValue)
             }
         }
     }
+    else if (pValue->Name == "IgnoreBreakAfterMultilineField")
+    {
+        bool bBool = false;
+        if (pValue->Value >>= bBool)
+        {
+            mpImpl->mbIgnoreBreakAfterMultilineField = bBool;
+        }
+    }
 }
 
 template <typename T>
@@ -1841,6 +1856,8 @@ void SdrModel::WriteUserDataSequence(uno::Sequence 
<beans::PropertyValue>& rValu
             
GetCompatibilityFlag(SdrCompatibilityFlag::LegacySingleLineFontwork));
     addPair(aUserData, "ConnectorUseSnapRect",
             GetCompatibilityFlag(SdrCompatibilityFlag::ConnectorUseSnapRect));
+    addPair(aUserData, "IgnoreBreakAfterMultilineField",
+            
GetCompatibilityFlag(SdrCompatibilityFlag::IgnoreBreakAfterMultilineField));
 
     const sal_Int32 nOldLength = rValues.getLength();
     rValues.realloc(nOldLength + aUserData.size());
diff --git a/svx/source/svdraw/svdoutl.cxx b/svx/source/svdraw/svdoutl.cxx
index 1888fbbd3236..5e89f5d42874 100644
--- a/svx/source/svdraw/svdoutl.cxx
+++ b/svx/source/svdraw/svdoutl.cxx
@@ -17,9 +17,12 @@
  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
  */
 
+#include <optional>
 #include <svx/svdoutl.hxx>
 #include <editeng/outliner.hxx>
+#include <svx/svdmodel.hxx>
 #include <svx/svdotext.hxx>
+#include <svx/svdpage.hxx>
 #include <editeng/editstat.hxx>
 #include <svl/itempool.hxx>
 #include <editeng/editview.hxx>
@@ -104,4 +107,13 @@ bool SdrOutliner::hasEditViewCallbacks() const
     return false;
 }
 
+std::optional<bool> SdrOutliner::GetCompatFlag(SdrCompatibilityFlag eFlag) 
const
+{
+    if( mpVisualizedPage )
+    {
+        return 
{mpVisualizedPage->getSdrModelFromSdrPage().GetCompatibilityFlag(eFlag)};
+    }
+    return {};
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Reply via email to