[Libreoffice-commits] core.git: Branch 'libreoffice-5-1' - include/svx sd/qa svx/source

Miklos Vajna vmiklos at collabora.co.uk
Thu Jun 9 11:11:00 UTC 2016


 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 <vmiklos at 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.
    
    (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 <ci at libreoffice.org>
    Reviewed-by: Caolán McNamara <caolanm at redhat.com>
    Tested-by: Caolán McNamara <caolanm at redhat.com>

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);
 }
 
 


More information about the Libreoffice-commits mailing list