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

Reply via email to