diff options
-rw-r--r-- | include/svx/svddrag.hxx | 4 | ||||
-rw-r--r-- | include/svx/svdotable.hxx | 3 | ||||
-rw-r--r-- | include/svx/svdundo.hxx | 3 | ||||
-rw-r--r-- | sd/qa/unit/tiledrendering/data/table.odp | bin | 0 -> 10559 bytes | |||
-rw-r--r-- | sd/qa/unit/tiledrendering/tiledrendering.cxx | 51 | ||||
-rw-r--r-- | svx/source/svdraw/svddrag.cxx | 1 | ||||
-rw-r--r-- | svx/source/svdraw/svddrgmt.cxx | 6 | ||||
-rw-r--r-- | svx/source/svdraw/svdundo.cxx | 7 | ||||
-rw-r--r-- | svx/source/table/svdotable.cxx | 14 | ||||
-rw-r--r-- | svx/source/table/tablerow.cxx | 4 | ||||
-rw-r--r-- | svx/source/table/tablerow.hxx | 2 | ||||
-rw-r--r-- | svx/source/table/tableundo.cxx | 3 |
12 files changed, 97 insertions, 1 deletions
diff --git a/include/svx/svddrag.hxx b/include/svx/svddrag.hxx index 0160f8040235..ef48ccf692fa 100644 --- a/include/svx/svddrag.hxx +++ b/include/svx/svddrag.hxx @@ -55,6 +55,8 @@ protected: bool bEndDragChangesAttributes; bool bEndDragChangesGeoAndAttributes; + /// Table row drag: table will re-layout itself later. + bool mbEndDragChangesLayout; bool bMouseIsUp; bool bShown; // Xor visible? @@ -133,6 +135,8 @@ public: void SetEndDragChangesAttributes(bool bOn) { bEndDragChangesAttributes=bOn; } bool IsEndDragChangesGeoAndAttributes() const { return bEndDragChangesGeoAndAttributes; } void SetEndDragChangesGeoAndAttributes(bool bOn) { bEndDragChangesGeoAndAttributes=bOn; } + bool IsEndDragChangesLayout() const { return mbEndDragChangesLayout; } + void SetEndDragChangesLayout(bool bOn) { mbEndDragChangesLayout=bOn; } // Is set by the view and can be evaluated by Obj bool IsMouseDown() const { return !bMouseIsUp; } diff --git a/include/svx/svdotable.hxx b/include/svx/svdotable.hxx index ed1264d5eeb9..5747e2bf3dde 100644 --- a/include/svx/svdotable.hxx +++ b/include/svx/svdotable.hxx @@ -253,6 +253,9 @@ public: /// Add an undo action that should be on the undo stack after ending text edit. void AddUndo(SdrUndoAction* pUndo); + /// Next time layouting would be done, skip it (to layout at the end of multiple actions). + void SetSkipChangeLayout(bool bSkipChangeLayout); + virtual void onEditOutlinerStatusEvent( EditStatus* pEditStatus ) override; // Transformation interface for StarOfficeAPI. This implements support for diff --git a/include/svx/svdundo.hxx b/include/svx/svdundo.hxx index 23e65c69fd2f..5f3ee5f1601d 100644 --- a/include/svx/svdundo.hxx +++ b/include/svx/svdundo.hxx @@ -213,6 +213,8 @@ protected: SdrObjGeoData* pRedoGeo; // If we have a group object: SdrUndoGroup* pUndoGroup; + /// If we have a table object, should its layout change? + bool mbSkipChangeLayout; public: SdrUndoGeoObj(SdrObject& rNewObj); @@ -222,6 +224,7 @@ public: virtual void Redo() override; virtual OUString GetComment() const override; + void SetSkipChangeLayout(bool bOn) { mbSkipChangeLayout=bOn; } }; /** diff --git a/sd/qa/unit/tiledrendering/data/table.odp b/sd/qa/unit/tiledrendering/data/table.odp Binary files differnew file mode 100644 index 000000000000..6d92898a00c6 --- /dev/null +++ b/sd/qa/unit/tiledrendering/data/table.odp diff --git a/sd/qa/unit/tiledrendering/tiledrendering.cxx b/sd/qa/unit/tiledrendering/tiledrendering.cxx index 88b437f3286b..a47f99077267 100644 --- a/sd/qa/unit/tiledrendering/tiledrendering.cxx +++ b/sd/qa/unit/tiledrendering/tiledrendering.cxx @@ -25,6 +25,7 @@ #include <sfx2/viewfrm.hxx> #include <svl/srchitem.hxx> #include <comphelper/lok.hxx> +#include <svx/svdotable.hxx> #include <DrawDocShell.hxx> #include <ViewShell.hxx> @@ -61,6 +62,7 @@ public: void testInsertDeletePage(); void testInsertTable(); void testPartHash(); + void testResizeTable(); #endif CPPUNIT_TEST_SUITE(SdTiledRenderingTest); @@ -80,6 +82,7 @@ public: CPPUNIT_TEST(testInsertDeletePage); CPPUNIT_TEST(testInsertTable); CPPUNIT_TEST(testPartHash); + CPPUNIT_TEST(testResizeTable); #endif CPPUNIT_TEST_SUITE_END(); @@ -678,6 +681,54 @@ void SdTiledRenderingTest::testPartHash() comphelper::LibreOfficeKit::setActive(false); } +void SdTiledRenderingTest::testResizeTable() +{ + // Load the document. + comphelper::LibreOfficeKit::setActive(); + SdXImpressDocument* pXImpressDocument = createDoc("table.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 row heights. + uno::Reference<table::XColumnRowRange> xTable(pTableObject->getTable(), uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xRows(xTable->getRows(), uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xRow1(xRows->getByIndex(0), uno::UNO_QUERY); + sal_Int32 nExpectedRow1 = xRow1->getPropertyValue("Size").get<sal_Int32>(); + uno::Reference<beans::XPropertySet> xRow2(xRows->getByIndex(1), uno::UNO_QUERY); + sal_Int32 nExpectedRow2 = xRow2->getPropertyValue("Size").get<sal_Int32>(); + + // Resize the upper row, decrease its height 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()), convertMm100ToTwip(aInnerRowEdge.getY() - 1000)); + + // Remember the resized row heights. + sal_Int32 nResizedRow1 = xRow1->getPropertyValue("Size").get<sal_Int32>(); + CPPUNIT_ASSERT(nResizedRow1 < nExpectedRow1); + sal_Int32 nResizedRow2 = xRow2->getPropertyValue("Size").get<sal_Int32>(); + CPPUNIT_ASSERT_EQUAL(nExpectedRow2, nResizedRow2); + + // Now undo the resize. + pXImpressDocument->GetDocShell()->GetUndoManager()->Undo(); + + // Check the undo result. + sal_Int32 nActualRow1 = xRow1->getPropertyValue("Size").get<sal_Int32>(); + CPPUNIT_ASSERT_EQUAL(nExpectedRow1, nActualRow1); + sal_Int32 nActualRow2 = xRow2->getPropertyValue("Size").get<sal_Int32>(); + // Expected was 4000, actual was 4572, i.e. the second row after undo was larger than expected. + CPPUNIT_ASSERT_EQUAL(nExpectedRow2, nActualRow2); + comphelper::LibreOfficeKit::setActive(false); +} + #endif CPPUNIT_TEST_SUITE_REGISTRATION(SdTiledRenderingTest); diff --git a/svx/source/svdraw/svddrag.cxx b/svx/source/svdraw/svddrag.cxx index 8eb54cbef3d8..75c046a1326b 100644 --- a/svx/source/svdraw/svddrag.cxx +++ b/svx/source/svdraw/svddrag.cxx @@ -50,6 +50,7 @@ void SdrDragStat::Reset() pDragMethod=nullptr; bEndDragChangesAttributes=false; bEndDragChangesGeoAndAttributes=false; + mbEndDragChangesLayout=false; bMouseIsUp=false; Clear(true); aActionRect=Rectangle(); diff --git a/svx/source/svdraw/svddrgmt.cxx b/svx/source/svdraw/svddrgmt.cxx index 09ca6cba9b1a..5996b50eaecd 100644 --- a/svx/source/svdraw/svddrgmt.cxx +++ b/svx/source/svdraw/svddrgmt.cxx @@ -1410,6 +1410,12 @@ bool SdrDragObjOwn::EndSdrDrag(bool /*bCopy*/) } bRet = pObj->applySpecialDrag(DragStat()); + if (DragStat().IsEndDragChangesLayout()) + { + auto pGeoUndo = dynamic_cast<SdrUndoGeoObj*>(pUndo); + if (pGeoUndo) + pGeoUndo->SetSkipChangeLayout(true); + } if(bRet) { diff --git a/svx/source/svdraw/svdundo.cxx b/svx/source/svdraw/svdundo.cxx index 37e81e7cdffe..e3cc47895528 100644 --- a/svx/source/svdraw/svdundo.cxx +++ b/svx/source/svdraw/svdundo.cxx @@ -598,6 +598,7 @@ SdrUndoGeoObj::SdrUndoGeoObj(SdrObject& rNewObj) , pUndoGeo(nullptr) , pRedoGeo(nullptr) , pUndoGroup(nullptr) + , mbSkipChangeLayout(false) { SdrObjList* pOL=rNewObj.GetSubList(); if (pOL!=nullptr && pOL->GetObjCount() && dynamic_cast<const E3dScene* >( &rNewObj) == nullptr) @@ -640,7 +641,13 @@ void SdrUndoGeoObj::Undo() { delete pRedoGeo; pRedoGeo=pObj->GetGeoData(); + + auto pTableObj = dynamic_cast<sdr::table::SdrTableObj*>(pObj); + if (pTableObj && mbSkipChangeLayout) + pTableObj->SetSkipChangeLayout(true); pObj->SetGeoData(*pUndoGeo); + if (pTableObj && mbSkipChangeLayout && pTableObj) + pTableObj->SetSkipChangeLayout(false); } } diff --git a/svx/source/table/svdotable.cxx b/svx/source/table/svdotable.cxx index 4121fdaf3d6c..9d13f8fca6b3 100644 --- a/svx/source/table/svdotable.cxx +++ b/svx/source/table/svdotable.cxx @@ -204,6 +204,7 @@ public: TableStyleSettings maTableStyle; Reference< XIndexAccess > mxTableStyle; std::vector<std::unique_ptr<SdrUndoAction>> maUndos; + bool mbSkipChangeLayout; void SetModel(SdrModel* pOldModel, SdrModel* pNewModel); @@ -260,6 +261,7 @@ sal_Int32 SdrTableObjImpl::lastColCount; SdrTableObjImpl::SdrTableObjImpl() : mpTableObj( nullptr ) , mpLayouter( nullptr ) +, mbSkipChangeLayout(false) { } @@ -1868,7 +1870,11 @@ void SdrTableObj::NbcSetLogicRect(const Rectangle& rRect) const bool bWidth = maLogicRect.getWidth() != maRect.getWidth(); const bool bHeight = maLogicRect.getHeight() != maRect.getHeight(); maRect = maLogicRect; - NbcAdjustTextFrameWidthAndHeight( !bHeight, !bWidth ); + if (mpImpl->mbSkipChangeLayout) + // Avoid distributing newly available space between existing cells. + NbcAdjustTextFrameWidthAndHeight(true, true); + else + NbcAdjustTextFrameWidthAndHeight(!bHeight, !bWidth); SetRectsDirty(); } @@ -2005,6 +2011,11 @@ void SdrTableObj::AddUndo(SdrUndoAction* pUndo) mpImpl->maUndos.push_back(std::unique_ptr<SdrUndoAction>(pUndo)); } +void SdrTableObj::SetSkipChangeLayout(bool bSkipChangeLayout) +{ + mpImpl->mbSkipChangeLayout = bSkipChangeLayout; +} + // gets base transformation and rectangle of object. If it's an SdrPathObj it fills the PolyPolygon // with the base geometry and returns TRUE. Otherwise it returns FALSE. bool SdrTableObj::TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon ) const @@ -2247,6 +2258,7 @@ bool SdrTableObj::applySpecialDrag(SdrDragStat& rDrag) if( GetModel() && IsInserted() ) { rDrag.SetEndDragChangesAttributes(true); + rDrag.SetEndDragChangesLayout(true); } mpImpl->DragEdge( pEdgeHdl->IsHorizontalEdge(), pEdgeHdl->GetPointNum(), pEdgeHdl->GetValidDragOffset( rDrag ) ); diff --git a/svx/source/table/tablerow.cxx b/svx/source/table/tablerow.cxx index ee95e905554b..cd82cc423b45 100644 --- a/svx/source/table/tablerow.cxx +++ b/svx/source/table/tablerow.cxx @@ -149,6 +149,10 @@ void TableRow::removeColumns( sal_Int32 nIndex, sal_Int32 nCount ) } } +TableModelRef TableRow::getModel() const +{ + return mxTableModel; +} // XCellRange diff --git a/svx/source/table/tablerow.hxx b/svx/source/table/tablerow.hxx index 77d654f23297..6b38b8037389 100644 --- a/svx/source/table/tablerow.hxx +++ b/svx/source/table/tablerow.hxx @@ -47,6 +47,8 @@ public: void insertColumns( sal_Int32 nIndex, sal_Int32 nCount, CellVector::iterator* pIter = nullptr ); void removeColumns( sal_Int32 nIndex, sal_Int32 nCount ); + /// Reference to the table model containing this row. + TableModelRef getModel() const; // XCellRange virtual css::uno::Reference< css::table::XCell > SAL_CALL getCellByPosition( sal_Int32 nColumn, sal_Int32 nRow ) throw (css::lang::IndexOutOfBoundsException, css::uno::RuntimeException, std::exception) override; diff --git a/svx/source/table/tableundo.cxx b/svx/source/table/tableundo.cxx index baa7e6c29456..3a60ab02d0c2 100644 --- a/svx/source/table/tableundo.cxx +++ b/svx/source/table/tableundo.cxx @@ -463,6 +463,9 @@ void TableRowUndo::setData( const Data& rData ) mxRow->mbIsVisible = rData.mbIsVisible; mxRow->mbIsStartOfNewPage = rData.mbIsStartOfNewPage; mxRow->maName = rData.maName; + + // Trigger re-layout of the table. + mxRow->getModel()->setModified(true); } |