diff options
author | Sarper Akdemir <sarper.akdemir@collabora.com> | 2023-02-21 02:34:33 +0300 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2023-02-28 11:30:53 +0000 |
commit | 0bb169dcfa14e6db44bc0eaeabe12d0d3b62ffd8 (patch) | |
tree | 1fc1e56839ee7f9fb9a7d2c9be43c450f3815c97 | |
parent | 11451781d4c562f506a3aae3732e35b92387b4db (diff) |
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 <vmiklos@collabora.com>
-rw-r--r-- | editeng/inc/outleeng.hxx (renamed from editeng/source/outliner/outleeng.hxx) | 5 | ||||
-rw-r--r-- | editeng/source/editeng/impedit3.cxx | 20 | ||||
-rw-r--r-- | editeng/source/outliner/outleeng.cxx | 12 | ||||
-rw-r--r-- | editeng/source/outliner/outlin2.cxx | 2 | ||||
-rw-r--r-- | editeng/source/outliner/outliner.cxx | 2 | ||||
-rw-r--r-- | editeng/source/outliner/outlvw.cxx | 2 | ||||
-rw-r--r-- | include/editeng/outliner.hxx | 4 | ||||
-rw-r--r-- | include/svx/compatflags.hxx | 1 | ||||
-rw-r--r-- | include/svx/svdoutl.hxx | 5 | ||||
-rw-r--r-- | sd/qa/unit/data/odp/tdf148966-withflag.odp | bin | 0 -> 19074 bytes | |||
-rw-r--r-- | sd/qa/unit/data/odp/tdf148966-withoutflag.odp | bin | 0 -> 9395 bytes | |||
-rw-r--r-- | sd/qa/unit/data/pptx/tdf148966.pptx | bin | 0 -> 35714 bytes | |||
-rw-r--r-- | sd/qa/unit/layout-tests.cxx | 26 | ||||
-rw-r--r-- | sd/source/ui/docshell/docshel4.cxx | 3 | ||||
-rw-r--r-- | solenv/clang-format/excludelist | 2 | ||||
-rw-r--r-- | svx/source/svdraw/svdmodel.cxx | 17 | ||||
-rw-r--r-- | svx/source/svdraw/svdoutl.cxx | 12 |
17 files changed, 108 insertions, 5 deletions
diff --git a/editeng/source/outliner/outleeng.hxx b/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 Binary files differnew file mode 100644 index 000000000000..7ba89b1c8eb2 --- /dev/null +++ b/sd/qa/unit/data/odp/tdf148966-withflag.odp diff --git a/sd/qa/unit/data/odp/tdf148966-withoutflag.odp b/sd/qa/unit/data/odp/tdf148966-withoutflag.odp Binary files differnew file mode 100644 index 000000000000..fdc2c2523b0c --- /dev/null +++ b/sd/qa/unit/data/odp/tdf148966-withoutflag.odp diff --git a/sd/qa/unit/data/pptx/tdf148966.pptx b/sd/qa/unit/data/pptx/tdf148966.pptx Binary files differnew file mode 100644 index 000000000000..d6c77f912596 --- /dev/null +++ b/sd/qa/unit/data/pptx/tdf148966.pptx 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 058e57e3bb47..aeee4709208a 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 d9592f96ca4b..a26ac1400c8d 100644 --- a/solenv/clang-format/excludelist +++ b/solenv/clang-format/excludelist @@ -3377,6 +3377,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 @@ -3455,7 +3456,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 886252234c21..47f2b517bf5e 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) {} }; @@ -1704,6 +1706,9 @@ void SdrModel::SetCompatibilityFlag(SdrCompatibilityFlag eFlag, bool bEnabled) case SdrCompatibilityFlag::ConnectorUseSnapRect: mpImpl->mbConnectorUseSnapRect = bEnabled; break; + case SdrCompatibilityFlag::IgnoreBreakAfterMultilineField: + mpImpl->mbIgnoreBreakAfterMultilineField = bEnabled; + break; } } @@ -1717,6 +1722,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; } @@ -1799,6 +1806,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> @@ -1816,6 +1831,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: */ |