[Libreoffice-commits] core.git: Branch 'private/swe/libreoffice-5-2+backports' - 8 commits - sc/inc sc/qa sc/sdi sc/source sc/uiconfig

Samuel Mehrbrodt Samuel.Mehrbrodt at cib.de
Tue Jan 30 08:12:48 UTC 2018


 sc/inc/column.hxx                       |   11 ++-
 sc/inc/document.hxx                     |    8 ++
 sc/inc/drwlayer.hxx                     |    5 -
 sc/inc/sc.hrc                           |    1 
 sc/inc/sortparam.hxx                    |    1 
 sc/inc/table.hxx                        |    6 +
 sc/qa/unit/ucalc.hxx                    |    2 
 sc/qa/unit/ucalc_sort.cxx               |   64 ++++++++++++++++++
 sc/sdi/scalc.sdi                        |    2 
 sc/source/core/data/column.cxx          |   52 ++++++++------
 sc/source/core/data/column2.cxx         |   18 ++++-
 sc/source/core/data/column4.cxx         |   20 +++++
 sc/source/core/data/document.cxx        |    5 -
 sc/source/core/data/drwlayer.cxx        |   68 +++++++++++++++++--
 sc/source/core/data/sortparam.cxx       |    8 +-
 sc/source/core/data/table1.cxx          |   22 ++++--
 sc/source/core/data/table3.cxx          |   18 ++---
 sc/source/ui/dbgui/tpsort.cxx           |    4 +
 sc/source/ui/docshell/dbdocfun.cxx      |    3 
 sc/source/ui/inc/tpsort.hxx             |    2 
 sc/source/ui/view/cellsh2.cxx           |    5 +
 sc/source/ui/view/gridwin.cxx           |    1 
 sc/uiconfig/scalc/ui/sortoptionspage.ui |  111 ++++++++++++++++----------------
 23 files changed, 318 insertions(+), 119 deletions(-)

New commits:
commit 50dbe5e08b917f3715822d3422fb6eec26de95f9
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jan 23 14:22:59 2018 +0100

    Improve performance when looking for draw objects anchored to cells
    
    Look for a whole column at once so we don't have to iterate all draw objects
    for every cell, but only once per column.
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Change-Id: Ic8740fca7d595528785b432c1cedf4fad4f13ba1

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index 28a272912354..8be1d5422b3e 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -182,8 +182,8 @@ public:
     static void             SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
     static void             UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
-    std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos) const;
-    bool                    HasObjectsAnchoredInRange(ScRange& rRange) const;
+    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);
 
     // positions for detektive lines
diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index 9dac356f0ffc..beb2502c180f 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -1954,8 +1954,9 @@ void Test::testSortImages()
     ScAddress aCellPos(1, 1, 0);
     pDrawLayer->MoveObject(pObj, aCellPos);
 
-    std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    std::map<SCROW, std::vector<SdrObject*>> pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
 
     ScSortParam aSortData;
     aSortData.nCol1 = 0;
@@ -1973,8 +1974,9 @@ void Test::testSortImages()
 
     // check that note is also moved after sorting
     aCellPos = ScAddress(1, 0, 0);
-    pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+    pRowObjects
+        = pDrawLayer->GetObjectsAnchoredToRange(aCellPos.Tab(), aCellPos.Col(), aCellPos.Row(), aCellPos.Row());
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pRowObjects[aCellPos.Row()].size());
 
     m_pDoc->DeleteTab(0);
 }
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index aac576350017..57f9e152c5c3 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1005,16 +1005,18 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
     ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
     if (pDrawLayer)
     {
+        std::map<SCROW, std::vector<SdrObject*>> aThisColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), GetCol(), nRow1, nRow2);
+        std::map<SCROW, std::vector<SdrObject*>> aOtherColRowDrawObjects
+            = pDrawLayer->GetObjectsAnchoredToRange(GetTab(), rOther.GetCol(), nRow1, nRow2);
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
         {
-            ScAddress aThisCellPos(GetCol(), nRow, GetTab());
-            ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
-            std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
-            std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
-            if (!pThisColObjects.empty())
-                UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow);
-            if (!pOtherColObjects.empty())
-                rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
+            std::vector<SdrObject*>& aThisCellDrawObjects = aThisColRowDrawObjects[nRow];
+            if (!aThisCellDrawObjects.empty())
+                UpdateDrawObjectsForRow(aThisCellDrawObjects, rOther.GetCol(), nRow);
+            std::vector<SdrObject*>& aOtherCellDrawObjects = aOtherColRowDrawObjects[nRow];
+            if (!aOtherCellDrawObjects.empty())
+                rOther.UpdateDrawObjectsForRow(aOtherCellDrawObjects, GetCol(), nRow);
         }
     }
 
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 9a16554d7423..4c0773186e61 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1977,27 +1977,28 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
     return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
 }
 
-std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& rCell) const
+std::map<SCROW, std::vector<SdrObject*>>
+ScDrawLayer::GetObjectsAnchoredToRange(SCTAB nTab, SCCOL nCol, SCROW nStartRow, SCROW nEndRow) const
 {
-    const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab()));
+    const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
     if (!pPage || pPage->GetObjCount() < 1)
-        return std::vector<SdrObject*>();
+        return std::map<SCROW, std::vector<SdrObject*>>();
 
-    std::vector<SdrObject*> pObjects;
+    std::map<SCROW, std::vector<SdrObject*>> aRowObjects;
     SdrObjListIter aIter( *pPage, IM_FLAT );
     SdrObject* pObject = aIter.Next();
-    ScDrawObjData* pObjData;
+    ScRange aRange( nCol, nStartRow, nTab, nCol, nEndRow, nTab);
     while (pObject)
     {
         if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
         {
-            pObjData = GetObjData(pObject);
-            if (pObjData && pObjData->maStart == rCell) // Object is anchored to this cell
-                pObjects.push_back(pObject);
+            ScDrawObjData* pObjData = GetObjData(pObject);
+            if (aRange.In(pObjData->maStart))
+                aRowObjects[pObjData->maStart.Row()].push_back(pObject);
         }
         pObject = aIter.Next();
     }
-    return pObjects;
+    return aRowObjects;
 }
 
 bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange) const
diff --git a/sc/source/core/data/table3.cxx b/sc/source/core/data/table3.cxx
index 509731d0eff0..8abddc6ac1a7 100644
--- a/sc/source/core/data/table3.cxx
+++ b/sc/source/core/data/table3.cxx
@@ -435,6 +435,13 @@ void initDataRows(
 
         sc::ColumnBlockConstPosition aBlockPos;
         rCol.InitBlockPosition(aBlockPos);
+        std::map<SCROW, std::vector<SdrObject*>> aRowDrawObjects;
+        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)
         {
             ScSortInfoArray::Row& rRow = *rRows[nRow-nRow1];
@@ -442,17 +449,8 @@ void initDataRows(
             rCell.maCell = rCol.GetCellValue(aBlockPos, nRow);
             rCell.mpAttr = rCol.GetCellTextAttr(aBlockPos, nRow);
             rCell.mpNote = rCol.GetCellNote(aBlockPos, nRow);
-            ScDrawLayer* pDrawLayer = rTab.GetDoc().GetDrawLayer();
             if (pDrawLayer)
-            {
-                ScAddress aCellPos(nCol, nRow, rTab.GetTab());
-                std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
-                rCell.maDrawObjects = pObjects;
-            }
-            else
-            {
-                SAL_WARN("sc", "Could not retrieve anchored images, no DrawLayer available");
-            }
+                rCell.maDrawObjects = aRowDrawObjects[nRow];
 
             if (!bUniformPattern && bPattern)
                 rCell.mpPattern = rCol.GetPattern(nRow);
commit 39cff64e59aa20b4bb7b12abf0a2828638062b99
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Jan 26 22:54:50 2018 +0100

    Move declaration to where it is used
    
    Change-Id: Ibf650c3d38ff21cb03b5361f953423fd0d2195e6
    (cherry picked from commit 3edf52796ef62c1734f51011fd32d8dc269fbf2d)

diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 93c96b7893ee..9a16554d7423 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -2011,12 +2011,11 @@ bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange) const
 
     SdrObjListIter aIter( *pPage, IM_FLAT );
     SdrObject* pObject = aIter.Next();
-    ScDrawObjData* pObjData;
     while (pObject)
     {
         if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
         {
-            pObjData = GetObjData(pObject);
+            ScDrawObjData* pObjData = GetObjData(pObject);
             if (pObjData && rRange.In(pObjData->maStart)) // Object is in given range
                 return true;
         }
commit 0c8c8c6d042c4252bd2af5b228132e2c1ad35e0d
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jan 23 11:22:27 2018 +0100

    Improve performance when searching for blocks w/o draw objects
    
    ... by returning when the first object in the lookup range has been found
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Reviewed-on: https://gerrit.libreoffice.org/48395
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 401d4516234994d317a7c899358e8c2eef447fdc)
    
    Change-Id: I5cc9a268793eb8d156a39b0a2de557220da96748

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index e2762b437e1f..28a272912354 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -183,6 +183,7 @@ public:
     static void             UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
     std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos) const;
