Kaydet (Commit) aef569ed authored tarafından Miklos Vajna's avatar Miklos Vajna

tdf#120028 PPTX import: map shapes with multiple columns to table shapes

Longer term the core Impress shape has to be improved so that it can have
text in multiple columns.

Shorter term, map text with multiple columns to table shapes, that gives
correct layout in many cases and requires changes to the import filter
only.

Change-Id: Id7942b16882ab1f083ded2f0e577e8c9e128697c
Reviewed-on: https://gerrit.libreoffice.org/60859Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.co.uk>
Tested-by: Jenkins
üst 356db87a
......@@ -59,6 +59,9 @@ public:
const css::uno::Reference < css::beans::XPropertySet > & xPropSet,
const ::oox::drawingml::TextListStylePtr& pMasterTextListStyle );
/// Distributes text body with multiple columns in table cells.
void pullFromTextBody(oox::drawingml::TextBodyPtr pTextBody, sal_Int32 nShapeWidth);
private:
const TableStyle& getUsedTableStyle(const ::oox::core::XmlFilterBase& rFilterBase, std::unique_ptr<TableStyle>& rTableStyleToDelete);
......
......@@ -45,6 +45,8 @@ public:
const TextParagraphVector& getParagraphs() const { return maParagraphs; }
TextParagraph& addParagraph();
/// Appends an existing paragraph to this text body.
void appendParagraph(std::shared_ptr<TextParagraph> pTextParagraph);
const TextListStyle& getTextListStyle() const { return maTextListStyle; }
TextListStyle& getTextListStyle() { return maTextListStyle; }
......
......@@ -42,6 +42,8 @@ struct TextBodyProperties
boost::optional< sal_Int32 > moTextOffRight;
css::drawing::TextVerticalAdjust meVA;
OUString msPrst;
/// Number of requested columns.
sal_Int32 mnNumCol = 1;
explicit TextBodyProperties();
......
......@@ -19,6 +19,7 @@
#include <drawingml/table/tableproperties.hxx>
#include <drawingml/table/tablestylelist.hxx>
#include <drawingml/textbody.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <com/sun/star/table/XTable.hpp>
#include <com/sun/star/container/XNameContainer.hpp>
......@@ -304,6 +305,37 @@ void TableProperties::pushToPropSet( const ::oox::core::XmlFilterBase& rFilterBa
xTableStyleToDelete.reset();
}
void TableProperties::pullFromTextBody(oox::drawingml::TextBodyPtr pTextBody, sal_Int32 nShapeWidth)
{
// Create table grid and a single row.
sal_Int32 nNumCol = pTextBody->getTextProperties().mnNumCol;
std::vector<sal_Int32>& rTableGrid(getTableGrid());
sal_Int32 nColWidth = nShapeWidth / nNumCol;
for (sal_Int32 nCol = 0; nCol < nNumCol; ++nCol)
rTableGrid.push_back(nColWidth);
std::vector<drawingml::table::TableRow>& rTableRows(getTableRows());
rTableRows.emplace_back();
oox::drawingml::table::TableRow& rTableRow = rTableRows.back();
std::vector<oox::drawingml::table::TableCell>& rTableCells = rTableRow.getTableCells();
// Create the cells and distribute the paragraphs from pTextBody.
sal_Int32 nNumPara = pTextBody->getParagraphs().size();
sal_Int32 nParaPerCol = std::ceil(double(nNumPara) / nNumCol);
size_t nPara = 0;
for (sal_Int32 nCol = 0; nCol < nNumCol; ++nCol)
{
rTableCells.emplace_back();
oox::drawingml::table::TableCell& rTableCell = rTableCells.back();
TextBodyPtr pCellTextBody(new TextBody);
rTableCell.setTextBody(pCellTextBody);
for (sal_Int32 nParaInCol = 0; nParaInCol < nParaPerCol; ++nParaInCol)
{
if (nPara < pTextBody->getParagraphs().size())
pCellTextBody->appendParagraph(pTextBody->getParagraphs()[nPara]);
++nPara;
}
}
}
} } }
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
......@@ -54,6 +54,11 @@ TextParagraph& TextBody::addParagraph()
return *xPara;
}
void TextBody::appendParagraph(std::shared_ptr<TextParagraph> pTextParagraph)
{
maParagraphs.push_back(pTextParagraph);
}
void TextBody::insertAt(
const ::oox::core::XmlFilterBase& rFilterBase,
const Reference < XText > & xText,
......
......@@ -90,7 +90,7 @@ TextBodyPropertiesContext::TextBodyPropertiesContext( ContextHandler2Helper cons
// sal_Int32 nVertOverflow = rAttribs.getToken( XML_vertOverflow, XML_overflow );
// ST_TextColumnCount
// sal_Int32 nNumCol = rAttribs.getInteger( XML_numCol, 1 );
mrTextBodyProp.mnNumCol = rAttribs.getInteger( XML_numCol, 1 );
// ST_Angle
mrTextBodyProp.moRotation = rAttribs.getInteger( XML_rot );
......
......@@ -20,6 +20,7 @@
#include <oox/ppt/pptshape.hxx>
#include <oox/core/xmlfilterbase.hxx>
#include <drawingml/textbody.hxx>
#include <drawingml/table/tableproperties.hxx>
#include <com/sun/star/awt/Rectangle.hpp>
#include <com/sun/star/container/XNamed.hpp>
......@@ -224,6 +225,23 @@ void PPTShape::addShape(
}
}
if (sServiceName != "com.sun.star.drawing.TableShape")
{
if (TextBodyPtr pTextBody = getTextBody())
{
sal_Int32 nNumCol = pTextBody->getTextProperties().mnNumCol;
if (nNumCol > 1)
{
// This shape is not a table, but has multiple columns,
// represent that as a table.
sServiceName = "com.sun.star.drawing.TableShape";
oox::drawingml::table::TablePropertiesPtr pTableProperties = getTableProperties();
pTableProperties->pullFromTextBody(pTextBody, maSize.Width);
setTextBody(nullptr);
}
}
}
SAL_INFO("oox.ppt","shape service: " << sServiceName);
if (mnSubType && getSubTypeIndex().has() && meShapeLocation == Layout)
......
......@@ -189,6 +189,7 @@ public:
void testPatternImport();
void testPptCrop();
void testTdf119015();
void testTdf120028();
CPPUNIT_TEST_SUITE(SdImportTest);
......@@ -271,6 +272,7 @@ public:
CPPUNIT_TEST(testTdf116266);
CPPUNIT_TEST(testPptCrop);
CPPUNIT_TEST(testTdf119015);
CPPUNIT_TEST(testTdf120028);
CPPUNIT_TEST_SUITE_END();
};
......@@ -2557,6 +2559,30 @@ void SdImportTest::testTdf119015()
xDocShRef->DoClose();
}
void SdImportTest::testTdf120028()
{
::sd::DrawDocShellRef xDocShRef
= loadURL(m_directories.getURLFromSrc("/sd/qa/unit/data/pptx/tdf120028.pptx"), PPTX);
uno::Reference<drawing::XDrawPagesSupplier> xDoc(xDocShRef->GetDoc()->getUnoModel(),
uno::UNO_QUERY);
CPPUNIT_ASSERT(xDoc.is());
uno::Reference<drawing::XDrawPage> xPage(xDoc->getDrawPages()->getByIndex(0), uno::UNO_QUERY);
CPPUNIT_ASSERT(xPage.is());
// This failed, shape was not a table, all text was rendered in a single
// column.
uno::Reference<beans::XPropertySet> xShape(getShape(0, xPage));
uno::Reference<table::XColumnRowRange> xModel(xShape->getPropertyValue("Model"),
uno::UNO_QUERY);
CPPUNIT_ASSERT(xModel.is());
uno::Reference<table::XTableColumns> xColumns = xModel->getColumns();
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int32>(4), xColumns->getCount());
xDocShRef->DoClose();
}
CPPUNIT_TEST_SUITE_REGISTRATION(SdImportTest);
CPPUNIT_PLUGIN_IMPLEMENT();
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment