oox/inc/oox/vml/vmltextbox.hxx | 12 +- oox/inc/oox/vml/vmltextboxcontext.hxx | 5 oox/source/vml/vmlshape.cxx | 9 + oox/source/vml/vmltextbox.cxx | 55 ++++++++++ oox/source/vml/vmltextboxcontext.cxx | 61 ++++++++++-- sw/qa/extras/inc/swmodeltestbase.hxx | 9 + sw/qa/extras/ooxmlimport/data/groupshape-sdt.docx |binary sw/qa/extras/ooxmlimport/data/vml-text-vertical-adjust.docx |binary sw/qa/extras/ooxmlimport/ooxmlimport.cxx | 30 +++++ 9 files changed, 168 insertions(+), 13 deletions(-)
New commits: commit 975875c97b8617c883d3f02e48def960f2419695 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Sep 6 15:57:03 2013 +0200 bnc#779642 VML import: handle drawinglayer rectangle char spacing Change-Id: I79fa72c9235682030d23a03fdb0c7c40370c4a8a (cherry picked from commit 4cbc41bc4eaa822829e68c1ee11eafe834bb7da7) diff --git a/oox/inc/oox/vml/vmltextbox.hxx b/oox/inc/oox/vml/vmltextbox.hxx index 4ffec0b..eea12d2 100644 --- a/oox/inc/oox/vml/vmltextbox.hxx +++ b/oox/inc/oox/vml/vmltextbox.hxx @@ -54,6 +54,7 @@ struct OOX_DLLPUBLIC TextFontModel OptValue< bool > mobBold; OptValue< bool > mobItalic; OptValue< bool > mobStrikeout; + OptValue<sal_Int32> monSpacing; explicit TextFontModel(); }; diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index 1fbed35..7878505 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -20,6 +20,7 @@ #include "oox/vml/vmltextbox.hxx" #include <rtl/ustrbuf.hxx> +#include <svx/unopage.hxx> #include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/drawing/TextHorizontalAdjust.hpp> @@ -90,6 +91,15 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const aPropertyValue.Value = uno::makeAny(double(rFont.monSize.get()) / 2.); aPropVec.push_back(aPropertyValue); } + if (rFont.monSpacing.has()) + { + aPropertyValue.Name = "CharKerning"; + // Value is not converted to mm100: SvxKerningItem::PutValue() gets + // called with nMemberId = 0, so no mm100 -> twips conversion will + // be done there. + aPropertyValue.Value = uno::makeAny(sal_Int16(rFont.monSpacing.get())); + aPropVec.push_back(aPropertyValue); + } if (rParagraph.moParaAdjust.has()) { style::ParagraphAdjust eAdjust = style::ParagraphAdjust_LEFT; diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index e176db4..c37d904 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -133,6 +133,16 @@ void TextPortionContext::onStartElement(const AttributeList& rAttribs) case OOX_TOKEN(doc, color): maFont.moColor = rAttribs.getString( OOX_TOKEN(doc, val) ); break; + case OOX_TOKEN(doc, spacing): + maFont.monSpacing = rAttribs.getInteger(OOX_TOKEN(doc, val)); + break; + case OOX_TOKEN(doc, r): + case OOX_TOKEN(doc, rPr): + case OOX_TOKEN(doc, t): + break; + default: + SAL_INFO("oox", "unhandled: 0x" << std::hex<< getCurrentElement()); + break; } } diff --git a/sw/qa/extras/ooxmlimport/data/groupshape-sdt.docx b/sw/qa/extras/ooxmlimport/data/groupshape-sdt.docx new file mode 100755 index 0000000..0729847 Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/groupshape-sdt.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 9a0e08f..648baba 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -137,6 +137,7 @@ public: void testTablePagebreak(); void testFdo68607(); void testVmlTextVerticalAdjust(); + void testGroupshapeSdt(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -222,6 +223,7 @@ void Test::run() {"table-pagebreak.docx", &Test::testTablePagebreak}, {"fdo68607.docx", &Test::testFdo68607}, {"vml-text-vertical-adjust.docx", &Test::testVmlTextVerticalAdjust}, + {"groupshape-sdt.docx", &Test::testGroupshapeSdt}, }; for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) { @@ -1382,6 +1384,20 @@ void Test::testVmlTextVerticalAdjust() CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, getProperty<drawing::TextVerticalAdjust>(xShape, "TextVerticalAdjust")); } +void Test::testGroupshapeSdt() +{ + // All problems here are due to the groupshape: we have a drawinglayer rectangle, not a writer textframe. + uno::Reference<drawing::XShapes> xOuterGroupShape(getShape(1), uno::UNO_QUERY); + uno::Reference<drawing::XShapes> xInnerGroupShape(xOuterGroupShape->getByIndex(0), uno::UNO_QUERY); + uno::Reference<text::XTextRange> xShape(xInnerGroupShape->getByIndex(0), uno::UNO_QUERY); + // Border distances were not implemented, this was 0. + CPPUNIT_ASSERT_EQUAL(sal_Int32(1905), getProperty<sal_Int32>(xShape, "TextUpperDistance")); + // Sdt field result wasn't imported, this was "". + CPPUNIT_ASSERT_EQUAL(OUString("placeholder text"), xShape->getString()); + // w:spacing was ignored in oox, this was 0. + CPPUNIT_ASSERT_EQUAL(sal_Int32(20), getProperty<sal_Int32>(getRun(getParagraphOfText(1, xShape->getText()), 1), "CharKerning")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); commit 38e209eee11fe921e3c3c172518b17eae2faea66 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Sep 6 12:29:46 2013 +0200 bnc#779642 VML import: handle drawinglayer rectangle inset Change-Id: If8b064ca9a52bb02ff41f07e00142702a29df818 (cherry picked from commit 870a2394a87c77740daf41e1aa81b130113f8e00) diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx index 44910b5..bcdf65c 100644 --- a/oox/source/vml/vmlshape.cxx +++ b/oox/source/vml/vmlshape.cxx @@ -529,7 +529,16 @@ Reference< XShape > SimpleShape::implConvertAndInsert( const Reference< XShapes } if (getTextBox()) + { getTextBox()->convert(xShape); + if (getTextBox()->borderDistanceSet) + { + PropertySet(xShape).setAnyProperty(PROP_TextLeftDistance, makeAny(sal_Int32(getTextBox()->borderDistanceLeft))); + PropertySet(xShape).setAnyProperty(PROP_TextUpperDistance, makeAny(sal_Int32(getTextBox()->borderDistanceTop))); + PropertySet(xShape).setAnyProperty(PROP_TextRightDistance, makeAny(sal_Int32(getTextBox()->borderDistanceRight))); + PropertySet(xShape).setAnyProperty(PROP_TextLowerDistance, makeAny(sal_Int32(getTextBox()->borderDistanceBottom))); + } + } } // Import Legacy Fragments (if any) commit 33439c566e4c9cc2637c49ac729b86a57410fa48 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Fri Sep 6 12:09:45 2013 +0200 bnc#779642 VML import: import result of sdt fields We can't have e.g. placeholder fields on drawinglayer rectangles, but at least the result of the field is now imported. Change-Id: I135f205c4231645f11f824495993c4dbea4135ed (cherry picked from commit 3847de4b724f4f435bb68bceef9a5e187c3f363c) diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index c28e97d..e176db4 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -218,14 +218,19 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att if (nElement == OOX_TOKEN(doc, p)) return this; break; case OOX_TOKEN(doc, p): + case OOX_TOKEN(doc, sdtContent): if (nElement == OOX_TOKEN(doc, r)) return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs ); else return this; break; case OOX_TOKEN(doc, pPr): + case OOX_TOKEN(doc, sdt): return this; break; + default: + SAL_INFO("oox", "unhandled 0x" << std::hex << getCurrentElement()); + break; } return 0; } commit 0e757616f5188a4675933e44b983deecc0b44898 Author: Miklos Vajna <vmik...@suse.cz> Date: Mon Jul 1 13:59:47 2013 +0200 bnc#779642 fdo#46361 oox: handle w:color for groupshape textboxes Change-Id: Ifcbf622a04a4b3f06d95c079d5e13ec3f505268f (cherry picked from commit ef53d4aec2a3d690de2c7cdaf73ca95bbe29a433) diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index 5089742..1fbed35 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -102,6 +102,12 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const aPropertyValue.Value = uno::makeAny(eAdjust); aPropVec.push_back(aPropertyValue); } + if (rFont.moColor.has()) + { + aPropertyValue.Name = "CharColor"; + aPropertyValue.Value = uno::makeAny(sal_uInt32(rFont.moColor.get().toInt32(16))); + aPropVec.push_back(aPropertyValue); + } uno::Sequence<beans::PropertyValue> aPropSeq(aPropVec.size()); beans::PropertyValue* pValues = aPropSeq.getArray(); for (std::vector<beans::PropertyValue>::iterator i = aPropVec.begin(); i != aPropVec.end(); ++i) diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index b76dd23..c28e97d 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -130,6 +130,9 @@ void TextPortionContext::onStartElement(const AttributeList& rAttribs) case OOX_TOKEN(doc, br): mrTextBox.appendPortion( maParagraph, maFont, "\n" ); break; + case OOX_TOKEN(doc, color): + maFont.moColor = rAttribs.getString( OOX_TOKEN(doc, val) ); + break; } } commit d59160fe78175fbae3546984a36a57533bf8fc7b Author: Miklos Vajna <vmik...@suse.cz> Date: Mon Jul 1 16:47:56 2013 +0200 bnc#779642 fdo#46361 oox: handle w:jc for groupshape textboxes Change-Id: I21391d9a9f5b5173b599006287b33fdaab3c0c75 (cherry picked from commit 5a737fca37cd5a5f90aa03a30688d447677d3b8a) Conflicts: oox/inc/oox/vml/vmltextbox.hxx diff --git a/oox/inc/oox/vml/vmltextbox.hxx b/oox/inc/oox/vml/vmltextbox.hxx index f234b00..4ffec0b 100644 --- a/oox/inc/oox/vml/vmltextbox.hxx +++ b/oox/inc/oox/vml/vmltextbox.hxx @@ -37,6 +37,12 @@ struct ShapeTypeModel; // ============================================================================ +/// A text paragraph in a textbox. +struct TextParagraphModel +{ + OptValue<OUString> moParaAdjust; ///< Paragraph adjust (left, center, right, etc.) +}; + /** Font settings for a text portion in a textbox. */ struct OOX_DLLPUBLIC TextFontModel { @@ -57,10 +63,11 @@ struct OOX_DLLPUBLIC TextFontModel /** A text portion in a textbox with the same formatting for all characters. */ struct TextPortionModel { + TextParagraphModel maParagraph; TextFontModel maFont; ::rtl::OUString maText; - explicit TextPortionModel( const TextFontModel& rFont, const ::rtl::OUString& rText ); + explicit TextPortionModel( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const ::rtl::OUString& rText ); }; // ============================================================================ @@ -72,7 +79,7 @@ public: explicit TextBox(ShapeTypeModel& rTypeModel); /** Appends a new text portion to the textbox. */ - void appendPortion( const TextFontModel& rFont, const ::rtl::OUString& rText ); + void appendPortion( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const ::rtl::OUString& rText ); /** Returns the current number of text portions. */ inline size_t getPortionCount() const { return maPortions.size(); } diff --git a/oox/inc/oox/vml/vmltextboxcontext.hxx b/oox/inc/oox/vml/vmltextboxcontext.hxx index b324060..ebd4fce 100644 --- a/oox/inc/oox/vml/vmltextboxcontext.hxx +++ b/oox/inc/oox/vml/vmltextboxcontext.hxx @@ -34,6 +34,7 @@ public: explicit TextPortionContext( ::oox::core::ContextHandler2Helper& rParent, TextBox& rTextBox, + TextParagraphModel& rParagraph, const TextFontModel& rParentFont, sal_Int32 nElement, const AttributeList& rAttribs ); @@ -46,6 +47,7 @@ public: private: TextBox& mrTextBox; + TextParagraphModel maParagraph; TextFontModel maFont; size_t mnInitialPortions; }; @@ -63,10 +65,12 @@ public: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); + virtual void onStartElement(const AttributeList& rAttribs); virtual void onEndElement(); private: TextBox& mrTextBox; + TextParagraphModel maParagraph; }; // ============================================================================ diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index 490a897..5089742 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/drawing/TextHorizontalAdjust.hpp> #include <com/sun/star/text/XTextAppend.hpp> #include <com/sun/star/text/WritingMode.hpp> +#include <com/sun/star/style/ParagraphAdjust.hpp> namespace oox { namespace vml { @@ -37,7 +38,8 @@ TextFontModel::TextFontModel() { } -TextPortionModel::TextPortionModel( const TextFontModel& rFont, const OUString& rText ) : +TextPortionModel::TextPortionModel( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const OUString& rText ) : + maParagraph( rParagraph ), maFont( rFont ), maText( rText ) { @@ -49,9 +51,9 @@ TextBox::TextBox(ShapeTypeModel& rTypeModel) { } -void TextBox::appendPortion( const TextFontModel& rFont, const OUString& rText ) +void TextBox::appendPortion( const TextParagraphModel& rParagraph, const TextFontModel& rFont, const OUString& rText ) { - maPortions.push_back( TextPortionModel( rFont, rText ) ); + maPortions.push_back( TextPortionModel( rParagraph, rFont, rText ) ); } const TextFontModel* TextBox::getFirstFont() const @@ -74,6 +76,7 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const { beans::PropertyValue aPropertyValue; std::vector<beans::PropertyValue> aPropVec; + const TextParagraphModel& rParagraph = aIt->maParagraph; const TextFontModel& rFont = aIt->maFont; if (rFont.mobBold.has()) { @@ -87,6 +90,18 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const aPropertyValue.Value = uno::makeAny(double(rFont.monSize.get()) / 2.); aPropVec.push_back(aPropertyValue); } + if (rParagraph.moParaAdjust.has()) + { + style::ParagraphAdjust eAdjust = style::ParagraphAdjust_LEFT; + if (rParagraph.moParaAdjust.get() == "center") + eAdjust = style::ParagraphAdjust_CENTER; + else if (rParagraph.moParaAdjust.get() == "right") + eAdjust = style::ParagraphAdjust_RIGHT; + + aPropertyValue.Name = "ParaAdjust"; + aPropertyValue.Value = uno::makeAny(eAdjust); + aPropVec.push_back(aPropertyValue); + } uno::Sequence<beans::PropertyValue> aPropSeq(aPropVec.size()); beans::PropertyValue* pValues = aPropSeq.getArray(); for (std::vector<beans::PropertyValue>::iterator i = aPropVec.begin(); i != aPropVec.end(); ++i) diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 9e6f630..b76dd23 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -35,10 +35,11 @@ using ::rtl::OUString; // ============================================================================ TextPortionContext::TextPortionContext( ContextHandler2Helper& rParent, - TextBox& rTextBox, const TextFontModel& rParentFont, + TextBox& rTextBox, TextParagraphModel& rParagraph, const TextFontModel& rParentFont, sal_Int32 nElement, const AttributeList& rAttribs ) : ContextHandler2( rParent ), mrTextBox( rTextBox ), + maParagraph( rParagraph ), maFont( rParentFont ), mnInitialPortions( rTextBox.getPortionCount() ) { @@ -97,7 +98,7 @@ ContextHandlerRef TextPortionContext::onCreateContext( sal_Int32 nElement, const OSL_ENSURE( nElement != XML_font, "TextPortionContext::onCreateContext - nested <font> elements" ); if (getNamespace(getCurrentElement()) == NMSP_doc) return this; - return new TextPortionContext( *this, mrTextBox, maFont, nElement, rAttribs ); + return new TextPortionContext( *this, mrTextBox, maParagraph, maFont, nElement, rAttribs ); } void TextPortionContext::onCharacters( const OUString& rChars ) @@ -109,10 +110,10 @@ void TextPortionContext::onCharacters( const OUString& rChars ) { case XML_span: // replace all NBSP characters with SP - mrTextBox.appendPortion( maFont, rChars.replace( 0xA0, ' ' ) ); + mrTextBox.appendPortion( maParagraph, maFont, rChars.replace( 0xA0, ' ' ) ); break; default: - mrTextBox.appendPortion( maFont, rChars ); + mrTextBox.appendPortion( maParagraph, maFont, rChars ); } } @@ -127,7 +128,7 @@ void TextPortionContext::onStartElement(const AttributeList& rAttribs) maFont.monSize = rAttribs.getInteger( OOX_TOKEN(doc, val) ); break; case OOX_TOKEN(doc, br): - mrTextBox.appendPortion( maFont, "\n" ); + mrTextBox.appendPortion( maParagraph, maFont, "\n" ); break; } } @@ -154,7 +155,7 @@ void TextPortionContext::onEndElement() meantime, the space character has to be added manually. */ if( mrTextBox.getPortionCount() == mnInitialPortions ) - mrTextBox.appendPortion( maFont, OUString( sal_Unicode( ' ' ) ) ); + mrTextBox.appendPortion( maParagraph, maFont, OUString( sal_Unicode( ' ' ) ) ); } // ============================================================================ @@ -208,22 +209,41 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att else if (nElement == OOX_TOKEN(doc, txbxContent)) return this; break; case XML_div: - if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs ); + if( nElement == XML_font ) return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs ); break; case OOX_TOKEN(doc, txbxContent): if (nElement == OOX_TOKEN(doc, p)) return this; break; case OOX_TOKEN(doc, p): - if (nElement == OOX_TOKEN(doc, r)) return new TextPortionContext( *this, mrTextBox, TextFontModel(), nElement, rAttribs ); + if (nElement == OOX_TOKEN(doc, r)) + return new TextPortionContext( *this, mrTextBox, maParagraph, TextFontModel(), nElement, rAttribs ); + else + return this; + break; + case OOX_TOKEN(doc, pPr): + return this; break; } return 0; } +void TextBoxContext::onStartElement(const AttributeList& rAttribs) +{ + switch (getCurrentElement()) + { + case OOX_TOKEN(doc, jc): + maParagraph.moParaAdjust = rAttribs.getString( OOX_TOKEN(doc, val) ); + break; + } +} + void TextBoxContext::onEndElement() { if (getCurrentElement() == OOX_TOKEN(doc, p)) - mrTextBox.appendPortion( TextFontModel(), "\n" ); + { + mrTextBox.appendPortion( maParagraph, TextFontModel(), "\n" ); + maParagraph = TextParagraphModel(); + } } // ============================================================================ commit e5bc604fd2fd54f0f1fc79c2ac8004860afd0e20 Author: Miklos Vajna <vmik...@suse.cz> Date: Mon Jul 1 12:05:23 2013 +0200 bnc#779642 fdo#46361 oox: handle w:br for groupshape textboxes Change-Id: Ib78891614256b197cefbe766a4a4a9c76219f1cf (cherry picked from commit b1f78c44c1acc246f06a963383232c9bf649a06b) diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 903f64e..9e6f630 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -126,6 +126,9 @@ void TextPortionContext::onStartElement(const AttributeList& rAttribs) case OOX_TOKEN(doc, sz): maFont.monSize = rAttribs.getInteger( OOX_TOKEN(doc, val) ); break; + case OOX_TOKEN(doc, br): + mrTextBox.appendPortion( maFont, "\n" ); + break; } } commit 180c8178e8c99295b5d122faffc44330cfca954d Author: Miklos Vajna <vmik...@suse.cz> Date: Mon Jul 1 12:20:09 2013 +0200 bnc#779642 fdo#46361 oox: handle multiple w:p for groupshape textboxes One testcase had to be adjusted, as it seems previously we stripped all newlines at the end (I consider that as a bug), and now we only strip the last one (so the resulting number of paragraphs on the shape and in the source document equal). Change-Id: Ic22b96c2992b53c72e2609e2286622173b86065c (cherry picked from commit f24e4c74d7d6a7d95090c6fa6a584fed7787706c) diff --git a/oox/inc/oox/vml/vmltextboxcontext.hxx b/oox/inc/oox/vml/vmltextboxcontext.hxx index a644026..b324060 100644 --- a/oox/inc/oox/vml/vmltextboxcontext.hxx +++ b/oox/inc/oox/vml/vmltextboxcontext.hxx @@ -63,6 +63,7 @@ public: virtual ::oox::core::ContextHandlerRef onCreateContext( sal_Int32 nElement, const AttributeList& rAttribs ); + virtual void onEndElement(); private: TextBox& mrTextBox; diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index 5a5d75c..490a897 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -94,6 +94,13 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const xTextAppend->appendTextPortion(aIt->maText, aPropSeq); } + // Remove the last character of the shape text, if it would be a newline. + uno::Reference< text::XTextCursor > xCursor = xTextAppend->createTextCursor(); + xCursor->gotoEnd(false); + xCursor->goLeft(1, true); + if (xCursor->getString() == "\n") + xCursor->setString(""); + if ( maLayoutFlow == "vertical" ) { uno::Reference<beans::XPropertySet> xProperties(xShape, uno::UNO_QUERY); diff --git a/oox/source/vml/vmltextboxcontext.cxx b/oox/source/vml/vmltextboxcontext.cxx index 17b0872..903f64e 100644 --- a/oox/source/vml/vmltextboxcontext.cxx +++ b/oox/source/vml/vmltextboxcontext.cxx @@ -217,6 +217,12 @@ ContextHandlerRef TextBoxContext::onCreateContext( sal_Int32 nElement, const Att return 0; } +void TextBoxContext::onEndElement() +{ + if (getCurrentElement() == OOX_TOKEN(doc, p)) + mrTextBox.appendPortion( TextFontModel(), "\n" ); +} + // ============================================================================ } // namespace vml diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 6f07128..9a0e08f 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -375,7 +375,7 @@ xray ThisComponent.DrawPage(1).getByIndex(0).Anchor.PageStyleName uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); uno::Reference<drawing::XShapes> xShapes(xDrawPage->getByIndex(1), uno::UNO_QUERY); uno::Reference<text::XTextRange> xShape(xShapes->getByIndex(0), uno::UNO_QUERY); - CPPUNIT_ASSERT_EQUAL(OUString("TEXT1"), xShape->getString()); + CPPUNIT_ASSERT_EQUAL(OUString("TEXT1\n"), xShape->getString()); // we want to test the textbox is on the first page (it was put onto another page without the fix), // use a small trick and instead of checking the page layout, check the page style uno::Reference<text::XTextContent> xTextContent(xShape, uno::UNO_QUERY); commit 8f9f4232ca0cc5d2f8692083caf6a5f2494e5ce3 Author: Miklos Vajna <vmik...@collabora.co.uk> Date: Thu Sep 5 14:24:02 2013 +0200 bnc#779642 VML import: fix TextHorizontalAdjust when layout-flow is vertical The shape had no special properties about hori/vert text adjustment, so it should be hori left / vert top. Then it has vertical layout-flow, so vert should be top and hori should be right (vert was center). Change-Id: Ia89d8587b6a822ead45198dc5d1ba23907cc3567 (cherry picked from commit b10afb26296e33c77e94a6eda3f2c36c4d34c2aa) diff --git a/oox/source/vml/vmltextbox.cxx b/oox/source/vml/vmltextbox.cxx index 72a18ce..5a5d75c 100644 --- a/oox/source/vml/vmltextbox.cxx +++ b/oox/source/vml/vmltextbox.cxx @@ -22,6 +22,7 @@ #include <rtl/ustrbuf.hxx> #include <com/sun/star/awt/FontWeight.hpp> #include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/drawing/TextHorizontalAdjust.hpp> #include <com/sun/star/text/XTextAppend.hpp> #include <com/sun/star/text/WritingMode.hpp> @@ -96,6 +97,16 @@ void TextBox::convert(uno::Reference<drawing::XShape> xShape) const if ( maLayoutFlow == "vertical" ) { uno::Reference<beans::XPropertySet> xProperties(xShape, uno::UNO_QUERY); + + // VML has the text horizontally aligned to left (all the time), + // v-text-anchor for vertical alignment, and vertical mode to swap the + // two. drawinglayer supports both horizontal and vertical alignment, + // but no vertical mode: we use T->B, R->L instead. + // As a result, we need to set horizontal adjustment here to 'right', + // that will result in vertical 'top' after writing mode is applied, + // which matches the VML behavior. + xProperties->setPropertyValue("TextHorizontalAdjust", uno::makeAny(drawing::TextHorizontalAdjust_RIGHT)); + xProperties->setPropertyValue( "TextWritingMode", uno::makeAny( text::WritingMode_TB_RL ) ); } } diff --git a/sw/qa/extras/inc/swmodeltestbase.hxx b/sw/qa/extras/inc/swmodeltestbase.hxx index cf37f7f..17a978a 100644 --- a/sw/qa/extras/inc/swmodeltestbase.hxx +++ b/sw/qa/extras/inc/swmodeltestbase.hxx @@ -260,6 +260,15 @@ protected: return xCursor->getPage(); } + /// Get shape (counted from 1) + uno::Reference<drawing::XShape> getShape(int number) + { + uno::Reference<drawing::XDrawPageSupplier> xDrawPageSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<drawing::XDrawPage> xDrawPage = xDrawPageSupplier->getDrawPage(); + uno::Reference<drawing::XShape> xShape(xDrawPage->getByIndex(number - 1), uno::UNO_QUERY); + return xShape; + } + uno::Reference<lang::XComponent> mxComponent; xmlBufferPtr mpXmlBuffer; diff --git a/sw/qa/extras/ooxmlimport/data/vml-text-vertical-adjust.docx b/sw/qa/extras/ooxmlimport/data/vml-text-vertical-adjust.docx new file mode 100755 index 0000000..1b05dbd Binary files /dev/null and b/sw/qa/extras/ooxmlimport/data/vml-text-vertical-adjust.docx differ diff --git a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx index 4d6733a..6f07128 100644 --- a/sw/qa/extras/ooxmlimport/ooxmlimport.cxx +++ b/sw/qa/extras/ooxmlimport/ooxmlimport.cxx @@ -28,6 +28,7 @@ #include <com/sun/star/awt/XBitmap.hpp> #include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/document/XEmbeddedObjectSupplier2.hpp> +#include <com/sun/star/drawing/TextVerticalAdjust.hpp> #include <com/sun/star/drawing/XDrawPageSupplier.hpp> #include <com/sun/star/drawing/XControlShape.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> @@ -135,6 +136,7 @@ public: void testTableStyleParprop(); void testTablePagebreak(); void testFdo68607(); + void testVmlTextVerticalAdjust(); CPPUNIT_TEST_SUITE(Test); #if !defined(MACOSX) && !defined(WNT) @@ -219,6 +221,7 @@ void Test::run() {"table-style-parprop.docx", &Test::testTableStyleParprop}, {"table-pagebreak.docx", &Test::testTablePagebreak}, {"fdo68607.docx", &Test::testFdo68607}, + {"vml-text-vertical-adjust.docx", &Test::testVmlTextVerticalAdjust}, }; for (unsigned int i = 0; i < SAL_N_ELEMENTS(aMethods); ++i) { @@ -1370,6 +1373,15 @@ void Test::testFdo68607() CPPUNIT_ASSERT(getPages() > 1); } +void Test::testVmlTextVerticalAdjust() +{ + uno::Reference<drawing::XShapes> xOuterGroupShape(getShape(1), uno::UNO_QUERY); + uno::Reference<drawing::XShapes> xInnerGroupShape(xOuterGroupShape->getByIndex(0), uno::UNO_QUERY); + uno::Reference<drawing::XShape> xShape(xInnerGroupShape->getByIndex(0), uno::UNO_QUERY); + // Was CENTER. + CPPUNIT_ASSERT_EQUAL(drawing::TextVerticalAdjust_TOP, getProperty<drawing::TextVerticalAdjust>(xShape, "TextVerticalAdjust")); +} + CPPUNIT_TEST_SUITE_REGISTRATION(Test); CPPUNIT_PLUGIN_IMPLEMENT(); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/libreoffice-commits