+    bool                    HasObjectsAnchoredInRange(ScRange& rRange) const;
     void MoveObject(SdrObject* pObj, ScAddress& rNewPosition);
 
     // positions for detektive lines
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 62d83878301a..ccd823001475 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1932,13 +1932,8 @@ bool ScColumn::IsDrawObjectsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const
     if (!pDrawLayer)
         return true;
 
-    for (SCROW nCurrentRow = nStartRow; nCurrentRow <= nEndRow; nCurrentRow++)
-    {
-        ScAddress aCell(nCol, nCurrentRow, nTab);
-        if (!pDrawLayer->GetObjectsAnchoredToCell(aCell).empty())
-            return false;
-    }
-    return true;
+    ScRange aRange(nCol, nStartRow, nTab, nCol, nEndRow, nTab);
+    return !pDrawLayer->HasObjectsAnchoredInRange(aRange);
 }
 
 void ScColumn::SwapCol(ScColumn& rCol)
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 0d68c509e44b..93c96b7893ee 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -2000,6 +2000,31 @@ std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& r
     return pObjects;
 }
 
+bool ScDrawLayer::HasObjectsAnchoredInRange(ScRange& rRange) const
+{
+    // This only works for one table at a time
+    assert(rRange.aStart.Tab() == rRange.aEnd.Tab());
+
+    const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rRange.aStart.Tab()));
+    if (!pPage || pPage->GetObjCount() < 1)
+        return false;
+
+    SdrObjListIter aIter( *pPage, IM_FLAT );
+    SdrObject* pObject = aIter.Next();
+    ScDrawObjData* pObjData;
+    while (pObject)
+    {
+        if (!dynamic_cast<SdrCaptionObj*>(pObject)) // Caption objects are handled differently
+        {
+            pObjData = GetObjData(pObject);
+            if (pObjData && rRange.In(pObjData->maStart)) // Object is in given range
+                return true;
+        }
+        pObject = aIter.Next();
+    }
+    return false;
+}
+
 void ScDrawLayer::MoveObject(SdrObject* pObject, ScAddress& rNewPosition)
 {
     // Get anchor data
commit e9935531cce663ec62912a4026e0a78c4f55c227
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Mon Jan 22 12:46:11 2018 +0100

    tdf#98931 Test for sorting images
    
    Reviewed-on: https://gerrit.libreoffice.org/48310
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 9f329c08e6b7e87879545c1bd78a4d3435fc44e4)
    
    Change-Id: Ia9bbdfefc4f8ef2948d497391cdc1e9c760f1f64

diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index adb4180cd9e9..e2762b437e1f 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -183,6 +183,7 @@ public:
     static void             UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
     std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos) const;
+    void MoveObject(SdrObject* pObj, ScAddress& rNewPosition);
 
     // positions for detektive lines
     static ScDrawObjData* GetObjData( SdrObject* pObj, bool bCreate=false );
diff --git a/sc/qa/unit/ucalc.hxx b/sc/qa/unit/ucalc.hxx
index 3aad1ec33aa8..4ffba3a86294 100644
--- a/sc/qa/unit/ucalc.hxx
+++ b/sc/qa/unit/ucalc.hxx
@@ -420,6 +420,7 @@ public:
     void testSortBroadcastBroadcaster();
     void testSortOutOfPlaceResult();
     void testSortPartialFormulaGroup();
+    void testSortImages();
 
     void testNoteBasic();
     void testNoteDeleteRow();
@@ -684,6 +685,7 @@ public:
     CPPUNIT_TEST(testSortBroadcastBroadcaster);
     CPPUNIT_TEST(testSortOutOfPlaceResult);
     CPPUNIT_TEST(testSortPartialFormulaGroup);
+    CPPUNIT_TEST(testSortImages);
     CPPUNIT_TEST(testShiftCells);
     CPPUNIT_TEST(testNoteBasic);
     CPPUNIT_TEST(testNoteDeleteRow);
diff --git a/sc/qa/unit/ucalc_sort.cxx b/sc/qa/unit/ucalc_sort.cxx
index 59293ba21a92..9dac356f0ffc 100644
--- a/sc/qa/unit/ucalc_sort.cxx
+++ b/sc/qa/unit/ucalc_sort.cxx
@@ -21,10 +21,13 @@
 #include <docfunc.hxx>
 #include <scitems.hxx>
 #include <editutil.hxx>
+#include <table.hxx>
 
 #include <sal/config.h>
 #include <editeng/wghtitem.hxx>
 #include <editeng/postitem.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdpage.hxx>
 #include <test/bootstrapfixture.hxx>
 
 void Test::testSort()
@@ -1917,4 +1920,63 @@ void Test::testSortPartialFormulaGroup()
     m_pDoc->DeleteTab(0);
 }
 
+void Test::testSortImages()
+{
+    m_pDoc->InsertTab(0, "testSortImages");
+
+    // We need a drawing layer in order to create caption objects.
+    m_pDoc->InitDrawLayer(&getDocShell());
+    ScDrawLayer* pDrawLayer = m_pDoc->GetDrawLayer();
+    CPPUNIT_ASSERT(pDrawLayer);
+
+    ScRange aDataRange;
+    ScAddress aPos(0,0,0);
+    {
+        const char* aData[][1] = {
+            { "2" },
+            { "1" },
+        };
+
+        clearRange(m_pDoc, ScRange(0, 0, 0, 1, SAL_N_ELEMENTS(aData), 0));
+        aDataRange = insertRangeData(m_pDoc, aPos, aData, SAL_N_ELEMENTS(aData));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("failed to insert range data at correct position", aPos, aDataRange.aStart);
+    }
+
+    // Insert graphic in cell B2.
+    const Rectangle aOrigRect = Rectangle(1000, 1000, 1200, 1200);
+    SdrCircObj* pObj = new SdrCircObj(OBJ_CIRC, aOrigRect);
+    SdrPage* pPage = pDrawLayer->GetPage(0);
+    CPPUNIT_ASSERT(pPage);
+    pPage->InsertObject(pObj);
+    // Anchor to cell
+    ScDrawLayer::SetCellAnchoredFromPosition(*pObj, *m_pDoc, 0);
+    // Move to cell B2
+    ScAddress aCellPos(1, 1, 0);
+    pDrawLayer->MoveObject(pObj, aCellPos);
+
+    std::vector<SdrObject*> pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+
+    ScSortParam aSortData;
+    aSortData.nCol1 = 0;
+    aSortData.nCol2 = 1;
+    aSortData.nRow1 = 0;
+    aSortData.nRow2 = 1;
+    aSortData.maKeyState[0].bDoSort = true;
+    aSortData.maKeyState[0].nField = 0;
+    aSortData.maKeyState[0].bAscending = true;
+
+    m_pDoc->Sort(0, aSortData, false, true, nullptr, nullptr);
+
+    double nVal = m_pDoc->GetValue(0,0,0);
+    ASSERT_DOUBLES_EQUAL(nVal, 1.0);
+
+    // check that note is also moved after sorting
+    aCellPos = ScAddress(1, 0, 0);
+    pObjects = pDrawLayer->GetObjectsAnchoredToCell(aCellPos);
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pObjects.size());
+
+    m_pDoc->DeleteTab(0);
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index b77020425eb3..62d83878301a 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1917,29 +1917,12 @@ void ScColumn::UpdateDrawObjectsForRow( std::vector<SdrObject*>& pObjects, SCCOL
 {
     for (auto &pObject : pObjects)
     {
-        // Get anchor data
-        ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pObject, false);
-        if (!pObjData)
-            continue;
-        const ScAddress aOldStart = pObjData->maStart;
-        const ScAddress aOldEnd = pObjData->maEnd;
-
-        // Set start address
-        ScAddress aNewStart = ScAddress(nTargetCol, nTargetRow, nTab);
-        pObjData->maStart = aNewStart;
-
-        // Set end address
-        const SCCOL nObjectColSpan = aOldEnd.Col() - aOldStart.Col();
-        const SCROW nObjectRowSpan = aOldEnd.Row() - aOldStart.Row();
-        ScAddress aNewEnd = aNewStart;
-        aNewEnd.IncRow(nObjectRowSpan);
-        aNewEnd.IncCol(nObjectColSpan);
-        pObjData->maEnd = aNewEnd;
+        ScAddress aNewAddress = ScAddress(nTargetCol, nTargetRow, nTab);
 
         // Update draw object according to new anchor
         ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
         if (pDrawLayer)
-            pDrawLayer->RecalcPos(pObject, *pObjData, false, false);
+            pDrawLayer->MoveObject(pObject, aNewAddress);
     }
 }
 
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 87b44b7d7234..0d68c509e44b 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -2000,6 +2000,30 @@ std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& r
     return pObjects;
 }
 
+void ScDrawLayer::MoveObject(SdrObject* pObject, ScAddress& rNewPosition)
+{
+    // Get anchor data
+    ScDrawObjData* pObjData = GetObjData(pObject, false);
+    if (!pObjData)
+        return;
+    const ScAddress aOldStart = pObjData->maStart;
+    const ScAddress aOldEnd = pObjData->maEnd;
+
+    // Set start address
+    pObjData->maStart = rNewPosition;
+
+    // Set end address
+    const SCCOL nObjectColSpan = aOldEnd.Col() - aOldStart.Col();
+    const SCROW nObjectRowSpan = aOldEnd.Row() - aOldStart.Row();
+    ScAddress aNewEnd = rNewPosition;
+    aNewEnd.IncRow(nObjectRowSpan);
+    aNewEnd.IncCol(nObjectColSpan);
+    pObjData->maEnd = aNewEnd;
+
+    // Update draw object according to new anchor
+    RecalcPos(pObject, *pObjData, false, false);
+}
+
 ScDrawObjData* ScDrawLayer::GetNonRotatedObjData( SdrObject* pObj, bool bCreate )
 {
     sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
commit f92fd273e0319b18ab9b453b5ce753b865b37a1f
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Mon Jan 22 17:47:04 2018 +0100

    tdf#98931 Add option to sort boundary image-only columns
    
    A similiar option exists for comments-only columns.
    If enabled, image-only columns are considered when sorting (and selected).
    
    This is the default behavior, but can now be disabled.
    
    Reviewed-on: https://gerrit.libreoffice.org/48351
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit b5f8b046008a27f1da58b934dbe61c0decf36612)
    
    Change-Id: Ie9dfdf913ea5904480c96375beb4e25bcb880785

diff --git a/sc/inc/sc.hrc b/sc/inc/sc.hrc
index 8395c2366ff0..126ebb12e456 100644
--- a/sc/inc/sc.hrc
+++ b/sc/inc/sc.hrc
@@ -684,6 +684,7 @@
 #define SID_SORT_ATTRIBS        (SC_PARAM_START+3)
 #define SID_SORT_USERDEF        (SC_PARAM_START+4)
 #define SID_SORT_NATURALSORT    (SC_PARAM_START+5)
+#define SID_SORT_INCIMAGES      (SC_PARAM_START+6)
 
 // Sidebar -------------------------------------------------------------
 
diff --git a/sc/inc/sortparam.hxx b/sc/inc/sortparam.hxx
index 268b14c03c25..ab159497c476 100644
--- a/sc/inc/sortparam.hxx
+++ b/sc/inc/sortparam.hxx
@@ -49,6 +49,7 @@ struct SC_DLLPUBLIC ScSortParam
     bool        bByRow;
     bool        bCaseSens;
     bool        bNaturalSort;
+    bool        bIncludeGraphicObjects;
     bool        bUserDef;
     bool        bIncludePattern;
     bool        bInplace;
diff --git a/sc/sdi/scalc.sdi b/sc/sdi/scalc.sdi
index 14169f0757a5..407de11e1b1c 100644
--- a/sc/sdi/scalc.sdi
+++ b/sc/sdi/scalc.sdi
@@ -1245,7 +1245,7 @@ SfxVoidItem DataSelect SID_DATA_SELECT
 
 
 SfxVoidItem DataSort SID_SORT
