From 413791a65597a1808d9b98e4887864f3624b70cc Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Tue, 2 Jun 2020 09:07:48 +0200 Subject: [PATCH] tdf#133271 sw textbox: handle TextRotateAngle shape property Shape with btlr text direction is imported as TextPreRotateAngle=-270 from DOCX. Saving this to ODT turns the property name into TextRotateAngle and its type into double. Handle that as well to survive the ODF roundtrip of a shape+textbox where the textbox has a btlr text direction. (Also add a way to make multiple tests in a suite to be more independent from each other: depending on ordering, the new test made the old test fail. Calling ErrorRegistry::Reset() makes that go away.) Change-Id: Iea9212f3bbb01059caf3b0f2d809e48debf52953 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/95340 Reviewed-by: Miklos Vajna Tested-by: Jenkins --- include/vcl/errinf.hxx | 1 + sw/CppunitTest_sw_core_doc.mk | 1 + .../core/doc/data/textbox-textrotateangle.odt | Bin 0 -> 9496 bytes sw/qa/core/doc/doc.cxx | 22 ++++++++++++++++++ sw/source/core/doc/textboxhelper.cxx | 14 +++++++++-- vcl/source/window/errinf.cxx | 6 +++++ 6 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 sw/qa/core/doc/data/textbox-textrotateangle.odt diff --git a/include/vcl/errinf.hxx b/include/vcl/errinf.hxx index 6d57954aff2b..4a0edc75b259 100644 --- a/include/vcl/errinf.hxx +++ b/include/vcl/errinf.hxx @@ -59,6 +59,7 @@ public: static void RegisterDisplay(BasicDisplayErrorFunc*); static void RegisterDisplay(WindowDisplayErrorFunc*); + static void Reset(); private: DisplayFnPtr pDsp; diff --git a/sw/CppunitTest_sw_core_doc.mk b/sw/CppunitTest_sw_core_doc.mk index 487e02322ef4..856f007cb9b1 100644 --- a/sw/CppunitTest_sw_core_doc.mk +++ b/sw/CppunitTest_sw_core_doc.mk @@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_core_doc, \ comphelper \ cppu \ cppuhelper \ + editeng \ sal \ sfx \ sw \ diff --git a/sw/qa/core/doc/data/textbox-textrotateangle.odt b/sw/qa/core/doc/data/textbox-textrotateangle.odt new file mode 100644 index 0000000000000000000000000000000000000000..2ce4c3e0b7ec95b9cbadde18e49ac5862e2dbc5b GIT binary patch literal 9496 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 #include #include +#include +#include #include #include @@ -58,6 +60,26 @@ CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testMathInsertAnchorType) // - Actual : 4 // i.e. the anchor type was at-char, not as-char. CPPUNIT_ASSERT_EQUAL(RndStdIds::FLY_AS_CHAR, rAnchor.GetAnchorId()); + ErrorRegistry::Reset(); +} + +CPPUNIT_TEST_FIXTURE(SwCoreDocTest, testTextboxTextRotateAngle) +{ + // Check the writing direction of the only TextFrame in the document. + SwDoc* pDoc = createDoc("textbox-textrotateangle.odt"); + SwFrameFormats& rFrameFormats = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT_EQUAL(static_cast(2), rFrameFormats.size()); + CPPUNIT_ASSERT_EQUAL(static_cast(RES_DRAWFRMFMT), rFrameFormats[0]->Which()); + CPPUNIT_ASSERT_EQUAL(static_cast(RES_FLYFRMFMT), rFrameFormats[1]->Which()); + SvxFrameDirection eActual = rFrameFormats[1]->GetAttrSet().GetItem(RES_FRAMEDIR)->GetValue(); + + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 5 (btlr) + // - Actual : 0 (lrtb) + // i.e. the writing direction was in the ODT file, but it was lost on import in the textbox + // case. + CPPUNIT_ASSERT_EQUAL(SvxFrameDirection::Vertical_LR_BT, eActual); + ErrorRegistry::Reset(); } CPPUNIT_PLUGIN_IMPLEMENT(); diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx index 4f2550f06b52..1dcc7e242016 100644 --- a/sw/source/core/doc/textboxhelper.cxx +++ b/sw/source/core/doc/textboxhelper.cxx @@ -361,11 +361,21 @@ void SwTextBoxHelper::syncProperty(SwFrameFormat* pShape, const OUString& rPrope comphelper::SequenceAsHashMap aCustomShapeGeometry(rValue); auto it = aCustomShapeGeometry.find("TextPreRotateAngle"); + if (it == aCustomShapeGeometry.end()) + { + it = aCustomShapeGeometry.find("TextRotateAngle"); + } + if (it != aCustomShapeGeometry.end()) { - auto nTextPreRotateAngle = it->second.get(); + auto nAngle = it->second.has() ? it->second.get() : 0; + if (nAngle == 0) + { + nAngle = it->second.has() ? it->second.get() : 0; + } + sal_Int16 nDirection = 0; - switch (nTextPreRotateAngle) + switch (nAngle) { case -90: nDirection = text::WritingMode2::TB_RL; diff --git a/vcl/source/window/errinf.cxx b/vcl/source/window/errinf.cxx index 5307d60df716..8e08dc361acd 100644 --- a/vcl/source/window/errinf.cxx +++ b/vcl/source/window/errinf.cxx @@ -74,6 +74,12 @@ void ErrorRegistry::RegisterDisplay(WindowDisplayErrorFunc *aDsp) rData.pDsp = reinterpret_cast< DisplayFnPtr >(aDsp); } +void ErrorRegistry::Reset() +{ + ErrorRegistry &rData = TheErrorRegistry::get(); + rData = ErrorRegistry(); +} + static void aDspFunc(const OUString &rErr, const OUString &rAction) { SAL_WARN("vcl", "Action: " << rAction << " Error: " << rErr);