include/svx/svdotable.hxx | 2 sd/qa/unit/tiledrendering/data/table-column.odp |binary sd/qa/unit/tiledrendering/tiledrendering.cxx | 89 +++++++++++++++++++++++- svx/source/table/svdotable.cxx | 40 ++++++++++ svx/source/table/tablecolumn.cxx | 9 ++ svx/source/table/tablecolumn.hxx | 5 + svx/source/table/tablelayouter.cxx | 29 +++++++ svx/source/table/tablelayouter.hxx | 2 svx/source/table/tablemodel.cxx | 7 + svx/source/table/tablemodel.hxx | 2 svx/source/table/tableundo.cxx | 3 11 files changed, 186 insertions(+), 2 deletions(-)
New commits: commit 0525de4392491aa267c719dda09e3a068cdb413d Author: Miklos Vajna <[email protected]> Date: Wed Jun 8 15:36:24 2016 +0200 tdf#100269 svx: fix undo of table column resize SdrTableObjImpl::LayoutTable() assumed no re-layout is needed in case the total width of the table and the number of columns is the same, but undo of resize is a situation where we also need to check the individual widths of the columns, otherwise layout won't be up to date. (cherry picked from commits a106165e7fd39215c4717e1486aef05f6af9180f and 9cea9137b2534da4056f72d3c8a07f85a02f85be) Conflicts: sd/qa/unit/tiledrendering/tiledrendering.cxx Change-Id: Ia5ebb05af79dda1c0d8c5bb10e7f37f81ee1d035 Reviewed-on: https://gerrit.libreoffice.org/26072 Tested-by: Jenkins <[email protected]> Reviewed-by: Caolán McNamara <[email protected]> Tested-by: Caolán McNamara <[email protected]> diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx index 408f0b8..a38a27f 100644 --- a/include/svx/svdotable.hxx +++ b/include/svx/svdotable.hxx @@ -293,6 +293,8 @@ public: static void ExportAsRTF( SvStream& rStrm, SdrTableObj& rObj ); static void ImportAsRTF( SvStream& rStrm, SdrTableObj& rObj ); + virtual void dumpAsXml(struct _xmlTextWriter* pWriter) const override; + private: void init( sal_Int32 nColumns, sal_Int32 nRows ); diff --git a/sd/qa/unit/tiledrendering/data/table-column.odp b/sd/qa/unit/tiledrendering/data/table-column.odp new file mode 100644 index 0000000..d2c274e Binary files /dev/null and b/sd/qa/unit/tiledrendering/data/table-column.odp differ diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 7e527ef..7952b22 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -31,6 +31,7 @@ #include <ViewShell.hxx> #include <sdpage.hxx> #include <unomodel.hxx> +#include <drawdoc.hxx> using namespace css; @@ -57,6 +58,7 @@ public: void testSearchAll(); void testSearchAllSelections(); void testResizeTable(); + void testResizeTableColumn(); #endif CPPUNIT_TEST_SUITE(SdTiledRenderingTest); @@ -72,6 +74,7 @@ public: CPPUNIT_TEST(testSearchAll); CPPUNIT_TEST(testSearchAllSelections); CPPUNIT_TEST(testResizeTable); + CPPUNIT_TEST(testResizeTableColumn); #endif CPPUNIT_TEST_SUITE_END(); @@ -80,6 +83,7 @@ private: SdXImpressDocument* createDoc(const char* pName); static void callback(int nType, const char* pPayload, void* pData); void callbackImpl(int nType, const char* pPayload); + xmlDocPtr parseXmlDump(); #endif uno::Reference<lang::XComponent> mxComponent; @@ -90,13 +94,15 @@ private: sal_Int32 m_nPart; std::vector<OString> m_aSearchResultSelection; std::vector<int> m_aSearchResultPart; + xmlBufferPtr m_pXmlBuffer; #endif }; SdTiledRenderingTest::SdTiledRenderingTest() #if !defined(WNT) && !defined(MACOSX) : m_bFound(true), - m_nPart(0) + m_nPart(0), + m_pXmlBuffer(nullptr) #endif { } @@ -113,6 +119,11 @@ void SdTiledRenderingTest::tearDown() if (mxComponent.is()) mxComponent->dispose(); +#if !defined(_WIN32) && !defined(MACOSX) + if (m_pXmlBuffer) + xmlBufferFree(m_pXmlBuffer); +#endif + test::BootstrapFixture::tearDown(); } @@ -211,6 +222,28 @@ void SdTiledRenderingTest::callbackImpl(int nType, const char* pPayload) } } +xmlDocPtr SdTiledRenderingTest::parseXmlDump() +{ + if (m_pXmlBuffer) + xmlBufferFree(m_pXmlBuffer); + + // Create the xml writer. + m_pXmlBuffer = xmlBufferCreate(); + xmlTextWriterPtr pXmlWriter = xmlNewTextWriterMemory(m_pXmlBuffer, 0); + xmlTextWriterStartDocument(pXmlWriter, nullptr, nullptr, nullptr); + + // Create the dump. + SdXImpressDocument* pImpressDocument = dynamic_cast<SdXImpressDocument*>(mxComponent.get()); + CPPUNIT_ASSERT(pImpressDocument); + pImpressDocument->GetDoc()->dumpAsXml(pXmlWriter); + + // Delete the xml writer. + xmlTextWriterEndDocument(pXmlWriter); + xmlFreeTextWriter(pXmlWriter); + + return xmlParseMemory(reinterpret_cast<const char*>(xmlBufferContent(m_pXmlBuffer)), xmlBufferLength(m_pXmlBuffer)); +} + void SdTiledRenderingTest::testRegisterCallback() { SdXImpressDocument* pXImpressDocument = createDoc("dummy.odp"); @@ -502,6 +535,60 @@ void SdTiledRenderingTest::testResizeTable() comphelper::LibreOfficeKit::setActive(false); } +void SdTiledRenderingTest::testResizeTableColumn() +{ + // Load the document. + comphelper::LibreOfficeKit::setActive(); + SdXImpressDocument* pXImpressDocument = createDoc("table-column.odp"); + sd::ViewShell* pViewShell = pXImpressDocument->GetDocShell()->GetViewShell(); + SdPage* pActualPage = pViewShell->GetActualPage(); + SdrObject* pObject = pActualPage->GetObj(0); + auto pTableObject = dynamic_cast<sdr::table::SdrTableObj*>(pObject); + CPPUNIT_ASSERT(pTableObject); + + // Select the table by marking it + starting and ending text edit. + SdrView* pView = pViewShell->GetView(); + pView->MarkObj(pObject, pView->GetSdrPageView()); + pView->SdrBeginTextEdit(pObject); + pView->SdrEndTextEdit(); + + // Remember the original cell widths. + xmlDocPtr pXmlDoc = parseXmlDump(); + OString aPrefix = "/sdrModel/sdPage/sdrObjList/sdrTableObj/sdrTableObjImpl/tableLayouter/columns/"; + sal_Int32 nExpectedColumn1 = getXPath(pXmlDoc, aPrefix + "layout[1]", "size").toInt32(); + sal_Int32 nExpectedColumn2 = getXPath(pXmlDoc, aPrefix + "layout[2]", "size").toInt32(); + xmlFreeDoc(pXmlDoc); + pXmlDoc = nullptr; + + // Resize the left column, decrease its width by 1 cm. + Point aInnerRowEdge = pObject->GetSnapRect().Center(); + pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_START, convertMm100ToTwip(aInnerRowEdge.getX()), convertMm100ToTwip(aInnerRowEdge.getY())); + pXImpressDocument->setGraphicSelection(LOK_SETGRAPHICSELECTION_END, convertMm100ToTwip(aInnerRowEdge.getX() - 1000), convertMm100ToTwip(aInnerRowEdge.getY())); + + // Remember the resized column widths. + pXmlDoc = parseXmlDump(); + sal_Int32 nResizedColumn1 = getXPath(pXmlDoc, aPrefix + "layout[1]", "size").toInt32(); + CPPUNIT_ASSERT(nResizedColumn1 < nExpectedColumn1); + sal_Int32 nResizedColumn2 = getXPath(pXmlDoc, aPrefix + "layout[2]", "size").toInt32(); + CPPUNIT_ASSERT(nResizedColumn2 > nExpectedColumn2); + xmlFreeDoc(pXmlDoc); + pXmlDoc = nullptr; + + // Now undo the resize. + pXImpressDocument->GetDocShell()->GetUndoManager()->Undo(); + + // Check the undo result. + pXmlDoc = parseXmlDump(); + sal_Int32 nActualColumn1 = getXPath(pXmlDoc, aPrefix + "layout[1]", "size").toInt32(); + // Expected was 7049, actual was 6048, i.e. the first column width after undo was 1cm smaller than expected. + CPPUNIT_ASSERT_EQUAL(nExpectedColumn1, nActualColumn1); + sal_Int32 nActualColumn2 = getXPath(pXmlDoc, aPrefix + "layout[2]", "size").toInt32(); + CPPUNIT_ASSERT_EQUAL(nExpectedColumn2, nActualColumn2); + xmlFreeDoc(pXmlDoc); + pXmlDoc = nullptr; + comphelper::LibreOfficeKit::setActive(false); +} + #endif CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx index 4fbcb1f..1bf48c1 100644 --- a/svx/source/table/svdotable.cxx +++ b/svx/source/table/svdotable.cxx @@ -57,6 +57,7 @@ #include "svx/xflftrit.hxx" #include "svx/xfltrit.hxx" #include <cppuhelper/implbase.hxx> +#include <libxml/xmlwriter.h> using ::com::sun::star::uno::Any; @@ -223,6 +224,8 @@ public: void dispose(); sal_Int32 getColumnCount() const; + /// Get widths of the columns in the table. + std::vector<sal_Int32> getColumnWidths() const; sal_Int32 getRowCount() const; void DragEdge( bool mbHorizontal, int nEdge, sal_Int32 nOffset ); @@ -240,6 +243,7 @@ public: void connectTableStyle(); void disconnectTableStyle(); virtual bool isInUse() override; + void dumpAsXml(struct _xmlTextWriter* pWriter) const; private: static SdrTableObjImpl* lastLayoutTable; static Rectangle lastLayoutInputRectangle; @@ -249,6 +253,7 @@ private: static WritingMode lastLayoutMode; static sal_Int32 lastRowCount; static sal_Int32 lastColCount; + static std::vector<sal_Int32> lastColWidths; }; SdrTableObjImpl* SdrTableObjImpl::lastLayoutTable = nullptr; @@ -259,6 +264,7 @@ bool SdrTableObjImpl::lastLayoutFitHeight; WritingMode SdrTableObjImpl::lastLayoutMode; sal_Int32 SdrTableObjImpl::lastRowCount; sal_Int32 SdrTableObjImpl::lastColCount; +std::vector<sal_Int32> SdrTableObjImpl::lastColWidths; SdrTableObjImpl::SdrTableObjImpl() : mpTableObj( nullptr ) @@ -641,6 +647,14 @@ bool SdrTableObjImpl::isInUse() return mpTableObj && mpTableObj->IsInserted(); } +void SdrTableObjImpl::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("sdrTableObjImpl")); + if (mpLayouter) + mpLayouter->dumpAsXml(pWriter); + xmlTextWriterEndElement(pWriter); +} + // XEventListener @@ -680,6 +694,15 @@ sal_Int32 SdrTableObjImpl::getColumnCount() const return mxTable.is() ? mxTable->getColumnCount() : 0; } +std::vector<sal_Int32> SdrTableObjImpl::getColumnWidths() const +{ + std::vector<sal_Int32> aRet; + + if (mxTable.is()) + aRet = mxTable->getColumnWidths(); + + return aRet; +} sal_Int32 SdrTableObjImpl::getRowCount() const @@ -701,7 +724,8 @@ void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHe || lastLayoutFitWidth != bFitWidth || lastLayoutFitHeight != bFitHeight || lastLayoutMode != writingMode || lastRowCount != getRowCount() - || lastColCount != getColumnCount() ) + || lastColCount != getColumnCount() + || lastColWidths != getColumnWidths() ) { lastLayoutTable = this; lastLayoutInputRectangle = rArea; @@ -710,6 +734,9 @@ void SdrTableObjImpl::LayoutTable( Rectangle& rArea, bool bFitWidth, bool bFitHe lastLayoutMode = writingMode; lastRowCount = getRowCount(); lastColCount = getColumnCount(); + // Column resize, when the total width and column count of the + // table is unchanged, but re-layout is still needed. + lastColWidths = getColumnWidths(); TableModelNotifyGuard aGuard( mxTable.get() ); mpLayouter->LayoutTable( rArea, bFitWidth, bFitHeight ); lastLayoutResultRectangle = rArea; @@ -2609,6 +2636,17 @@ void SdrTableObj::uno_unlock() mpImpl->mxTable->unlockBroadcasts(); } +void SdrTableObj::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("sdrTableObj")); + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("ptr"), "%p", this); + + SdrObject::dumpAsXml(pWriter); + + mpImpl->dumpAsXml(pWriter); + + xmlTextWriterEndElement(pWriter); +} diff --git a/svx/source/table/tablecolumn.cxx b/svx/source/table/tablecolumn.cxx index 8f48aad..9695169 100644 --- a/svx/source/table/tablecolumn.cxx +++ b/svx/source/table/tablecolumn.cxx @@ -294,6 +294,15 @@ rtl::Reference< FastPropertySetInfo > TableColumn::getStaticPropertySetInfo() return xInfo; } +TableModelRef TableColumn::getModel() const +{ + return mxTableModel; +} + +sal_Int32 TableColumn::getWidth() const +{ + return mnWidth; +} } } diff --git a/svx/source/table/tablecolumn.hxx b/svx/source/table/tablecolumn.hxx index 2f9b3cc..cc76845 100644 --- a/svx/source/table/tablecolumn.hxx +++ b/svx/source/table/tablecolumn.hxx @@ -59,6 +59,11 @@ public: virtual void SAL_CALL setFastPropertyValue( ::sal_Int32 nHandle, const css::uno::Any& aValue ) throw (css::beans::UnknownPropertyException, css::beans::PropertyVetoException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override; virtual css::uno::Any SAL_CALL getFastPropertyValue( ::sal_Int32 nHandle ) throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) override; + /// Get the table that owns this column. + TableModelRef getModel() const; + /// Get the width of this column. + sal_Int32 getWidth() const; + private: static rtl::Reference< FastPropertySetInfo > getStaticPropertySetInfo(); diff --git a/svx/source/table/tablelayouter.cxx b/svx/source/table/tablelayouter.cxx index 1df1378..62d179f 100644 --- a/svx/source/table/tablelayouter.cxx +++ b/svx/source/table/tablelayouter.cxx @@ -22,6 +22,7 @@ #include <com/sun/star/awt/XLayoutConstrains.hpp> #include <tools/gen.hxx> +#include <libxml/xmlwriter.h> #include "cell.hxx" #include "cellrange.hxx" @@ -1151,6 +1152,34 @@ void TableLayouter::DistributeRows( ::Rectangle& rArea, sal_Int32 nFirstRow, sal } } +void TableLayouter::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("tableLayouter")); + + xmlTextWriterStartElement(pWriter, BAD_CAST("columns")); + for (const auto& rColumn : maColumns) + rColumn.dumpAsXml(pWriter); + xmlTextWriterEndElement(pWriter); + + xmlTextWriterStartElement(pWriter, BAD_CAST("rows")); + for (const auto& rRow : maRows) + rRow.dumpAsXml(pWriter); + xmlTextWriterEndElement(pWriter); + + xmlTextWriterEndElement(pWriter); +} + +void TableLayouter::Layout::dumpAsXml(xmlTextWriterPtr pWriter) const +{ + xmlTextWriterStartElement(pWriter, BAD_CAST("layout")); + + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("pos"), BAD_CAST(OString::number(mnPos).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("size"), BAD_CAST(OString::number(mnSize).getStr())); + xmlTextWriterWriteAttribute(pWriter, BAD_CAST("minSize"), BAD_CAST(OString::number(mnMinSize).getStr())); + + xmlTextWriterEndElement(pWriter); +} + } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/svx/source/table/tablelayouter.hxx b/svx/source/table/tablelayouter.hxx index 82b8468..9cd7359 100644 --- a/svx/source/table/tablelayouter.hxx +++ b/svx/source/table/tablelayouter.hxx @@ -97,6 +97,7 @@ public: void DistributeColumns( ::Rectangle& rArea, sal_Int32 nFirstCol, sal_Int32 nLastCol ); void DistributeRows( ::Rectangle& rArea, sal_Int32 nFirstRow, sal_Int32 nLastRow ); + void dumpAsXml(struct _xmlTextWriter* pWriter) const; private: CellRef getCell( const CellPos& rPos ) const; @@ -126,6 +127,7 @@ private: Layout() : mnPos( 0 ), mnSize( 0 ), mnMinSize( 0 ) {} void clear() { mnPos = 0; mnSize = 0; mnMinSize = 0; } + void dumpAsXml(struct _xmlTextWriter* pWriter) const; }; typedef std::vector< Layout > LayoutVector; diff --git a/svx/source/table/tablemodel.cxx b/svx/source/table/tablemodel.cxx index c815720..0bef744 100644 --- a/svx/source/table/tablemodel.cxx +++ b/svx/source/table/tablemodel.cxx @@ -338,6 +338,13 @@ sal_Int32 SAL_CALL TableModel::getColumnCount() throw (RuntimeException, std::ex return getColumnCountImpl(); } +std::vector<sal_Int32> TableModel::getColumnWidths() +{ + std::vector<sal_Int32> aRet; + for (const TableColumnRef& xColumn : maColumns) + aRet.push_back(xColumn->getWidth()); + return aRet; +} // XComponent diff --git a/svx/source/table/tablemodel.hxx b/svx/source/table/tablemodel.hxx index 32d5973..cf9d253 100644 --- a/svx/source/table/tablemodel.hxx +++ b/svx/source/table/tablemodel.hxx @@ -82,6 +82,8 @@ public: /// merges the cell at the given position with the given span void merge( sal_Int32 nCol, sal_Int32 nRow, sal_Int32 nColSpan, sal_Int32 nRowSpan ); + /// Get the width of all columns in this table. + std::vector<sal_Int32> getColumnWidths(); // ICellRange virtual sal_Int32 getLeft() override; diff --git a/svx/source/table/tableundo.cxx b/svx/source/table/tableundo.cxx index 59d08a2..eb01847 100644 --- a/svx/source/table/tableundo.cxx +++ b/svx/source/table/tableundo.cxx @@ -423,6 +423,9 @@ void TableColumnUndo::setData( const Data& rData ) mxCol->mbIsVisible = rData.mbIsVisible; mxCol->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; mxCol->maName = rData.maName; + + // Trigger re-layout of the table. + mxCol->getModel()->setModified(true); }
_______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
