summaryrefslogtreecommitdiff
path: root/svx
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.co.uk>2016-04-25 10:57:49 +0200
committerAndras Timar <andras.timar@collabora.com>2016-05-02 07:36:15 +0000
commit5c32e526d7cc1f623ca1b60a16537efa5740dd6c (patch)
treee0116313902d11980866f029a5f29deaa129e66e /svx
parent6ca35a05e8f5f41482535ecab307dc393dacc5cc (diff)
tdf#99452 svx: fix undo of table row edge drag
The problem as seen by the user: if you have a table of 2 rows and 1 column, and the separator line is dragged upwards by the mouse, then undo doesn't restore the original situation. Two items are created on the undo stack: sd::UndoGeoObject and sdr::table::TableRowUndo. Let's say the table height is 8000 mm100 and the two cell heights are 4000 and 4000. If the user resizes the first cell, so that its height is 2000, then the new table height will be 6000. The problem is that when undo is executed, first sd::UndoGeoObject resizes the table, distributing the newly available 2000 between the existing rows, and then sdr::table::TableRowUndo sets the row height of the first row: the height of the second cell will be larger than expected. Fix the problem by not doing a relayout during sd::UndoGeoObject, but doing a relayout after sdr::table::TableRowUndo in this case. This is done by: 1) Adding a new SdrDragStat::mbEndDragChangesLayout, so that SdrTableObj::applySpecialDrag() can inform SdrDragObjOwn::EndSdrDrag() that TableRowUndo will do the layout instead of UndoGeoObject. (This is done only in case a row edge is dragged, as otherwise it's not guaranteed that a TableRowUndo will follow the UndoGeoObject on the undo stack.) 2) Adding a new SdrUndoGeoObj::mbSkipChangeLayout, so that SdrTableObj::applySpecialDrag() can let SdrUndoGeoObj::Undo() not do the layout. 3) Adding a sdr::table::SdrTableObjImpl::mbSkipChangeLayout, so that SdrUndoGeoObj::Undo() can let SdrTableObj::NbcSetLogicRect() not do the layout. 4) Marking the table model as modified in TableRowUndo::setData(), so it does the layout at the end of the undo group. (cherry picked from commits cafc53f8b4c08443524b1da6f4918d49afd45bb5, 8d1fa417bc49a9e9eee923e3ce6a37d7b0f056f1 and 758e6f39d96237881198818e3bac432012be61d8) Conflicts: sd/qa/unit/tiledrendering/tiledrendering.cxx svx/source/table/svdotable.cxx Change-Id: I8adde3cdad5741e6fcb420e333ce336e18c77cf1 Reviewed-on: https://gerrit.libreoffice.org/24392 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Andras Timar <andras.timar@collabora.com>
Diffstat (limited to 'svx')
-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
7 files changed, 36 insertions, 1 deletions
diff --git a/svx/source/svdraw/svddrag.cxx b/svx/source/svdraw/svddrag.cxx
index 91cd2d145072..2f44f4776856 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 bff9a6c0aead..9d70c20a48b8 100644
--- a/svx/source/svdraw/svddrgmt.cxx
+++ b/svx/source/svdraw/svddrgmt.cxx
@@ -1423,6 +1423,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 b3cf6ae637fa..9567d9e1a12e 100644
--- a/svx/source/svdraw/svdundo.cxx
+++ b/svx/source/svdraw/svdundo.cxx
@@ -603,6 +603,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)
@@ -645,7 +646,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 5b979febf860..4fbcb1f4963c 100644
--- a/svx/source/table/svdotable.cxx
+++ b/svx/source/table/svdotable.cxx
@@ -206,6 +206,7 @@ public:
TableStyleSettings maTableStyle;
Reference< XIndexAccess > mxTableStyle;
std::vector<std::unique_ptr<SdrUndoAction>> maUndos;
+ bool mbSkipChangeLayout;
void SetModel(SdrModel* pOldModel, SdrModel* pNewModel);
@@ -262,6 +263,7 @@ sal_Int32 SdrTableObjImpl::lastColCount;
SdrTableObjImpl::SdrTableObjImpl()
: mpTableObj( nullptr )
, mpLayouter( nullptr )
+, mbSkipChangeLayout(false)
{
}
@@ -1950,7 +1952,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();
+ else
+ NbcAdjustTextFrameWidthAndHeight(!bHeight, !bWidth);
SetRectsDirty();
}
@@ -2098,6 +2104,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.
@@ -2341,6 +2352,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 d86f7e9186b4..37212b72e797 100644
--- a/svx/source/table/tablerow.cxx
+++ b/svx/source/table/tablerow.cxx
@@ -157,6 +157,10 @@ void TableRow::removeColumns( sal_Int32 nIndex, sal_Int32 nCount )
}
}
+TableModelRef const & TableRow::getModel() const
+{
+ return mxTableModel;
+}
// XCellRange
diff --git a/svx/source/table/tablerow.hxx b/svx/source/table/tablerow.hxx
index cc8c23618435..5fdd94064cb0 100644
--- a/svx/source/table/tablerow.hxx
+++ b/svx/source/table/tablerow.hxx
@@ -48,6 +48,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 const & 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 250675e67d48..59d08a2edbf2 100644
--- a/svx/source/table/tableundo.cxx
+++ b/svx/source/table/tableundo.cxx
@@ -492,6 +492,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);
}