summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSarper Akdemir <sarper.akdemir@collabora.com>2023-03-29 19:44:18 +0300
committerSarper Akdemir <sarper.akdemir@collabora.com>2023-04-17 16:21:06 +0200
commit178832ef7139b9279a3ae0056eb11be9c476800e (patch)
tree28c49618beca5101f445a16dc1a9b131254d14df
parent77655fc3dca05d4bb2366e67ccea228e3886bfe2 (diff)
oox: tcPr vert roundtrip, introduce interopability grab bag for table cell
To properly roundtrip all possible values of <a:tcPr vert="..."> + Introduce grab bag for table cell + on import: Store the unsupported values in the grab bag: + (e.g. wordArtVert, mongolianVert, wordArtVertRtl) + on export: if nothing is being exported from the doc model, export the value from the grabbag Also adds a unit test covering this behavior. Change-Id: I791ed2d992b0a554ef6da37200f027cffd8c5f2f Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149737 Tested-by: Jenkins Reviewed-by: Sarper Akdemir <sarper.akdemir@collabora.com>
-rw-r--r--include/svx/svddef.hxx4
-rw-r--r--oox/source/drawingml/table/tablecell.cxx38
-rw-r--r--oox/source/export/shapes.cxx14
-rw-r--r--sd/qa/unit/data/pptx/tcPr-vert-roundtrip.pptxbin0 -> 32277 bytes
-rw-r--r--sd/qa/unit/export-tests-ooxml3.cxx12
-rw-r--r--svx/source/inc/cell.hxx3
-rw-r--r--svx/source/svdraw/svdattr.cxx3
-rw-r--r--svx/source/table/cell.cxx21
8 files changed, 89 insertions, 6 deletions
diff --git a/include/svx/svddef.hxx b/include/svx/svddef.hxx
index 85a72e5b713d..84db8c4d0aa4 100644
--- a/include/svx/svddef.hxx
+++ b/include/svx/svddef.hxx
@@ -138,6 +138,7 @@ class SdrVertShearAllItem;
class SdrVertShearOneItem;
class SdrYesNoItem;
class SfxBoolItem;
+class SfxGrabBagItem;
class SfxInt16Item;
class SfxUInt16Item;
class SfxUInt32Item;
@@ -417,7 +418,8 @@ constexpr TypedWhichId<SvxBoxInfoItem> SDRATTR_TABLE_BORDER_INNER (SDRATTR_T
constexpr TypedWhichId<SvxLineItem> SDRATTR_TABLE_BORDER_TLBR (SDRATTR_TABLE_FIRST+2);
constexpr TypedWhichId<SvxLineItem> SDRATTR_TABLE_BORDER_BLTR (SDRATTR_TABLE_FIRST+3);
constexpr TypedWhichId<SvxTextRotateItem> SDRATTR_TABLE_TEXT_ROTATION (SDRATTR_TABLE_FIRST+4);
-constexpr sal_uInt16 SDRATTR_TABLE_LAST (SDRATTR_TABLE_TEXT_ROTATION);
+constexpr TypedWhichId<SfxGrabBagItem> SDRATTR_TABLE_GRABBAG (SDRATTR_TABLE_FIRST+5);
+constexpr sal_uInt16 SDRATTR_TABLE_LAST (SDRATTR_TABLE_GRABBAG);
constexpr sal_uInt16 SDRATTR_GLOW_FIRST (SDRATTR_TABLE_LAST+1);
constexpr TypedWhichId<SdrMetricItem> SDRATTR_GLOW_RADIUS (SDRATTR_GLOW_FIRST+0);
diff --git a/oox/source/drawingml/table/tablecell.cxx b/oox/source/drawingml/table/tablecell.cxx
index 17b13526084d..b0849b7002f3 100644
--- a/oox/source/drawingml/table/tablecell.cxx
+++ b/oox/source/drawingml/table/tablecell.cxx
@@ -29,12 +29,15 @@
#include <oox/helper/propertyset.hxx>
#include <oox/token/properties.hxx>
#include <oox/token/tokens.hxx>
+#include <oox/token/tokenmap.hxx>
#include <tools/color.hxx>
#include <com/sun/star/table/BorderLineStyle.hpp>
#include <com/sun/star/table/BorderLine2.hpp>
#include <com/sun/star/drawing/TextVerticalAdjust.hpp>
#include <com/sun/star/text/XText.hpp>
#include <com/sun/star/text/WritingMode.hpp>
+#include <comphelper/propertysequence.hxx>
+#include <comphelper/propertyvalue.hxx>
using namespace ::oox::core;
using namespace ::com::sun::star;
@@ -566,6 +569,36 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, cons
{
xPropSet->setPropertyValue("TextWritingMode", Any(css::text::WritingMode_TB_RL));
}
+ else if ( getVertToken() == XML_vert )
+ {
+ xPropSet->setPropertyValue("RotateAngle", Any(short(27000)));
+ }
+ else if ( getVertToken() == XML_vert270 )
+ {
+ xPropSet->setPropertyValue("RotateAngle", Any(short(9000)));
+ }
+ else if ( getVertToken() != XML_horz )
+ {
+ // put the vert value in the grab bag for roundtrip
+ const Sequence<sal_Int8>& aTokenNameSeq = StaticTokenMap().getUtf8TokenName(getVertToken());
+ const OUString aTokenName{ reinterpret_cast<const char*>(aTokenNameSeq.getConstArray()),
+ aTokenNameSeq.getLength(), RTL_TEXTENCODING_UTF8 };
+
+ Sequence<PropertyValue> aGrabBag;
+ xPropSet->getPropertyValue("CellInteropGrabBag") >>= aGrabBag;
+ PropertyValue aPropertyValue = comphelper::makePropertyValue("mso-tcPr-vert-value", aTokenName);
+ if (aGrabBag.hasElements())
+ {
+ sal_Int32 nLength = aGrabBag.getLength();
+ aGrabBag.realloc(nLength + 1);
+ aGrabBag.getArray()[nLength] = aPropertyValue;
+ }
+ else
+ {
+ aGrabBag = { aPropertyValue };
+ }
+ xPropSet->setPropertyValue("CellInteropGrabBag", Any(aGrabBag));
+ }
getTextBody()->insertAt( rFilterBase, xText, xAt, aTextStyleProps, pMasterTextListStyle );
@@ -582,11 +615,6 @@ void TableCell::pushToXCell( const ::oox::core::XmlFilterBase& rFilterBase, cons
aTextCharacterProps.pushToPropSet(aPropSet, rFilterBase);
}
}
-
- if (getVertToken() == XML_vert)
- xPropSet->setPropertyValue("RotateAngle", Any(short(27000)));
- else if (getVertToken() == XML_vert270)
- xPropSet->setPropertyValue("RotateAngle", Any(short(9000)));
}
}
diff --git a/oox/source/export/shapes.cxx b/oox/source/export/shapes.cxx
index eecd1b38512c..b93dd01b69fb 100644
--- a/oox/source/export/shapes.cxx
+++ b/oox/source/export/shapes.cxx
@@ -2317,6 +2317,20 @@ void ShapeExport::WriteTableCellProperties(const Reference< XPropertySet>& xCell
aRotateAngle >>= nRotateAngle;
std::optional<OString> aTextVerticalValue = GetTextVerticalType(nRotateAngle);
+ Sequence<PropertyValue> aGrabBag;
+ if( !aTextVerticalValue &&
+ (xCellPropSet->getPropertyValue("CellInteropGrabBag") >>= aGrabBag) )
+ {
+ for (auto const& rIt : std::as_const(aGrabBag))
+ {
+ if (rIt.Name == "mso-tcPr-vert-value")
+ {
+ aTextVerticalValue = rIt.Value.get<OUString>().toUtf8();
+ break;
+ }
+ }
+ }
+
mpFS->startElementNS(XML_a, XML_tcPr, XML_anchor, sVerticalAlignment,
XML_vert, aTextVerticalValue,
XML_marL, sax_fastparser::UseIf(OString::number(oox::drawingml::convertHmmToEmu(nLeftMargin)), nLeftMargin > 0),
diff --git a/sd/qa/unit/data/pptx/tcPr-vert-roundtrip.pptx b/sd/qa/unit/data/pptx/tcPr-vert-roundtrip.pptx
new file mode 100644
index 000000000000..9600f5ec1d98
--- /dev/null
+++ b/sd/qa/unit/data/pptx/tcPr-vert-roundtrip.pptx
Binary files differ
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx b/sd/qa/unit/export-tests-ooxml3.cxx
index 3931c53b912b..d8d92ca54ae8 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -1984,6 +1984,18 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf102261_testParaTabStopDefaultDis
}
}
+CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTableCellVerticalPropertyRoundtrip)
+{
+ createSdImpressDoc("pptx/tcPr-vert-roundtrip.pptx");
+ saveAndReload("Impress Office Open XML");
+
+ xmlDocUniquePtr pXml = parseExport("ppt/slides/slide1.xml");
+
+ assertXPath(pXml, "(//a:tcPr)[1]", "vert", "vert270");
+ assertXPath(pXml, "(//a:tcPr)[2]", "vert", "vert");
+ assertXPath(pXml, "(//a:tcPr)[3]", "vert", "wordArtVert");
+}
+
CPPUNIT_PLUGIN_IMPLEMENT();
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/inc/cell.hxx b/svx/source/inc/cell.hxx
index 331465f4eaa3..34ae09223ce5 100644
--- a/svx/source/inc/cell.hxx
+++ b/svx/source/inc/cell.hxx
@@ -27,6 +27,7 @@
#include <rtl/ref.hxx>
#include <svl/style.hxx>
+#include <svl/grabbagitem.hxx>
#include <svx/sdtaitm.hxx>
#include "tablemodel.hxx"
#include <editeng/unotext.hxx>
@@ -209,6 +210,8 @@ private:
tools::Rectangle maCellRect;
css::uno::Reference< css::table::XTable > mxTable;
+
+ std::unique_ptr<SfxGrabBagItem> mpGrabBagItem = {};
};
diff --git a/svx/source/svdraw/svdattr.cxx b/svx/source/svdraw/svdattr.cxx
index 5af9956fc45d..1898f13140ae 100644
--- a/svx/source/svdraw/svdattr.cxx
+++ b/svx/source/svdraw/svdattr.cxx
@@ -43,6 +43,8 @@
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
+#include <svl/grabbagitem.hxx>
+
#include <svx/strings.hrc>
#include <svx/dialmgr.hxx>
#include <svx/sdgcpitm.hxx>
@@ -327,6 +329,7 @@ SdrItemPool::SdrItemPool(
rPoolDefaults[ SDRATTR_TABLE_BORDER_TLBR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_TLBR );
rPoolDefaults[ SDRATTR_TABLE_BORDER_BLTR - SDRATTR_START ] = new SvxLineItem( SDRATTR_TABLE_BORDER_BLTR );
rPoolDefaults[ SDRATTR_TABLE_TEXT_ROTATION - SDRATTR_START ] = new SvxTextRotateItem(0_deg10, SDRATTR_TABLE_TEXT_ROTATION);
+ rPoolDefaults[ SDRATTR_TABLE_GRABBAG - SDRATTR_START ] = new SfxGrabBagItem(SDRATTR_TABLE_GRABBAG);
rPoolDefaults[ SDRATTR_GLOW_RADIUS - SDRATTR_START ] = new SdrMetricItem(SDRATTR_GLOW_RADIUS, 0);
rPoolDefaults[ SDRATTR_GLOW_COLOR - SDRATTR_START ] = new XColorItem(SDRATTR_GLOW_COLOR, aNullCol);
diff --git a/svx/source/table/cell.cxx b/svx/source/table/cell.cxx
index 97490977a50e..d1dbd0f8088f 100644
--- a/svx/source/table/cell.cxx
+++ b/svx/source/table/cell.cxx
@@ -27,6 +27,7 @@
#include <comphelper/sequence.hxx>
#include <o3tl/any.hxx>
+#include <svl/grabbagitem.hxx>
#include <svl/style.hxx>
#include <svl/itemset.hxx>
@@ -96,6 +97,7 @@ static const SvxItemPropertySet* ImplGetSvxCellPropertySet()
{ u"LeftBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, LEFT_BORDER },
{ u"RightBorder", SDRATTR_TABLE_BORDER, cppu::UnoType<BorderLine>::get(), 0, RIGHT_BORDER },
{ u"RotateAngle", SDRATTR_TABLE_TEXT_ROTATION, cppu::UnoType<sal_Int32>::get(), 0, 0 },
+ { u"CellInteropGrabBag", SDRATTR_TABLE_GRABBAG, cppu::UnoType<css::uno::Sequence<css::beans::PropertyValue>>::get(), 0, 0},
SVX_UNOEDIT_OUTLINER_PROPERTIES,
SVX_UNOEDIT_CHAR_PROPERTIES,
@@ -1105,6 +1107,14 @@ void SAL_CALL Cell::setPropertyValue( const OUString& rPropertyName, const Any&
mpProperties->SetObjectItem(SvxTextRotateItem(Degree10(nRotVal/10), SDRATTR_TABLE_TEXT_ROTATION));
return;
}
+ case SDRATTR_TABLE_GRABBAG:
+ {
+ if (mpGrabBagItem == nullptr)
+ mpGrabBagItem.reset(new SfxGrabBagItem);
+
+ mpGrabBagItem->PutValue(rValue, 0);
+ return;
+ }
default:
{
SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);
@@ -1225,6 +1235,17 @@ Any SAL_CALL Cell::getPropertyValue( const OUString& PropertyName )
const SvxTextRotateItem& rTextRotate = mpProperties->GetItem(SDRATTR_TABLE_TEXT_ROTATION);
return Any(sal_Int32(to<Degree100>(rTextRotate.GetValue())));
}
+ case SDRATTR_TABLE_GRABBAG:
+ {
+ if (mpGrabBagItem != nullptr)
+ {
+ Any aGrabBagSequence;
+ mpGrabBagItem->QueryValue(aGrabBagSequence);
+ return aGrabBagSequence;
+ }
+ else
+ return Any{css::uno::Sequence<css::beans::PropertyValue>()};
+ }
default:
{
SfxItemSet aSet(GetObject().getSdrModelFromSdrObject().GetItemPool(), pMap->nWID, pMap->nWID);