-(SfxBoolItem ByRows SID_SORT_BYROW,SfxBoolItem HasHeader SID_SORT_HASHEADER,SfxBoolItem CaseSensitive SID_SORT_CASESENS,SfxBoolItem NaturalSort SID_SORT_NATURALSORT,SfxBoolItem IncludeAttribs SID_SORT_ATTRIBS,SfxUInt16Item UserDefIndex SID_SORT_USERDEF,SfxInt32Item Col1 FN_PARAM_1,SfxBoolItem Ascending1 FN_PARAM_2,SfxInt32Item Col2 FN_PARAM_3,SfxBoolItem Ascending2 FN_PARAM_4,SfxInt32Item Col3 FN_PARAM_5,SfxBoolItem Ascending3 FN_PARAM_6)
+(SfxBoolItem ByRows SID_SORT_BYROW,SfxBoolItem HasHeader SID_SORT_HASHEADER,SfxBoolItem CaseSensitive SID_SORT_CASESENS,SfxBoolItem NaturalSort SID_SORT_NATURALSORT,SfxBoolItem IncludeAttribs SID_SORT_ATTRIBS,SfxUInt16Item UserDefIndex SID_SORT_USERDEF,SfxInt32Item Col1 FN_PARAM_1,SfxBoolItem Ascending1 FN_PARAM_2,SfxInt32Item Col2 FN_PARAM_3,SfxBoolItem Ascending2 FN_PARAM_4,SfxInt32Item Col3 FN_PARAM_5,SfxBoolItem Ascending3 FN_PARAM_6, SfxBoolItem IncludeImages SID_SORT_INCIMAGES)
 [
     AutoUpdate = FALSE,
     FastCall = FALSE,
diff --git a/sc/source/core/data/sortparam.cxx b/sc/source/core/data/sortparam.cxx
index 0f7c158e6cb1..f55fc42b86ca 100644
--- a/sc/source/core/data/sortparam.cxx
+++ b/sc/source/core/data/sortparam.cxx
@@ -35,7 +35,7 @@ ScSortParam::ScSortParam()
 ScSortParam::ScSortParam( const ScSortParam& r ) :
         nCol1(r.nCol1),nRow1(r.nRow1),nCol2(r.nCol2),nRow2(r.nRow2),nUserIndex(r.nUserIndex),
         bHasHeader(r.bHasHeader),bByRow(r.bByRow),bCaseSens(r.bCaseSens),
-        bNaturalSort(r.bNaturalSort),bUserDef(r.bUserDef),
+        bNaturalSort(r.bNaturalSort),bUserDef(r.bUserDef),bIncludeGraphicObjects(r.bIncludeGraphicObjects),
         bIncludePattern(r.bIncludePattern),bInplace(r.bInplace),
         nDestTab(r.nDestTab),nDestCol(r.nDestCol),nDestRow(r.nDestRow),
         maKeyState( r.maKeyState ),
@@ -56,6 +56,7 @@ void ScSortParam::Clear()
     nDestTab = 0;
     nUserIndex = 0;
     bHasHeader=bCaseSens=bUserDef=bNaturalSort = false;
+    bIncludeGraphicObjects = true;
     bByRow=bIncludePattern=bInplace = true;
     aCollatorLocale = css::lang::Locale();
     aCollatorAlgorithm.clear();
@@ -79,6 +80,7 @@ ScSortParam& ScSortParam::operator=( const ScSortParam& r )
     bByRow          = r.bByRow;
     bCaseSens       = r.bCaseSens;
     bNaturalSort    = r.bNaturalSort;
+    bIncludeGraphicObjects = r.bIncludeGraphicObjects;
     bUserDef        = r.bUserDef;
     bIncludePattern = r.bIncludePattern;
     bInplace        = r.bInplace;
@@ -122,6 +124,7 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
         && (bByRow          == rOther.bByRow)
         && (bCaseSens       == rOther.bCaseSens)
         && (bNaturalSort    == rOther.bNaturalSort)
+        && (bIncludeGraphicObjects == rOther.bIncludeGraphicObjects)
         && (bUserDef        == rOther.bUserDef)
         && (nUserIndex      == rOther.nUserIndex)
         && (bIncludePattern == rOther.bIncludePattern)
@@ -150,6 +153,7 @@ bool ScSortParam::operator==( const ScSortParam& rOther ) const
 ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld ) :
         nCol1(rSub.nCol1),nRow1(rSub.nRow1),nCol2(rSub.nCol2),nRow2(rSub.nRow2),nUserIndex(rSub.nUserIndex),
         bHasHeader(true),bByRow(true),bCaseSens(rSub.bCaseSens),bNaturalSort(rOld.bNaturalSort),
+        bIncludeGraphicObjects(rOld.bIncludeGraphicObjects),
         bUserDef(rSub.bUserDef),bIncludePattern(rSub.bIncludePattern),
         bInplace(true),
         nDestTab(0),nDestCol(0),nDestRow(0),
@@ -193,7 +197,7 @@ ScSortParam::ScSortParam( const ScSubTotalParam& rSub, const ScSortParam& rOld )
 ScSortParam::ScSortParam( const ScQueryParam& rParam, SCCOL nCol ) :
         nCol1(nCol),nRow1(rParam.nRow1),nCol2(nCol),nRow2(rParam.nRow2),nUserIndex(0),
         bHasHeader(rParam.bHasHeader),bByRow(true),bCaseSens(rParam.bCaseSens),
-        bNaturalSort(false),
+        bNaturalSort(false),bIncludeGraphicObjects(true),
 //TODO: what about Locale and Algorithm?
         bUserDef(false),bIncludePattern(false),
         bInplace(true),
diff --git a/sc/source/ui/dbgui/tpsort.cxx b/sc/source/ui/dbgui/tpsort.cxx
index 3b5d4023b375..408631638e3f 100644
--- a/sc/source/ui/dbgui/tpsort.cxx
+++ b/sc/source/ui/dbgui/tpsort.cxx
@@ -507,6 +507,7 @@ ScTabPageSortOptions::ScTabPageSortOptions( vcl::Window*             pParent,
     get(m_pBtnHeader, "header");
     get(m_pBtnFormats, "formats");
     get(m_pBtnNaturalSort, "naturalsort");
+    get(m_pBtnIncImages, "includeimages");
     get(m_pBtnCopyResult, "copyresult");
     get(m_pLbOutPos, "outarealb");
     get(m_pEdOutPos, "outareaed");
@@ -543,6 +544,7 @@ void ScTabPageSortOptions::dispose()
     m_pBtnHeader.clear();
     m_pBtnFormats.clear();
     m_pBtnNaturalSort.clear();
+    m_pBtnIncImages.clear();
     m_pBtnCopyResult.clear();
     m_pLbOutPos.clear();
     m_pEdOutPos.clear();
@@ -664,6 +666,7 @@ void ScTabPageSortOptions::Reset( const SfxItemSet* /* rArgSet */ )
     m_pBtnFormats->Check       ( aSortData.bIncludePattern );
     m_pBtnHeader->Check        ( aSortData.bHasHeader );
     m_pBtnNaturalSort->Check   ( aSortData.bNaturalSort );
+    m_pBtnIncImages->Check     ( aSortData.bIncludeGraphicObjects );
 
     if ( aSortData.bByRow )
     {
@@ -728,6 +731,7 @@ bool ScTabPageSortOptions::FillItemSet( SfxItemSet* rArgSet )
     aNewSortData.bHasHeader      = m_pBtnHeader->IsChecked();
     aNewSortData.bCaseSens       = m_pBtnCase->IsChecked();
     aNewSortData.bNaturalSort    = m_pBtnNaturalSort->IsChecked();
+    aNewSortData.bIncludeGraphicObjects = m_pBtnIncImages->IsChecked();
     aNewSortData.bIncludePattern = m_pBtnFormats->IsChecked();
     aNewSortData.bInplace        = !m_pBtnCopyResult->IsChecked();
     aNewSortData.nDestCol        = theOutPos.Col();
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index 996ddf726cfd..e924947b442c 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -514,7 +514,7 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     bool bShrunk = false;
     rDoc.ShrinkToUsedDataArea( bShrunk, nTab, aLocalParam.nCol1, aLocalParam.nRow1,
             aLocalParam.nCol2, aLocalParam.nRow2, false, aLocalParam.bByRow, !aLocalParam.bByRow,
-            false, true );
+            false, aLocalParam.bIncludeGraphicObjects );
 
     SCROW nStartRow = aLocalParam.nRow1;
     if (aLocalParam.bByRow && aLocalParam.bHasHeader && nStartRow < aLocalParam.nRow2)
diff --git a/sc/source/ui/inc/tpsort.hxx b/sc/source/ui/inc/tpsort.hxx
index f777f74e5666..3164861fc945 100644
--- a/sc/source/ui/inc/tpsort.hxx
+++ b/sc/source/ui/inc/tpsort.hxx
@@ -145,6 +145,8 @@ private:
     VclPtr<RadioButton>        m_pBtnTopDown;
     VclPtr<RadioButton>        m_pBtnLeftRight;
 
+    VclPtr<CheckBox>           m_pBtnIncImages;
+
     OUString            aStrRowLabel;
     OUString            aStrColLabel;
     OUString            aStrUndefined;
diff --git a/sc/source/ui/view/cellsh2.cxx b/sc/source/ui/view/cellsh2.cxx
index e85e36942e11..10e7c5e43b82 100644
--- a/sc/source/ui/view/cellsh2.cxx
+++ b/sc/source/ui/view/cellsh2.cxx
@@ -379,6 +379,7 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                     aSortParam.bByRow           = true;
                     aSortParam.bCaseSens        = false;
                     aSortParam.bNaturalSort     = false;
+                    aSortParam.bIncludeGraphicObjects = true;
                     aSortParam.bIncludePattern  = true;
                     aSortParam.bInplace         = true;
                     aSortParam.maKeyState[0].bDoSort = true;
@@ -432,6 +433,8 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                             aSortParam.bCaseSens = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_NATURALSORT, true, &pItem ) == SfxItemState::SET )
                             aSortParam.bNaturalSort = static_cast<const SfxBoolItem*>(pItem)->GetValue();
