sd/qa/unit/tiledrendering/data/table-column.odp |binary sd/qa/unit/tiledrendering/tiledrendering.cxx | 88 +++++++++++++++++++++++- svx/source/table/svdotable.cxx | 19 ++++- svx/source/table/tablecolumn.cxx | 9 ++ svx/source/table/tablecolumn.hxx | 5 + svx/source/table/tablemodel.cxx | 7 + svx/source/table/tablemodel.hxx | 2 svx/source/table/tableundo.cxx | 3 8 files changed, 131 insertions(+), 2 deletions(-)
New commits: commit 9cea9137b2534da4056f72d3c8a07f85a02f85be Author: Miklos Vajna <vmik...@collabora.co.uk> 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. Change-Id: Ia5ebb05af79dda1c0d8c5bb10e7f37f81ee1d035 Reviewed-on: https://gerrit.libreoffice.org/26061 Reviewed-by: Miklos Vajna <vmik...@collabora.co.uk> Tested-by: Jenkins <c...@libreoffice.org> 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 a47f990..b4b2ec6 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -63,6 +63,7 @@ public: void testInsertTable(); void testPartHash(); void testResizeTable(); + void testResizeTableColumn(); #endif CPPUNIT_TEST_SUITE(SdTiledRenderingTest); @@ -83,6 +84,7 @@ public: CPPUNIT_TEST(testInsertTable); CPPUNIT_TEST(testPartHash); CPPUNIT_TEST(testResizeTable); + CPPUNIT_TEST(testResizeTableColumn); #endif CPPUNIT_TEST_SUITE_END(); @@ -91,6 +93,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; @@ -106,6 +109,7 @@ private: /// For document size changed callback. osl::Condition m_aDocumentSizeCondition; + xmlBufferPtr m_pXmlBuffer; #endif }; @@ -114,7 +118,8 @@ SdTiledRenderingTest::SdTiledRenderingTest() : m_bFound(true), m_nPart(0), m_nSelectionBeforeSearchResult(0), - m_nSelectionAfterSearchResult(0) + m_nSelectionAfterSearchResult(0), + m_pXmlBuffer(nullptr) #endif { } @@ -131,6 +136,11 @@ void SdTiledRenderingTest::tearDown() if (mxComponent.is()) mxComponent->dispose(); +#if !defined(_WIN32) && !defined(MACOSX) + if (m_pXmlBuffer) + xmlBufferFree(m_pXmlBuffer); +#endif + test::BootstrapFixture::tearDown(); } @@ -238,6 +248,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"); @@ -729,6 +761,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 = "/sdDrawDocument/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 36fa94f..d9a48be 100644 --- a/svx/source/table/svdotable.cxx +++ b/svx/source/table/svdotable.cxx @@ -222,6 +222,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 ); @@ -249,6 +251,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 +262,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 ) @@ -671,6 +675,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 { @@ -691,7 +704,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; @@ -700,6 +714,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; diff --git a/svx/source/table/tablecolumn.cxx b/svx/source/table/tablecolumn.cxx index 597da0b..c5ceade 100644 --- a/svx/source/table/tablecolumn.cxx +++ b/svx/source/table/tablecolumn.cxx @@ -283,6 +283,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 9c81c69..0c5083d 100644 --- a/svx/source/table/tablecolumn.hxx +++ b/svx/source/table/tablecolumn.hxx @@ -58,6 +58,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/tablemodel.cxx b/svx/source/table/tablemodel.cxx index b6dd245..e706228 100644 --- a/svx/source/table/tablemodel.cxx +++ b/svx/source/table/tablemodel.cxx @@ -321,6 +321,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 66263e6..411bf2f 100644 --- a/svx/source/table/tablemodel.hxx +++ b/svx/source/table/tablemodel.hxx @@ -81,6 +81,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 3a60ab0..cb0093f 100644 --- a/svx/source/table/tableundo.cxx +++ b/svx/source/table/tableundo.cxx @@ -400,6 +400,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 libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits