summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/svx/svddrag.hxx4
-rw-r--r--include/svx/svdotable.hxx3
-rw-r--r--include/svx/svdundo.hxx3
-rw-r--r--sd/qa/unit/tiledrendering/data/table.odpbin0 -> 10559 bytes
-rw-r--r--sd/qa/unit/tiledrendering/tiledrendering.cxx51
-rw-r--r--svx/source/svdraw/svddrag.cxx1
-rw-r--r--svx/source/svdraw/svddrgmt.cxx6
-rw-r--r--svx/source/svdraw/svdundo.cxx7
-rw-r--r--svx/source/table/svdotable.cxx14
-rw-r--r--svx/source/table/tablerow.cxx4
-rw-r--r--svx/source/table/tablerow.hxx2
-rw-r--r--svx/source/table/tableundo.cxx3
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
new file mode 100644
index 000000000000..6d92898a00c6
--- /dev/null
+++ b/sd/qa/unit/tiledrendering/data/table.odp
Binary files differ
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);
}