+                        if ( pArgs->GetItemState( SID_SORT_INCIMAGES, true, &pItem ) == SfxItemState::SET )
+                            aSortParam.bIncludeGraphicObjects = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_ATTRIBS, true, &pItem ) == SfxItemState::SET )
                             aSortParam.bIncludePattern = static_cast<const SfxBoolItem*>(pItem)->GetValue();
                         if ( pArgs->GetItemState( SID_SORT_USERDEF, true, &pItem ) == SfxItemState::SET )
@@ -516,6 +519,8 @@ void ScCellShell::ExecuteDB( SfxRequest& rReq )
                                     rOutParam.bCaseSens ) );
                                 rReq.AppendItem( SfxBoolItem( SID_SORT_NATURALSORT,
                                             rOutParam.bNaturalSort ) );
+                                rReq.AppendItem( SfxBoolItem( SID_SORT_INCIMAGES,
+                                            rOutParam.bIncludeGraphicObjects ) );
                                 rReq.AppendItem( SfxBoolItem( SID_SORT_ATTRIBS,
                                     rOutParam.bIncludePattern ) );
                                 sal_uInt16 nUser = rOutParam.bUserDef ? ( rOutParam.nUserIndex + 1 ) : 0;
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 1af4606a1c94..52dd3383eff5 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -810,6 +810,7 @@ void ScGridWindow::UpdateAutoFilterFromMenu(AutoFilterMode eMode)
             aSortParam.bByRow = true;
             aSortParam.bCaseSens = false;
             aSortParam.bNaturalSort = false;
+            aSortParam.bIncludeGraphicObjects = true;
             aSortParam.bIncludePattern = true;
             aSortParam.bInplace = true;
             aSortParam.maKeyState[0].bDoSort = true;
diff --git a/sc/uiconfig/scalc/ui/sortoptionspage.ui b/sc/uiconfig/scalc/ui/sortoptionspage.ui
index 44128d0e6910..0e3d2d1628f7 100644
--- a/sc/uiconfig/scalc/ui/sortoptionspage.ui
+++ b/sc/uiconfig/scalc/ui/sortoptionspage.ui
@@ -1,7 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<interface>
-  <!-- interface-requires gtk+ 3.0 -->
-  <!-- interface-requires LibreOffice 1.0 -->
+<!-- Generated with glade 3.20.0 -->
+<interface domain="sc">
+  <requires lib="gtk+" version="3.0"/>
+  <requires lib="LibreOffice" version="1.0"/>
   <object class="GtkBox" id="SortOptionsPage">
     <property name="visible">True</property>
     <property name="can_focus">False</property>
@@ -28,7 +29,7 @@
                 <property name="column_spacing">12</property>
                 <child>
                   <object class="GtkCheckButton" id="case">
-                    <property name="label" translatable="yes">Case _sensitive</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|case">Case _sensitive</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -39,13 +40,11 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkCheckButton" id="header">
-                    <property name="label" translatable="yes">Range contains...</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|header">Range contains...</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -55,13 +54,11 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkCheckButton" id="formats">
-                    <property name="label" translatable="yes">Include formats</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|formats">Include formats</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -71,13 +68,11 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">2</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkCheckButton" id="naturalsort">
-                    <property name="label" translatable="yes">Enable natural sort</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|naturalsort">Enable natural sort</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -87,13 +82,25 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">3</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkCheckButton" id="includeimages">
+                    <property name="label" translatable="yes" context="sortoptionspage|includeimages">Include boundary column(s) containing only images</property>
+                    <property name="visible">True</property>
+                    <property name="can_focus">True</property>
+                    <property name="receives_default">False</property>
+                    <property name="xalign">0</property>
+                    <property name="draw_indicator">True</property>
+                  </object>
+                  <packing>
+                    <property name="left_attach">0</property>
+                    <property name="top_attach">4</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkCheckButton" id="copyresult">
-                    <property name="label" translatable="yes">Copy sort results to:</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|copyresult">Copy sort results to:</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -105,9 +112,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">4</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">5</property>
                   </packing>
                 </child>
                 <child>
@@ -119,12 +124,15 @@
                       <relation type="labelled-by" target="copyresult"/>
                       <relation type="label-for" target="outareaed"/>
                     </accessibility>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="outarealb-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes">Copy sort results to:</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">6</property>
                   </packing>
                 </child>
                 <child>
@@ -133,21 +141,23 @@
                     <property name="can_focus">True</property>
                     <property name="hexpand">True</property>
                     <property name="invisible_char">•</property>
-                    <property name="invisible_char_set">True</property>
                     <accessibility>
                       <relation type="labelled-by" target="outarealb"/>
                     </accessibility>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="outareaed-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes">Copy sort results to:</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">5</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">6</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkCheckButton" id="sortuser">
-                    <property name="label" translatable="yes">Custom sort order</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|sortuser">Custom sort order</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -159,9 +169,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">6</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">7</property>
                   </packing>
                 </child>
                 <child>
@@ -173,12 +181,16 @@
                     <accessibility>
                       <relation type="labelled-by" target="sortuser"/>
                     </accessibility>
+                    <child internal-child="accessible">
+                      <object class="AtkObject" id="sortuserlb-atkobject">
+                        <property name="AtkObject::accessible-name" translatable="yes" context="sortoptionspage|sortuserlb-atkobject">Custom sort order</property>
+                      </object>
+                    </child>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">7</property>
+                    <property name="top_attach">8</property>
                     <property name="width">2</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
@@ -186,15 +198,13 @@
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="label" translatable="yes">Language</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|label6">Language</property>
                     <property name="use_underline">True</property>
                     <property name="mnemonic_widget">language</property>
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">8</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">9</property>
                   </packing>
                 </child>
                 <child>
@@ -202,15 +212,13 @@
                     <property name="visible">True</property>
                     <property name="can_focus">False</property>
                     <property name="halign">start</property>
-                    <property name="label" translatable="yes">Options</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|algorithmft">Options</property>
                     <property name="use_underline">True</property>
                     <property name="mnemonic_widget">algorithmlb</property>
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">8</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">9</property>
                   </packing>
                 </child>
                 <child>
@@ -220,9 +228,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">0</property>
-                    <property name="top_attach">9</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">10</property>
                   </packing>
                 </child>
                 <child>
@@ -232,9 +238,7 @@
                   </object>
                   <packing>
                     <property name="left_attach">1</property>
-                    <property name="top_attach">9</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
+                    <property name="top_attach">10</property>
                   </packing>
                 </child>
                 <child>
@@ -255,6 +259,9 @@
                 <child>
                   <placeholder/>
                 </child>
+                <child>
+                  <placeholder/>
+                </child>
               </object>
             </child>
           </object>
@@ -263,7 +270,7 @@
           <object class="GtkLabel" id="label2">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="label" translatable="yes">Sort Options</property>
+            <property name="label" translatable="yes" context="sortoptionspage|label2">Sort Options</property>
             <attributes>
               <attribute name="weight" value="bold"/>
             </attributes>
@@ -294,7 +301,7 @@
                 <property name="can_focus">False</property>
                 <child>
                   <object class="GtkRadioButton" id="topdown">
-                    <property name="label" translatable="yes">_Top to bottom (sort rows)</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|topdown">_Top to bottom (sort rows)</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -307,13 +314,11 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">0</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
                 <child>
                   <object class="GtkRadioButton" id="leftright">
-                    <property name="label" translatable="yes">L_eft to right (sort columns)</property>
+                    <property name="label" translatable="yes" context="sortoptionspage|leftright">L_eft to right (sort columns)</property>
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
                     <property name="receives_default">False</property>
@@ -325,8 +330,6 @@
                   <packing>
                     <property name="left_attach">0</property>
                     <property name="top_attach">1</property>
-                    <property name="width">1</property>
-                    <property name="height">1</property>
                   </packing>
                 </child>
               </object>
@@ -337,7 +340,7 @@
           <object class="GtkLabel" id="label1">
             <property name="visible">True</property>
             <property name="can_focus">False</property>
-            <property name="label" translatable="yes">Direction</property>
+            <property name="label" translatable="yes" context="sortoptionspage|label1">Direction</property>
             <attributes>
               <attribute name="weight" value="bold"/>
             </attributes>
commit 947b9ce8283c5d17ea282ed45d294d13c27b3193
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jan 23 10:11:16 2018 +0100

    Updating images should not depend on unrelated condition
    
    Instead update them unconditionally as it is done with comments.
    
    The data range has been set beforehand (considering the option
    to include boundary columns with images only) so at this point
    the swapping should happen unconditionally.
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Reviewed-on: https://gerrit.libreoffice.org/48383
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    Tested-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    (cherry picked from commit cf847a7287148304afe98f0efe68cdf9617d4e44)
    
    Change-Id: I1d75dd6e22db5cc28aa45f7b86dab013f3595199

diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index b8a93b3b6d4b..aac576350017 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1001,6 +1001,23 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
     maCellNotes.swap(nRow1, nRow2, rOther.maCellNotes, nRow1);
     maBroadcasters.swap(nRow1, nRow2, rOther.maBroadcasters, nRow1);
 
+    // Update draw object anchors
+    ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+    if (pDrawLayer)
+    {
+        for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
+        {
+            ScAddress aThisCellPos(GetCol(), nRow, GetTab());
+            ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
+            std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
+            std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
+            if (!pThisColObjects.empty())
+                UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow);
+            if (!pOtherColObjects.empty())
+                rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
+        }
+    }
+
     if (bPattern)
     {
         for (SCROW nRow = nRow1; nRow <= nRow2; ++nRow)
@@ -1012,21 +1029,6 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
                 SetPattern(nRow, *pPat2);
                 rOther.SetPattern(nRow, *pPat1);
             }
-
-            // Update draw object anchors
-            ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
-            if (pDrawLayer)
-            {
-                ScAddress aThisCellPos(GetCol(), nRow, GetTab());
-                ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
-                std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
-                std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
-                if (!pThisColObjects.empty())
-                    UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow);
-                if (!pOtherColObjects.empty())
-                    rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
-
-            }
         }
     }
 
commit b8b285b51ef51dda14d1f0e0526eda13879ab93f
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Tue Jan 23 10:10:11 2018 +0100

    Assert that parameters are valid
    
    Follow-up for 3a2a430ae8e2c1647c18d8904477949f6e2e7941
    
    Change-Id: I46a4f8a4528b73e4dcb01770af127ddea4000fdb
    Reviewed-on: https://gerrit.libreoffice.org/48382
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
    (cherry picked from commit f84c9164c5bfa438282c4264203163d4c6b7e689)

diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 66d8e9d4bec3..b77020425eb3 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1901,6 +1901,8 @@ void ScColumn::UpdateNoteCaptions( SCROW nRow1, SCROW nRow2 )
 
 void ScColumn::UpdateDrawObjects(std::vector<std::vector<SdrObject*>>& pObjects, SCROW nRowStart, SCROW nRowEnd)
 {
+    assert(static_cast<int>(pObjects.size()) >= nRowEnd - nRowStart + 1);
+
     int nObj = 0;
     for (SCROW nCurrentRow = nRowStart; nCurrentRow <= nRowEnd; nCurrentRow++, nObj++)
     {
commit d4a284a74eac1b2b0a712998c92a1e15451d1141
Author: Samuel Mehrbrodt <Samuel.Mehrbrodt at cib.de>
Date:   Mon Jan 29 10:57:32 2018 +0100

    tdf#98931 Consider cell-anchored images when sorting
    
    This makes images/draw objects anchored to cells move as any
    other content when sorting cells.
    
    Works for sorting rows and columns.
    
    Also fixes a bug where notes attached to cells were not sorted
    when sorting columns.
    
    Change-Id: Id9a56a15f776d5adbe382a9bca167bff48b69a0c
    Reviewed-on: https://gerrit.libreoffice.org/46838
    Tested-by: Jenkins <ci at libreoffice.org>
    Reviewed-by: Thorsten Behrens <Thorsten.Behrens at CIB.de>
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Eike Rathke <erack at redhat.com>
    (cherry picked from commit 3a2a430ae8e2c1647c18d8904477949f6e2e7941)
    
    The first part of this commit was already merged with efb190857650b2f2592be783a0e2997b8eeaf768

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 2188c539bf41..d0b52f329db4 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -221,11 +221,13 @@ public:
                 // data only:
     bool               IsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
     SCSIZE         GetEmptyLinesInBlock( SCROW nStartRow, SCROW nEndRow, ScDirection eDir ) const;
-    bool               HasDataAt(SCROW nRow) const;
+    bool        HasDataAt(SCROW nRow, bool bConsiderCellNotes=false,
+                          bool bConsiderCellDrawObjects=false) const;
     bool               HasVisibleDataAt(SCROW nRow) const;
     SCROW              GetFirstDataPos() const;
     SCROW              GetLastDataPos() const;
-    SCROW GetLastDataPos( SCROW nLastRow ) const;
+    SCROW       GetLastDataPos( SCROW nLastRow, bool bConsiderCellNotes=false,
+                                bool bConsiderCellDrawObjects=false ) const;
     bool               GetPrevDataPos(SCROW& rRow) const;
     bool               GetNextDataPos(SCROW& rRow) const;
     void               FindDataAreaPos(SCROW& rRow, bool bDown) const; // (without Broadcaster)
@@ -609,7 +611,10 @@ public:
                             sc::ColumnBlockPosition& maDestBlockPos, bool bCloneCaption = true, SCROW nRowOffsetDest=0 ) const;
 
     void UpdateNoteCaptions( SCROW nRow1, SCROW nRow2 );
-    void UpdateDrawObjects( std::vector<std::vector<SdrObject*>> pObjects, SCROW nRowStart, SCROW nRowEnd );
+
+    void UpdateDrawObjects( std::vector<std::vector<SdrObject*>>& pObjects, SCROW nRowStart, SCROW nRowEnd );
+    void UpdateDrawObjectsForRow( std::vector<SdrObject*>& pObjects, SCCOL nTargetCol, SCROW nTargetRow );
+    bool IsDrawObjectsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const;
 
     void InterpretDirtyCells( SCROW nRow1, SCROW nRow2 );
 
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index e2fc8852dfcc..3f3eb17c5b88 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -1242,13 +1242,19 @@ public:
                                 If TRUE, do not adjust the top row.
                         @param  bStickyLeftCol
                                 If TRUE, do not adjust the left column.
+                        @param  bConsiderCellNotes
+                                If TRUE, consider the presence of cell notes besides data.
+                        @param  bConsiderCellDrawObjects
+                                If TRUE, consider the presence of draw objects anchored to the cell.
 
                         @returns true if there is any data, false if not.
                      */
     bool            ShrinkToUsedDataArea( bool& o_bShrunk,
                                           SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow,
                                           SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
-                                          bool bStickyTopRow = false, bool bStickyLeftCol = false ) const;
+                                          bool bStickyTopRow = false, bool bStickyLeftCol = false,
+                                          bool bConsiderCellNotes = false,
+                                          bool bConsiderCellDrawObjects = false ) const;
 
     /**
      * Return the last non-empty row position in given columns that's no
diff --git a/sc/inc/drwlayer.hxx b/sc/inc/drwlayer.hxx
index 64c8b1980c68..adb4180cd9e9 100644
--- a/sc/inc/drwlayer.hxx
+++ b/sc/inc/drwlayer.hxx
@@ -140,7 +140,6 @@ public:
 
     void            MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
                                 SCsCOL nDx,SCsROW nDy, bool bInsDel, bool bUpdateNoteCaptionPos = true );
-
     void            RecalcPos( SdrObject* pObj, ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos );
 
     bool            HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow );
@@ -183,7 +182,7 @@ public:
     static void             SetCellAnchoredFromPosition( SdrObject &rObj, const ScDocument &rDoc, SCTAB nTab );
     static void             UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect = true );
     static ScAnchorType     GetAnchorType( const SdrObject& );
-    std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos);
+    std::vector<SdrObject*> GetObjectsAnchoredToCell(const ScAddress& rPos) const;
 
     // positions for detektive lines
     static ScDrawObjData* GetObjData( SdrObject* pObj, bool bCreate=false );
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 4877f2be9835..b78adcc78971 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -505,9 +505,11 @@ public:
 
     bool        ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
                                       SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
-                                      bool bStickyTopRow, bool bStickyLeftCol ) const;
+                                      bool bStickyTopRow, bool bStickyLeftCol, bool bConsiderCellNotes,
+                                      bool bConsiderCellDrawObjects ) const;
 
-    SCROW GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const;
+    SCROW GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow,
+                         bool bConsiderCellNotes = false, bool bConsiderCellDrawObjects = false ) const;
 
     SCSIZE      GetEmptyLinesInBlock( SCCOL nStartCol, SCROW nStartRow,
                                         SCCOL nEndCol, SCROW nEndRow, ScDirection eDir ) const;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 91b078e37d9b..66d8e9d4bec3 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -1898,7 +1898,8 @@ void ScColumn::UpdateNoteCaptions( SCROW nRow1, SCROW nRow2 )
     NoteCaptionUpdater aFunc(nCol, nTab);
     sc::ProcessNote(maCellNotes.begin(), maCellNotes, nRow1, nRow2, aFunc);
 }
-void ScColumn::UpdateDrawObjects(std::vector<std::vector<SdrObject*>> pObjects, SCROW nRowStart, SCROW nRowEnd)
+
+void ScColumn::UpdateDrawObjects(std::vector<std::vector<SdrObject*>>& pObjects, SCROW nRowStart, SCROW nRowEnd)
 {
     int nObj = 0;
     for (SCROW nCurrentRow = nRowStart; nCurrentRow <= nRowEnd; nCurrentRow++, nObj++)
@@ -1906,32 +1907,55 @@ void ScColumn::UpdateDrawObjects(std::vector<std::vector<SdrObject*>> pObjects,
         if (pObjects[nObj].empty())
             continue; // No draw objects in this row
 
-        for (auto &pObject : pObjects[nObj])
-        {
-            // Get anchor data
-            ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pObject, false);
-            const ScAddress aOldStart = pObjData->maStart;
-            const ScAddress aOldEnd = pObjData->maEnd;
-
-            // Set start address
-            ScAddress aNewStart = ScAddress(nCol, nCurrentRow, nTab);
-            pObjData->maStart = aNewStart;
-
-            // Set end address
-            const SCCOL nObjectColSpan = aOldEnd.Col() - aOldStart.Col();
-            const SCROW nObjectRowSpan = aOldEnd.Row() - aOldStart.Row();
-            ScAddress aNewEnd = aNewStart;
-            aNewEnd.IncRow(nObjectRowSpan);
-            aNewEnd.IncCol(nObjectColSpan);
-            pObjData->maEnd = aNewEnd;
-
-            // Update draw object according to new anchor
-            ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+        UpdateDrawObjectsForRow(pObjects[nObj], nCol, nCurrentRow);
+    }
+}
+
+void ScColumn::UpdateDrawObjectsForRow( std::vector<SdrObject*>& pObjects, SCCOL nTargetCol, SCROW nTargetRow )
+{
+    for (auto &pObject : pObjects)
+    {
+        // Get anchor data
+        ScDrawObjData* pObjData = ScDrawLayer::GetObjData(pObject, false);
+        if (!pObjData)
+            continue;
+        const ScAddress aOldStart = pObjData->maStart;
+        const ScAddress aOldEnd = pObjData->maEnd;
+
+        // Set start address
+        ScAddress aNewStart = ScAddress(nTargetCol, nTargetRow, nTab);
+        pObjData->maStart = aNewStart;
+
+        // Set end address
+        const SCCOL nObjectColSpan = aOldEnd.Col() - aOldStart.Col();
+        const SCROW nObjectRowSpan = aOldEnd.Row() - aOldStart.Row();
+        ScAddress aNewEnd = aNewStart;
+        aNewEnd.IncRow(nObjectRowSpan);
+        aNewEnd.IncCol(nObjectColSpan);
+        pObjData->maEnd = aNewEnd;
+
+        // Update draw object according to new anchor
+        ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+        if (pDrawLayer)
             pDrawLayer->RecalcPos(pObject, *pObjData, false, false);
-        }
     }
 }
 
+bool ScColumn::IsDrawObjectsEmptyBlock(SCROW nStartRow, SCROW nEndRow) const
+{
+    const ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+    if (!pDrawLayer)
+        return true;
+
+    for (SCROW nCurrentRow = nStartRow; nCurrentRow <= nEndRow; nCurrentRow++)
+    {
+        ScAddress aCell(nCol, nCurrentRow, nTab);
+        if (!pDrawLayer->GetObjectsAnchoredToCell(aCell).empty())
+            return false;
+    }
+    return true;
+}
+
 void ScColumn::SwapCol(ScColumn& rCol)
 {
     maBroadcasters.swap(rCol.maBroadcasters);
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 1f3aea8226df..fd884b9b49b9 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -1312,9 +1312,17 @@ SCROW ScColumn::GetLastDataPos() const
     return MAXROW - static_cast<SCROW>(it->size);
 }
 
-SCROW ScColumn::GetLastDataPos( SCROW nLastRow ) const
+SCROW ScColumn::GetLastDataPos( SCROW nLastRow, bool bConsiderCellNotes,
+                                bool bConsiderCellDrawObjects ) const
 {
     sc::CellStoreType::const_position_type aPos = maCells.position(nLastRow);
+
+    if (bConsiderCellNotes && !IsNotesEmptyBlock(nLastRow, nLastRow))
+        return nLastRow;
+
+    if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nLastRow, nLastRow))
+        return nLastRow;
+
     if (aPos.first->type != sc::element_type_empty)
         return nLastRow;
 
@@ -2865,8 +2873,14 @@ void ScColumn::FindDataAreaPos(SCROW& rRow, bool bDown) const
     rRow = nLastRow;
 }
 
-bool ScColumn::HasDataAt(SCROW nRow) const
+bool ScColumn::HasDataAt(SCROW nRow, bool bConsiderCellNotes, bool bConsiderCellDrawObjects) const
 {
+    if (bConsiderCellNotes && !IsNotesEmptyBlock(nRow, nRow))
+        return true;
+
+    if (bConsiderCellDrawObjects && !IsDrawObjectsEmptyBlock(nRow, nRow))
+        return true;
+
     return maCells.get_type(nRow) != sc::element_type_empty;
 }
 
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index b524c59e1424..b8a93b3b6d4b 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -28,6 +28,7 @@
 #include <scitems.hxx>
 #include <cellform.hxx>
 #include <sharedformula.hxx>
+#include <drwlayer.hxx>
 
 #include <svl/sharedstringpool.hxx>
 
@@ -1011,6 +1012,21 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, SCROW nRow2, bool bPattern )
                 SetPattern(nRow, *pPat2);
                 rOther.SetPattern(nRow, *pPat1);
             }
+
+            // Update draw object anchors
+            ScDrawLayer* pDrawLayer = GetDoc().GetDrawLayer();
+            if (pDrawLayer)
+            {
+                ScAddress aThisCellPos(GetCol(), nRow, GetTab());
+                ScAddress aOtherCellPos(rOther.GetCol(), nRow, GetTab());
+                std::vector<SdrObject*> pThisColObjects = pDrawLayer->GetObjectsAnchoredToCell(aThisCellPos);
+                std::vector<SdrObject*> pOtherColObjects = pDrawLayer->GetObjectsAnchoredToCell(aOtherCellPos);
+                if (!pThisColObjects.empty())
+                    UpdateDrawObjectsForRow(pThisColObjects, rOther.GetCol(), nRow);
+                if (!pOtherColObjects.empty())
+                    rOther.UpdateDrawObjectsForRow(pOtherColObjects, GetCol(), nRow);
+
+            }
         }
     }
 
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index c94e4a85f970..bed73d7c32e9 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -1064,7 +1064,8 @@ bool ScDocument::ShrinkToDataArea(SCTAB nTab, SCCOL& rStartCol, SCROW& rStartRow
 
 bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStartCol,
         SCROW& rStartRow, SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly,
-        bool bStickyTopRow, bool bStickyLeftCol ) const
+        bool bStickyTopRow, bool bStickyLeftCol, bool bConsiderCellNotes,
+        bool bConsiderCellDrawObjects ) const
 {
     if (!ValidTab(nTab) || nTab >= static_cast<SCTAB> (maTabs.size()) || !maTabs[nTab])
     {
@@ -1072,7 +1073,7 @@ bool ScDocument::ShrinkToUsedDataArea( bool& o_bShrunk, SCTAB nTab, SCCOL& rStar
         return false;
     }
     return maTabs[nTab]->ShrinkToUsedDataArea( o_bShrunk, rStartCol, rStartRow, rEndCol, rEndRow,
-            bColumnsOnly, bStickyTopRow, bStickyLeftCol);
+            bColumnsOnly, bStickyTopRow, bStickyLeftCol, bConsiderCellNotes, bConsiderCellDrawObjects );
 }
 
 SCROW ScDocument::GetLastDataRow( SCTAB nTab, SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 501cb275c973..87b44b7d7234 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1936,6 +1936,7 @@ void ScDrawLayer::GetCellAnchorFromPosition( SdrObject &rObj, ScDrawObjData &rAn
         rAnchor.maEndOffset.X() = aObjRect.Right()-aCellRect.Left();
     else
         rAnchor.maEndOffset.X() = aCellRect.Right()-aObjRect.Left();
+
 }
 
 void ScDrawLayer::UpdateCellAnchorFromPositionEnd( SdrObject &rObj, ScDrawObjData &rAnchor, const ScDocument &rDoc, SCTAB nTab, bool bUseLogicRect )
@@ -1976,9 +1977,9 @@ ScAnchorType ScDrawLayer::GetAnchorType( const SdrObject &rObj )
     return ScDrawLayer::GetObjData(const_cast<SdrObject*>(&rObj)) ? SCA_CELL : SCA_PAGE;
 }
 
-std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& rCell)
+std::vector<SdrObject*> ScDrawLayer::GetObjectsAnchoredToCell(const ScAddress& rCell) const
 {
-    SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab()));
+    const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(rCell.Tab()));
     if (!pPage || pPage->GetObjCount() < 1)
         return std::vector<SdrObject*>();
 
diff --git a/sc/source/core/data/table1.cxx b/sc/source/core/data/table1.cxx
index 06c2ccfffbe6..00931e3cab35 100644
--- a/sc/source/core/data/table1.cxx
+++ b/sc/source/core/data/table1.cxx
@@ -915,7 +915,8 @@ void ScTable::GetDataArea( SCCOL& rStartCol, SCROW& rStartRow, SCCOL& rEndCol, S
 }
 
 bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rStartRow,
-        SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol ) const
+        SCCOL& rEndCol, SCROW& rEndRow, bool bColumnsOnly, bool bStickyTopRow, bool bStickyLeftCol,
+        bool bConsiderCellNotes, bool bConsiderCellDrawObjects ) const
 {
     o_bShrunk = false;
 
@@ -946,6 +947,9 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
     {
         if (aCol[rEndCol].IsEmptyBlock( rStartRow, rEndRow))
         {
+            if (bConsiderCellDrawObjects && !aCol[rEndCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow ))
+                break;
+
             --rEndCol;
             o_bShrunk = true;
         }
@@ -959,6 +963,9 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
         {
             if (aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow))
             {
+                if (bConsiderCellDrawObjects && !aCol[rStartCol].IsDrawObjectsEmptyBlock( rStartRow, rEndRow ))
+                    break;
+
                 ++rStartCol;
                 o_bShrunk = true;
             }
@@ -976,7 +983,7 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
                 bool bFound = false;
                 for (SCCOL i=rStartCol; i<=rEndCol && !bFound; i++)
                 {
-                    if (aCol[i].HasDataAt( rStartRow))
+                    if (aCol[i].HasDataAt( rStartRow, bConsiderCellNotes, bConsiderCellDrawObjects))
                         bFound = true;
                 }
                 if (!bFound)
@@ -991,7 +998,8 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
 
         while (rStartRow < rEndRow)
         {
-            SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow);
+            SCROW nLastDataRow = GetLastDataRow( rStartCol, rEndCol, rEndRow,
+                                                 bConsiderCellNotes, bConsiderCellDrawObjects);
             if (0 <= nLastDataRow && nLastDataRow < rEndRow)
             {
                 rEndRow = std::max( rStartRow, nLastDataRow);
@@ -1004,10 +1012,12 @@ bool ScTable::ShrinkToUsedDataArea( bool& o_bShrunk, SCCOL& rStartCol, SCROW& rS
 
     return rStartCol != rEndCol || (bColumnsOnly ?
             !aCol[rStartCol].IsEmptyBlock( rStartRow, rEndRow) :
-            (rStartRow != rEndRow || aCol[rStartCol].HasDataAt( rStartRow)));
+            (rStartRow != rEndRow ||
+                aCol[rStartCol].HasDataAt( rStartRow, bConsiderCellNotes, bConsiderCellDrawObjects)));
 }
 
-SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
+SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow,
+                               bool bConsiderCellNotes, bool bConsiderCellDrawObjects ) const
 {
     if (!ValidCol(nCol1) || !ValidCol(nCol2))
         return -1;
@@ -1015,7 +1025,7 @@ SCROW ScTable::GetLastDataRow( SCCOL nCol1, SCCOL nCol2, SCROW nLastRow ) const
     SCROW nNewLastRow = 0;
     for (SCCOL i = nCol1; i <= nCol2; ++i)
     {
-        SCROW nThis = aCol[i].GetLastDataPos(nLastRow);
+        SCROW nThis = aCol[i].GetLastDataPos(nLastRow, bConsiderCellNotes, bConsiderCellDrawObjects);
         if (nNewLastRow < nThis)
             nNewLastRow = nThis;
     }
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index acbace69428a..996ddf726cfd 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -513,7 +513,8 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
     // so empty leading cells will be sorted to the end.
     bool bShrunk = false;
     rDoc.ShrinkToUsedDataArea( bShrunk, nTab, aLocalParam.nCol1, aLocalParam.nRow1,
-            aLocalParam.nCol2, aLocalParam.nRow2, false, aLocalParam.bByRow, !aLocalParam.bByRow);
+            aLocalParam.nCol2, aLocalParam.nRow2, false, aLocalParam.bByRow, !aLocalParam.bByRow,
+            false, true );
 
     SCROW nStartRow = aLocalParam.nRow1;
     if (aLocalParam.bByRow && aLocalParam.bHasHeader && nStartRow < aLocalParam.nRow2)


More information about the Libreoffice-commits mailing list