include/svx/svxids.hrc | 4 sc/inc/drwlayer.hxx | 1 sc/inc/userdat.hxx | 22 +++ sc/qa/unit/subsequent_export-test.cxx | 22 +-- sc/qa/unit/subsequent_filters-test.cxx | 2 sc/qa/unit/ucalc.cxx | 10 + sc/sdi/drawsh.sdi | 1 sc/source/core/data/drwlayer.cxx | 150 +++++++++++++++++++------ sc/source/core/data/table3.cxx | 2 sc/source/core/data/table5.cxx | 10 + sc/source/ui/drawfunc/drawsh2.cxx | 2 sc/source/ui/drawfunc/drawsh5.cxx | 2 sc/source/ui/view/drawvie3.cxx | 2 sc/uiconfig/scalc/toolbar/drawobjectbar.xml | 2 sc/uiconfig/scalc/toolbar/formdesign.xml | 2 sc/uiconfig/scalc/toolbar/graphicobjectbar.xml | 2 svx/sdi/svx.sdi | 17 ++ sw/inc/cmdid.h | 1 sw/sdi/_basesh.sdi | 4 sw/sdi/swriter.sdi | 19 --- sw/source/uibase/shells/basesh.cxx | 8 - 21 files changed, 197 insertions(+), 88 deletions(-)
New commits: commit 7b6a26187590d46f6ca71347d92c30601d349a06 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Date: Fri Mar 9 09:41:08 2018 +0100 tdf#114552 Convert anchor toggle to anchor menu Since we now have three, not two anchor types. Reviewed-on: https://gerrit.libreoffice.org/50987 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Maxim Monastirsky <momonas...@gmail.com> Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> (cherry picked from commit 1a7444ed69a68696b05feb3f3618b6704a140ba6) Change-Id: I9654de574a9d546d2191093cba9c192fac3cd3d7 diff --git a/include/svx/svxids.hrc b/include/svx/svxids.hrc index af989bc60a2a..67cbc9a24973 100644 --- a/include/svx/svxids.hrc +++ b/include/svx/svxids.hrc @@ -1030,10 +1030,10 @@ #define SID_ATTR_PAGE_FILLSTYLE ( SID_SVX_START + 1157 ) #define SID_EDIT_POSTIT ( SID_SVX_START + 1158 ) - +#define SID_ANCHOR_MENU ( SID_SVX_START + 1159 ) // IMPORTANT NOTE: adjust SID_SVX_FIRSTFREE, when adding new slot id -#define SID_SVX_FIRSTFREE (SID_EDIT_POSTIT + 1) +#define SID_SVX_FIRSTFREE (SID_ANCHOR_MENU + 1) // Overflow check for slot IDs diff --git a/sc/sdi/drawsh.sdi b/sc/sdi/drawsh.sdi index d6c0f4ca0352..2e9f8640d66a 100644 --- a/sc/sdi/drawsh.sdi +++ b/sc/sdi/drawsh.sdi @@ -166,6 +166,7 @@ interface TableDraw SID_MIRROR_VERTICAL [ ExecMethod = ExecDrawFunc; StateMethod = GetDrawFuncState; Export = FALSE; ] SID_FLIP_HORIZONTAL [ ExecMethod = ExecDrawFunc; StateMethod = GetDrawFuncState; Export = FALSE; ] SID_FLIP_VERTICAL [ ExecMethod = ExecDrawFunc; StateMethod = GetDrawFuncState; Export = FALSE; ] + SID_ANCHOR_MENU [ StateMethod = GetDrawFuncState; Export = FALSE; ] SID_ANCHOR_PAGE [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] SID_ANCHOR_TOGGLE [ ExecMethod = ExecDrawFunc; StateMethod = GetDrawFuncState; Export = FALSE; ] SID_ANCHOR_CELL [ ExecMethod = ExecDrawFunc; StateMethod = GetState; Export = FALSE; ] diff --git a/sc/source/ui/drawfunc/drawsh2.cxx b/sc/source/ui/drawfunc/drawsh2.cxx index ec02c32d923b..3ff312bdfb67 100644 --- a/sc/source/ui/drawfunc/drawsh2.cxx +++ b/sc/source/ui/drawfunc/drawsh2.cxx @@ -245,6 +245,7 @@ void ScDrawShell::GetDrawFuncState( SfxItemSet& rSet ) // Funktionen disabl rSet.DisableItem( SID_COPY ); // Notes always default to Page anchor. rSet.DisableItem( SID_ANCHOR_TOGGLE ); + rSet.DisableItem( SID_ANCHOR_MENU ); } } @@ -274,6 +275,7 @@ void ScDrawShell::GetDrawFuncState( SfxItemSet& rSet ) // Funktionen disabl rSet.DisableItem( SID_COPY ); // sonstiges rSet.DisableItem( SID_ANCHOR_TOGGLE ); + rSet.DisableItem( SID_ANCHOR_MENU ); rSet.DisableItem( SID_ORIGINALSIZE ); rSet.DisableItem( SID_FITCELLSIZE ); rSet.DisableItem( SID_ATTR_TRANSFORM ); diff --git a/sc/source/ui/drawfunc/drawsh5.cxx b/sc/source/ui/drawfunc/drawsh5.cxx index 49a266b065d5..c0df55b43825 100644 --- a/sc/source/ui/drawfunc/drawsh5.cxx +++ b/sc/source/ui/drawfunc/drawsh5.cxx @@ -377,8 +377,6 @@ void ScDrawShell::ExecDrawFunc( SfxRequest& rReq ) rBindings.Invalidate( SID_ANCHOR_CELL_RESIZE ); break; - // TODO: This toggle should probably be converted to a dropdown, - // since we now have three states, not two. case SID_ANCHOR_TOGGLE: { switch( pView->GetAnchorType() ) diff --git a/sc/uiconfig/scalc/toolbar/drawobjectbar.xml b/sc/uiconfig/scalc/toolbar/drawobjectbar.xml index 334ac397189a..a13a113e8b73 100644 --- a/sc/uiconfig/scalc/toolbar/drawobjectbar.xml +++ b/sc/uiconfig/scalc/toolbar/drawobjectbar.xml @@ -32,7 +32,7 @@ <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:FillStyle" toolbar:helpid="10164"/> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:ToggleAnchorType" toolbar:helpid="26412"/> + <toolbar:toolbaritem xlink:href=".uno:AnchorMenu"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:ToggleObjectRotateMode" toolbar:helpid="10129"/> <toolbar:toolbaritem xlink:href=".uno:ObjectAlign" toolbar:helpid="10130"/> diff --git a/sc/uiconfig/scalc/toolbar/formdesign.xml b/sc/uiconfig/scalc/toolbar/formdesign.xml index ed70f63eb9ec..5804f06448c4 100644 --- a/sc/uiconfig/scalc/toolbar/formdesign.xml +++ b/sc/uiconfig/scalc/toolbar/formdesign.xml @@ -30,7 +30,7 @@ <toolbar:toolbaritem xlink:href=".uno:AddField"/> <toolbar:toolbaritem xlink:href=".uno:AutoControlFocus"/> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:ToggleAnchorType"/> + <toolbar:toolbaritem xlink:href=".uno:AnchorMenu"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:BringToFront" toolbar:visible="false"/> <toolbar:toolbaritem xlink:href=".uno:SendToBack" toolbar:visible="false"/> diff --git a/sc/uiconfig/scalc/toolbar/graphicobjectbar.xml b/sc/uiconfig/scalc/toolbar/graphicobjectbar.xml index 21b6e75f3915..aec3dfb52b7e 100644 --- a/sc/uiconfig/scalc/toolbar/graphicobjectbar.xml +++ b/sc/uiconfig/scalc/toolbar/graphicobjectbar.xml @@ -35,7 +35,7 @@ <toolbar:toolbaritem xlink:href=".uno:Crop"/> <toolbar:toolbaritem xlink:href=".uno:FillShadow"/> <toolbar:toolbarseparator/> - <toolbar:toolbaritem xlink:href=".uno:ToggleAnchorType"/> + <toolbar:toolbaritem xlink:href=".uno:AnchorMenu"/> <toolbar:toolbaritem xlink:href=".uno:ObjectAlign"/> <toolbar:toolbarseparator/> <toolbar:toolbaritem xlink:href=".uno:BringToFront"/> diff --git a/svx/sdi/svx.sdi b/svx/sdi/svx.sdi index 9754bd41cc50..4e15bb51801d 100644 --- a/svx/sdi/svx.sdi +++ b/svx/sdi/svx.sdi @@ -11950,3 +11950,20 @@ SfxUInt16Item CurrentOutlineType FN_OUTLINE_RULE_INDEX ToolBoxConfig = FALSE, GroupId = GID_ENUMERATION; ] + +SfxVoidItem AnchorMenu SID_ANCHOR_MENU +() +[ + AutoUpdate = FALSE, + FastCall = TRUE, + ReadOnlyDoc = FALSE, + Toggle = FALSE, + Container = FALSE, + RecordAbsolute = FALSE, + RecordPerSet; + + AccelConfig = TRUE, + MenuConfig = TRUE, + ToolBoxConfig = TRUE, + GroupId = GID_FORMAT; +] diff --git a/sw/inc/cmdid.h b/sw/inc/cmdid.h index 36a93cef8ba7..9793ef1c2c4d 100644 --- a/sw/inc/cmdid.h +++ b/sw/inc/cmdid.h @@ -241,7 +241,6 @@ #define FN_INSERT_IDX_ENTRY_DLG (FN_INSERT + 35) /* insert index entry */ #define FN_INSERT_FRAME_INTERACT_NOCOL (FN_INSERT + 36) /*insert interactive non column frame*/ -#define FN_TOOL_ANCHOR (FN_INSERT + 49) /* Draw Anchor for object */ #define FN_TOOL_ANCHOR_PAGE (FN_INSERT + 50) /* anchor Draw object to page */ #define FN_TOOL_ANCHOR_PARAGRAPH (FN_INSERT + 51) /* anchor Draw object to paragraph */ #define FN_TOOL_HIERARCHIE (FN_INSERT + 52) /* change hierarchy */ diff --git a/sw/sdi/_basesh.sdi b/sw/sdi/_basesh.sdi index 87de4941bc8e..16c57f8e42c1 100644 --- a/sw/sdi/_basesh.sdi +++ b/sw/sdi/_basesh.sdi @@ -387,8 +387,8 @@ interface BaseTextSelection StateMethod = GetState ; DisableFlags="SW_DISABLE_ON_PROTECTED_CURSOR"; ] -// Methode fuer Rahmen und Objekte - FN_TOOL_ANCHOR +// Method for frames and objects + SID_ANCHOR_MENU [ ExecMethod = Execute ; StateMethod = GetState ; diff --git a/sw/sdi/swriter.sdi b/sw/sdi/swriter.sdi index 1b6c16a6a6f5..04f6afe79a81 100644 --- a/sw/sdi/swriter.sdi +++ b/sw/sdi/swriter.sdi @@ -5999,25 +5999,6 @@ SfxVoidItem TextWrap FN_DRAW_WRAP_DLG GroupId = GID_FORMAT; ] -SfxVoidItem AnchorMenu FN_TOOL_ANCHOR -() -[ - AutoUpdate = FALSE, - FastCall = TRUE, - ReadOnlyDoc = FALSE, - Toggle = FALSE, - Container = FALSE, - RecordAbsolute = FALSE, - RecordPerSet; - - SlotType = SfxUInt16Item - - AccelConfig = TRUE, - MenuConfig = TRUE, - ToolBoxConfig = TRUE, - GroupId = GID_FORMAT; -] - SfxVoidItem ToggleObjectLayer FN_TOOL_HIERARCHIE () [ diff --git a/sw/source/uibase/shells/basesh.cxx b/sw/source/uibase/shells/basesh.cxx index 03572fcc3809..d196220df476 100644 --- a/sw/source/uibase/shells/basesh.cxx +++ b/sw/source/uibase/shells/basesh.cxx @@ -1003,7 +1003,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) rSh.CallChgLnk(); } break; - case FN_TOOL_ANCHOR: + case SID_ANCHOR_MENU: break; case FN_TOOL_ANCHOR_PAGE: case FN_TOOL_ANCHOR_PARAGRAPH: @@ -1098,7 +1098,7 @@ void SwBaseShell::Execute(SfxRequest &rReq) } rSh.EndUndo(); - GetView().GetViewFrame()->GetBindings().Invalidate( FN_TOOL_ANCHOR ); + GetView().GetViewFrame()->GetBindings().Invalidate( SID_ANCHOR_MENU ); } break; @@ -1560,7 +1560,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) } break; - case FN_TOOL_ANCHOR: + case SID_ANCHOR_MENU: case FN_TOOL_ANCHOR_PAGE: case FN_TOOL_ANCHOR_PARAGRAPH: case FN_TOOL_ANCHOR_CHAR: @@ -1589,7 +1589,7 @@ void SwBaseShell::GetState( SfxItemSet &rSet ) (eSet == FLY_AT_CHAR)) || ((nWhich == FN_TOOL_ANCHOR_CHAR) && (eSet == FLY_AS_CHAR)); - if(nWhich != FN_TOOL_ANCHOR) + if(nWhich != SID_ANCHOR_MENU) { if( nWhich == FN_TOOL_ANCHOR_FRAME && !rSh.IsFlyInFly() ) rSet.DisableItem(nWhich); commit ecbdf2e3465b2fe544d078872cbb87d081541685 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Date: Tue Feb 27 16:56:44 2018 +0100 tdf#114552 Improve image scaling in Calc When anchor type "To cell (resize with cell)" is selected, we do now:: 1. Consider aspect ratio when scaling graphic objects with cell This only works when the image fits into one cell. When the image is over multiple cells, we need to respect the end anchor, so we need to keep the existing behavior (no aspect ratio considered). 2. Always scale images if anchor type is "resize with cell" Previously it would only scale if the image is larger than the cell. Now we always enlarge the image if the cell is enlarged, and shrink the image if the cell is shrinked _and_ the image no longer fits into the shrinked cell Reviewed-on: https://gerrit.libreoffice.org/50451 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Eike Rathke <er...@redhat.com> (cherry picked from commit 4f29ce6a67b81e7f28e1c86d60ff15ec1d180661) Change-Id: Ib2a24819d0058bcebce73ea97bbf70a963d74584 diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx index df1ebbe8edb1..091d8f1da471 100644 --- a/sc/inc/drwlayer.hxx +++ b/sc/inc/drwlayer.hxx @@ -184,6 +184,7 @@ public: static void SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab, bool bResizeWithCell ); static void UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true ); static ScAnchorType GetAnchorType( const SdrObject& ); + std::vector<SdrObject*> GetObjectsAnchoredToRows(SCTAB nTab, SCROW nStartRow, SCROW nEndRow); std::map<SCROW, std::vector<SdrObject*>> GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow) const; bool HasObjectsAnchoredInRange(ScRange& rRange) const; void MoveObject(SdrObject* pObj, ScAddress& rNewPosition); diff --git a/sc/inc/userdat.hxx b/sc/inc/userdat.hxx index 3edf6fe3677d..b644df44a302 100644 --- a/sc/inc/userdat.hxx +++ b/sc/inc/userdat.hxx @@ -25,6 +25,7 @@ #include <svtools/imap.hxx> #include "global.hxx" #include "address.hxx" +#include "drwlayer.hxx" #define SC_DRAWLAYER 0x30334353 // Inventor: "SC30" @@ -51,13 +52,32 @@ public: Point maStartOffset; Point maEndOffset; Type meType; - Rectangle maLastRect; + bool mbResizeWithCell = false; + bool mbWasInHiddenRow = false; explicit ScDrawObjData(); + Rectangle getShapeRect() { return maShapeRect; }; + Rectangle getLastCellRect() { return maLastCellRect; }; + void setShapeRect(const ScDocument* rDoc, Rectangle rNewRect, bool bIsVisible=true) + { + // bIsVisible should be false when the object is hidden obviously. we dont want to store the old cell rect in that + // case because it will have height=0 + if (maStart.IsValid() && mbResizeWithCell && bIsVisible) + maLastCellRect = ScDrawLayer::GetCellRect(const_cast<ScDocument&>(*rDoc), maStart, true); + maShapeRect = rNewRect; + mbWasInHiddenRow = !bIsVisible; + }; + private: virtual ScDrawObjData* Clone( SdrObject* pObj ) const override; + + // Stores the last cell rect this shape was anchored to. + // Needed when the cell is resized to resize the image accordingly. + Rectangle maLastCellRect; + // Stores the rect of the shape to which this ScDrawObjData belongs. + Rectangle maShapeRect; }; class ScIMapInfo : public SdrObjUserData diff --git a/sc/qa/unit/subsequent_export-test.cxx b/sc/qa/unit/subsequent_export-test.cxx index 5638017e2de4..4e90034a5f99 100644 --- a/sc/qa/unit/subsequent_export-test.cxx +++ b/sc/qa/unit/subsequent_export-test.cxx @@ -1815,7 +1815,7 @@ void ScExportTest::testCellAnchoredGroupXLS() ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); CPPUNIT_ASSERT_MESSAGE("Upper left of bounding rectangle should be nonnegative.", - pData->maLastRect.Left() >= 0 || pData->maLastRect.Top() >= 0); + pData->getShapeRect().Left() >= 0 || pData->getShapeRect().Top() >= 0); xDocSh->DoClose(); } @@ -3405,7 +3405,7 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get anchor data ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); ScAddress aDataStart = pData->maStart; ScAddress aDataEnd = pData->maEnd; @@ -3413,7 +3413,7 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get non rotated anchor data ScDrawObjData* pNData = ScDrawLayer::GetNonRotatedObjData( pObj ); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty()); ScAddress aNDataStart = pNData->maStart; ScAddress aNDataEnd = pNData->maEnd; @@ -3426,12 +3426,12 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get anchor data pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); // Get non rotated anchor data pNData = ScDrawLayer::GetNonRotatedObjData( pObj ); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty()); // Check if data has moved to new rows CPPUNIT_ASSERT_EQUAL( pData->maStart.Row(), aDataStart.Row() + 2 ); @@ -3467,12 +3467,12 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get anchor data pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); // Get non rotated anchor data pNData = ScDrawLayer::GetNonRotatedObjData( pObj ); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty()); // Check if data after save it CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart); @@ -3487,12 +3487,12 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get anchor data pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); // Get non rotated anchor data pNData = ScDrawLayer::GetNonRotatedObjData( pObj ); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty()); // Check if data has moved to new rows CPPUNIT_ASSERT_EQUAL(pData->maStart.Col(), SCCOL(aDataStart.Col() + 1)); @@ -3528,12 +3528,12 @@ void ScExportTest::testMoveCellAnchoredShapes() // Get anchor data pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); // Get non rotated anchor data pNData = ScDrawLayer::GetNonRotatedObjData( pObj ); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve non rotated user data for this object.", pNData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pNData->getShapeRect().IsEmpty()); // Check if data after save it CPPUNIT_ASSERT_EQUAL(pData->maStart, aDataStart); diff --git a/sc/qa/unit/subsequent_filters-test.cxx b/sc/qa/unit/subsequent_filters-test.cxx index 15cf041123d7..69d7a4f43a36 100644 --- a/sc/qa/unit/subsequent_filters-test.cxx +++ b/sc/qa/unit/subsequent_filters-test.cxx @@ -1744,7 +1744,7 @@ void ScFiltersTest::testCellAnchoredShapesODS() CPPUNIT_ASSERT_MESSAGE("Failed to get drawing object.", pObj); ScDrawObjData* pData = ScDrawLayer::GetObjData(pObj); CPPUNIT_ASSERT_MESSAGE("Failed to retrieve user data for this object.", pData); - CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->maLastRect.IsEmpty()); + CPPUNIT_ASSERT_MESSAGE("Bounding rectangle should have been calculated upon import.", !pData->getShapeRect().IsEmpty()); } xDocSh->DoClose(); diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx index 3c2f6c723fb8..d52c771edb26 100644 --- a/sc/qa/unit/ucalc.cxx +++ b/sc/qa/unit/ucalc.cxx @@ -2583,14 +2583,18 @@ void Test::testGraphicsInGroup() m_pDoc->ShowRows(0, 100, 0, false); m_pDoc->SetDrawPageSize(0); + + const long TOLERANCE = 30; //30 hmm + CPPUNIT_ASSERT_MESSAGE("Left and Right should be unchanged", - aOrigRect.Left() == rNewRect.Left() && aOrigRect.Right() == rNewRect.Right()); + testEqualsWithTolerance(aOrigRect.Left(), rNewRect.Left(), TOLERANCE) && + testEqualsWithTolerance(aOrigRect.Right(), rNewRect.Right(), TOLERANCE)); CPPUNIT_ASSERT_MESSAGE("Height should be minimum allowed height", (rNewRect.Bottom() - rNewRect.Top()) <= 1); m_pDoc->ShowRows(0, 100, 0, true); m_pDoc->SetDrawPageSize(0); - CPPUNIT_ASSERT_EQUAL_MESSAGE("Should not change when page anchored", - static_cast<const Rectangle &>(aOrigRect), rNewRect); + CPPUNIT_ASSERT_EQUAL_MESSAGE("Should not change when cell anchored", + const_cast<const Rectangle &>(aOrigRect), rNewRect); } { diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index 4ac593948eac..cd9c8c70400a 100644 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -638,40 +638,94 @@ namespace static_cast<long>(aRange.getMaxX()), static_cast<long>(aRange.getMaxY())); } } + void ScDrawLayer::ResizeLastRectFromAnchor( SdrObject* pObj, ScDrawObjData& rData, bool bUseLogicRect, bool bNegativePage, bool bCanResize, bool bHiddenAsZero ) { - rData.maLastRect = ( bUseLogicRect ? pObj->GetLogicRect() : pObj->GetSnapRect() ); + Rectangle aRect = bUseLogicRect ? pObj->GetLogicRect() : pObj->GetSnapRect(); SCCOL nCol1 = rData.maStart.Col(); SCROW nRow1 = rData.maStart.Row(); SCTAB nTab1 = rData.maStart.Tab(); SCCOL nCol2 = rData.maEnd.Col(); SCROW nRow2 = rData.maEnd.Row(); SCTAB nTab2 = rData.maEnd.Tab(); - Point aPos( pDoc->GetColOffset( nCol1, nTab1, bHiddenAsZero ), pDoc->GetRowOffset( nRow1, nTab1, bHiddenAsZero ) ); - TwipsToMM( aPos.X() ); - TwipsToMM( aPos.Y() ); + Point aPos(pDoc->GetColOffset(nCol1, nTab1, bHiddenAsZero), + pDoc->GetRowOffset(nRow1, nTab1, bHiddenAsZero)); + aPos.setX(TwipsToHmm(aPos.X())); + aPos.setY(TwipsToHmm(aPos.Y())); aPos += lcl_calcAvailableDiff(*pDoc, nCol1, nRow1, nTab1, rData.maStartOffset); + aRect.SetPos(aPos); - if( bCanResize ) + if (bCanResize) { - Point aEnd( pDoc->GetColOffset( nCol2, nTab2, bHiddenAsZero ), pDoc->GetRowOffset( nRow2, nTab2, bHiddenAsZero ) ); - TwipsToMM( aEnd.X() ); - TwipsToMM( aEnd.Y() ); - aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset); + Rectangle aLastCellRect = rData.getLastCellRect(); - Rectangle aNew = Rectangle( aPos, aEnd ); - if ( bNegativePage ) - MirrorRectRTL( aNew ); + // If the row was hidden before, or we don't have a valid cell rect, calculate the + // new rect based on the end point. + // Also when the end point is set, we need to consider it. + if (rData.mbWasInHiddenRow || aLastCellRect.IsEmpty() || nRow1 != nRow2 || nCol1 != nCol2) + { + Point aEnd(pDoc->GetColOffset(nCol2, nTab2, bHiddenAsZero), + pDoc->GetRowOffset(nRow2, nTab2, bHiddenAsZero)); + aEnd.setX(TwipsToHmm(aEnd.X())); + aEnd.setY(TwipsToHmm(aEnd.Y())); + aEnd += lcl_calcAvailableDiff(*pDoc, nCol2, nRow2, nTab2, rData.maEndOffset); - rData.maLastRect = lcl_makeSafeRectangle(aNew); - } - else - { - if ( bNegativePage ) - aPos.X() = -aPos.X() - rData.maLastRect.GetWidth(); - // shouldn't we initialise maLastRect with the object rectangle ? - rData.maLastRect.SetPos( aPos ); + aRect = Rectangle(aPos, aEnd); + } + else if (!aLastCellRect.IsEmpty()) + { + // We calculate based on the last cell rect to be able to scale the image + // as much as the cell was scaled. + // Still, we keep the image in its current cell (to keep start anchor == end anchor) + Rectangle aCurrentCellRect = GetCellRect(*GetDocument(), rData.maStart, true); + double fWidthFactor = static_cast<double>(aCurrentCellRect.GetWidth()) + / static_cast<double>(aLastCellRect.GetWidth()); + double fHeightFactor = static_cast<double>(aCurrentCellRect.GetHeight()) + / static_cast<double>(aLastCellRect.GetHeight()); + + bool bIsGrowingLarger = aLastCellRect.GetWidth() * aLastCellRect.GetHeight() + < aCurrentCellRect.GetWidth() * aCurrentCellRect.GetHeight(); + + if (pObj->shouldKeepAspectRatio()) + { + Rectangle aRectIncludingOffset = aRect; + aRectIncludingOffset.setWidth(aRect.GetWidth() + rData.maStartOffset.X()); + aRectIncludingOffset.setHeight(aRect.GetHeight() + rData.maStartOffset.Y()); + double fMaxWidthFactor = static_cast<double>(aCurrentCellRect.GetWidth()) + / static_cast<double>(aRectIncludingOffset.GetWidth()); + double fMaxHeightFactor = static_cast<double>(aCurrentCellRect.GetHeight()) + / static_cast<double>(aRectIncludingOffset.GetHeight()); + double fMaxFactor = std::min(fMaxHeightFactor, fMaxWidthFactor); + + if (bIsGrowingLarger) // cell is growing larger + { + // To actually grow the image, we need to take the max + fWidthFactor = fHeightFactor = std::max(fWidthFactor, fHeightFactor); + // But we don't want the image to become larger than the current cell + fWidthFactor = fHeightFactor = std::min(fWidthFactor, fMaxFactor); + } + else // cell is growing smaller, take the min + { + fWidthFactor = fHeightFactor = std::min(fWidthFactor, fHeightFactor); + } + } + + // When shrinking the cell, and the image still fits in the smaller cell, don't resize it at all + if (bIsGrowingLarger + || rData.getShapeRect().GetUnion(aCurrentCellRect) != aCurrentCellRect) + { + aRect.setWidth( + rtl::math::round(static_cast<double>(aRect.GetWidth()) * fWidthFactor)); + aRect.setHeight( + rtl::math::round(static_cast<double>(aRect.GetHeight()) * fHeightFactor)); + } + } } + + if (bNegativePage) + MirrorRectRTL(aRect); + + rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(aRect), pObj->IsVisible()); } void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos ) @@ -709,7 +763,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if (rData.meType == ScDrawObjData::ValidationCircle) { // Validation circle for detective. - rData.maLastRect = pObj->GetLogicRect(); + rData.setShapeRect(GetDocument(), pObj->GetLogicRect()); Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) ); TwipsToMM( aPos.X() ); @@ -731,13 +785,13 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati { if (bRecording) AddCalcUndo( new SdrUndoGeoObj( *pObj ) ); - rData.maLastRect = lcl_makeSafeRectangle(aRect); - pObj->SetLogicRect(rData.maLastRect); + rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(aRect)); + pObj->SetLogicRect(rData.getShapeRect()); } } else if (rData.meType == ScDrawObjData::DetectiveArrow) { - rData.maLastRect = pObj->GetLogicRect(); + rData.setShapeRect(GetDocument(), pObj->GetLogicRect()); basegfx::B2DPolygon aCalcPoly; Point aOrigStartPos(pObj->GetPoint(0)); Point aOrigEndPos(pObj->GetPoint(1)); @@ -764,7 +818,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if (bRecording) AddCalcUndo( new SdrUndoGeoObj( *pObj ) ); - rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos); + rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos)); pObj->SetPoint( aStartPos, 0 ); } @@ -780,7 +834,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if (bRecording) AddCalcUndo( new SdrUndoGeoObj( *pObj ) ); - rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos); + rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos)); pObj->SetPoint( aEndPos, 1 ); } } @@ -802,7 +856,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if (bRecording) AddCalcUndo( new SdrUndoGeoObj( *pObj ) ); - rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos); + rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 1, aEndPos)); pObj->SetPoint( aEndPos, 1 ); } @@ -820,7 +874,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if (bRecording) AddCalcUndo( new SdrUndoGeoObj( *pObj ) ); - rData.maLastRect = lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos); + rData.setShapeRect(GetDocument(), lcl_UpdateCalcPoly(aCalcPoly, 0, aStartPos)); pObj->SetPoint( aStartPos, 0 ); } } @@ -832,7 +886,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati //First time positioning, must be able to at least move it ScDrawObjData& rNoRotatedAnchor = *GetNonRotatedObjData( pObj, true ); - if (rData.maLastRect.IsEmpty()) + if (rData.getShapeRect().IsEmpty()) { // Every shape it is saved with an negative offset relative to cell ScAnchorType aAnchorType = ScDrawLayer::GetAnchorType(*pObj); @@ -892,7 +946,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati // is guaranteed to get consistent results) ResizeLastRectFromAnchor( pObj, rData, true, bNegativePage, bCanResize, false ); // aFullRect contains the unrotated size and position of the shape (regardless of any hidden row/columns) - Rectangle aFullRect = rData.maLastRect; + Rectangle aFullRect = rData.getShapeRect(); // get current size and position from the anchor for use later ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize ); @@ -905,7 +959,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati // an Anchor based on the SnapRect ( which is what you see on the screen ) ScDrawLayer::GetCellAnchorFromPosition( *pObj, rData, *pDoc, nTab1, false, false ); // reset shape to true 'maybe affected by hidden rows/cols' size calculated previously - pObj->SetLogicRect(rNoRotatedAnchor.maLastRect); + pObj->SetLogicRect(rNoRotatedAnchor.getShapeRect()); } // update anchor with snap rect @@ -913,7 +967,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati if( bCanResize ) { - Rectangle aNew = rData.maLastRect; + Rectangle aNew = rData.getShapeRect(); if ( pObj->GetSnapRect() != aNew ) { @@ -935,8 +989,8 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati } // order of these lines is important, modify rData.maLastRect carefully it is used as both // a value and a flag for initialisation - rData.maLastRect = lcl_makeSafeRectangle(rData.maLastRect); - pObj->SetSnapRect(rData.maLastRect); + rData.setShapeRect(GetDocument(), lcl_makeSafeRectangle(rData.getShapeRect()), pObj->IsVisible()); + pObj->SetSnapRect(rData.getShapeRect()); // update 'unrotated anchor' it's the anchor we persist, it must be kept in sync // with the normal Anchor ResizeLastRectFromAnchor( pObj, rNoRotatedAnchor, true, bNegativePage, bCanResize ); @@ -944,7 +998,7 @@ void ScDrawLayer::RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegati } else { - Point aPos( rData.maLastRect.getX(), rData.maLastRect.getY() ); + Point aPos( rData.getShapeRect().getX(), rData.getShapeRect().getY() ); if ( pObj->GetRelativePos() != aPos ) { if (bRecording) @@ -1915,7 +1969,7 @@ void ScDrawLayer::SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument // doing an initialisation hack if ( ScDrawObjData* pAnchor = GetObjData( &rObj ) ) { - pAnchor->maLastRect = rObj.GetSnapRect(); + pAnchor->setShapeRect(&rDoc, rObj.GetSnapRect()); } } @@ -2005,6 +2059,30 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj ) return SCA_CELL; } +std::vector<SdrObject*> +ScDrawLayer::GetObjectsAnchoredToRows(SCTAB nTab, SCROW nStartRow, SCROW nEndRow) +{ + SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab)); + if (!pPage || pPage->GetObjCount() < 1) + return std::vector<SdrObject*>(); + + std::vector<SdrObject*> aObjects; + SdrObjListIter aIter( *pPage, IM_FLAT ); + SdrObject* pObject = aIter.Next(); + ScRange aRange( 0, nStartRow, nTab, MAXCOL, nEndRow, nTab); + while (pObject) + { + if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently + { + ScDrawObjData* pObjData = GetObjData(pObject); + if (pObjData && aRange.In(pObjData->maStart)) + aObjects.push_back(pObject); + } + pObject = aIter.Next(); + } + return aObjects; +} + std::map<SCROW, std::vector<SdrObject*>> ScDrawLayer::GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow) const { diff --git a/sc/source/core/data/table5.cxx b/sc/source/core/data/table5.cxx index 2ae8872488ed..2ffd9133ba7a 100644 --- a/sc/source/core/data/table5.cxx +++ b/sc/source/core/data/table5.cxx @@ -591,6 +591,16 @@ bool ScTable::SetRowHidden(SCROW nStartRow, SCROW nEndRow, bool bHidden) else bChanged = mpHiddenRows->setFalse(nStartRow, nEndRow); + std::vector<SdrObject*> aRowDrawObjects; + ScDrawLayer* pDrawLayer = pDocument->GetDrawLayer(); + if (pDrawLayer) { + aRowDrawObjects = pDrawLayer->GetObjectsAnchoredToRows(GetTab(), nStartRow, nEndRow); + for (auto aObj : aRowDrawObjects) + { + aObj->SetVisible(!bHidden); + } + } + if (bChanged) { if (IsStreamValid()) diff --git a/sc/source/ui/view/drawvie3.cxx b/sc/source/ui/view/drawvie3.cxx index 8ac6455e26b7..6b0d68f379e4 100644 --- a/sc/source/ui/view/drawvie3.cxx +++ b/sc/source/ui/view/drawvie3.cxx @@ -159,7 +159,7 @@ void adjustAnchoredPosition(const SdrHint& rHint, const ScDocument& rDoc, SCTAB if (pAnchor->meType == ScDrawObjData::CellNote) return; - if (pAnchor->maLastRect == pObj->GetSnapRect()) + if (pAnchor->getShapeRect() == pObj->GetSnapRect()) return; if (pAnchor->maStart.Tab() != nTab) commit b1fc4d35ab6adddb1e01f279eda55731632d7fa8 Author: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> Date: Thu Mar 8 18:08:16 2018 +0100 Remove warning "No DrawLayer available" This warning appears very often in unit tests. We have similiar checks all over the place and don't emit a warning either. Change-Id: Ic1667fa51ce39e72c9a940023cc12a72458bd490 Reviewed-on: https://gerrit.libreoffice.org/50968 Tested-by: Jenkins <c...@libreoffice.org> Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@cib.de> (cherry picked from commit daf17846789cf09d1861f1e6f03851d2e12cffc8) diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx index 8abddc6ac1a7..91d3249deb57 100644 --- a/sc/source/core/data/table3.cxx +++ b/sc/source/core/data/table3.cxx @@ -439,8 +439,6 @@ void initDataRows( ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer(); if (pDrawLayer) aRowDrawObjects = pDrawLayer->GetObjectsAnchoredToRange(rTab.GetTab(), nCol, nRow1, nRow2); - else - SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available"); for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow) { _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits