[Libreoffice-commits] core.git: sc/inc sc/source

Eike Rathke (via logerrit) logerrit at kemper.freedesktop.org
Tue Apr 7 23:58:19 UTC 2020


 sc/inc/column.hxx                  |    2 +-
 sc/inc/document.hxx                |    3 ++-
 sc/inc/table.hxx                   |    6 ++++--
 sc/source/core/data/column.cxx     |    8 +++++++-
 sc/source/core/data/document.cxx   |    5 +++--
 sc/source/core/data/table2.cxx     |   30 +++++++++++++++++++++---------
 sc/source/ui/docshell/dbdocfun.cxx |    4 ++--
 sc/source/ui/docshell/editable.cxx |   12 ++++++------
 sc/source/ui/inc/editable.hxx      |    9 +++++++--
 9 files changed, 53 insertions(+), 26 deletions(-)

New commits:
commit b1da67699bd05b26ee11460347ca7077d366c2fc
Author:     Eike Rathke <erack at redhat.com>
AuthorDate: Wed Apr 8 00:47:09 2020 +0200
Commit:     Eike Rathke <erack at redhat.com>
CommitDate: Wed Apr 8 01:57:45 2020 +0200

    Resolves: tdf#131442 Sort must not contain matrix formula except 1x1 array
    
    Change-Id: Idc7a9646a70c59fceee0b36426f38a938cf073ce
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91858
    Reviewed-by: Eike Rathke <erack at redhat.com>
    Tested-by: Jenkins

diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index 576a88a8f71a..0eb2ad5f1c85 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -234,7 +234,7 @@ public:
     void        FindUsed( SCROW nStartRow, SCROW nEndRow, mdds::flat_segment_tree<SCROW, bool>& rUsed ) const;
 
     SCSIZE             VisibleCount( SCROW nStartRow, SCROW nEndRow ) const;
-    sc::MatrixEdge     GetBlockMatrixEdges(SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask ) const;
+    sc::MatrixEdge     GetBlockMatrixEdges(SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask, bool bNoMatrixAtAll ) const;
     bool    HasSelectionMatrixFragment(const ScMarkData& rMark) const;
 
     bool    GetFirstVisibleAttr( SCROW& rFirstRow ) const;
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx
index 847a4c42ccee..99c328157347 100644
--- a/sc/inc/document.hxx
+++ b/sc/inc/document.hxx
@@ -900,7 +900,8 @@ public:
 
     bool            IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
                                      SCCOL nEndCol, SCROW nEndRow,
-                                     bool* pOnlyNotBecauseOfMatrix = nullptr ) const;
+                                     bool* pOnlyNotBecauseOfMatrix = nullptr,
+                                     bool bNoMatrixAtAll = false ) const;
     bool            IsSelectionEditable( const ScMarkData& rMark,
                                          bool* pOnlyNotBecauseOfMatrix = nullptr ) const;
     bool            HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow,
diff --git a/sc/inc/table.hxx b/sc/inc/table.hxx
index 8feb233480cf..7de7f24b59c2 100644
--- a/sc/inc/table.hxx
+++ b/sc/inc/table.hxx
@@ -392,11 +392,13 @@ public:
     void        UnlockTable();
 
     bool        IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
-                        SCROW nRow2, bool* pOnlyNotBecauseOfMatrix = nullptr ) const;
+                        SCROW nRow2, bool* pOnlyNotBecauseOfMatrix = nullptr,
+                        bool bNoMatrixAtAll = false ) const;
     bool        IsSelectionEditable( const ScMarkData& rMark,
                         bool* pOnlyNotBecauseOfMatrix = nullptr ) const;
 
-    bool        HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const;
+    bool        HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2,
+                                        bool bNoMatrixAtAll = false ) const;
     bool        HasSelectionMatrixFragment( const ScMarkData& rMark ) const;
 
     bool        IsBlockEmpty( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, bool bIgnoreNotes ) const;
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 7fa1c4c30286..9388e01ee1f0 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -110,7 +110,8 @@ SCROW ScColumn::GetNextUnprotected( SCROW nRow, bool bUp ) const
     return pAttrArray->GetNextUnprotected(nRow, bUp);
 }
 
-sc::MatrixEdge ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask ) const
+sc::MatrixEdge ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sc::MatrixEdge nMask,
+        bool bNoMatrixAtAll ) const
 {
     using namespace sc;
 
@@ -163,6 +164,11 @@ sc::MatrixEdge ScColumn::GetBlockMatrixEdges( SCROW nRow1, SCROW nRow2, sc::Matr
             if (nEdges == MatrixEdge::Nothing)
                 continue;
 
+            // A 1x1 matrix array formula is OK even for no matrix at all.
+            if (bNoMatrixAtAll
+                    && (nEdges != (MatrixEdge::Top | MatrixEdge::Left | MatrixEdge::Bottom | MatrixEdge::Right)))
+                return MatrixEdge::Inside;  // per convention Inside
+
             if (nEdges & MatrixEdge::Top)
                 bOpen = true;       // top edge opens, keep on looking
             else if (!bOpen)
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 4ecd59225f45..ad292b70b7e2 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5323,7 +5323,8 @@ void ScDocument::UnlockTable(SCTAB nTab)
 
 bool ScDocument::IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
                                         SCCOL nEndCol, SCROW nEndRow,
-                                        bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+                                        bool* pOnlyNotBecauseOfMatrix /* = NULL */,
+                                        bool bNoMatrixAtAll ) const
 {
     // import into read-only document is possible
     if (!bImportingXML && !mbChangeReadOnlyEnabled && mpShell && mpShell->IsReadOnly())
@@ -5336,7 +5337,7 @@ bool ScDocument::IsBlockEditable( SCTAB nTab, SCCOL nStartCol, SCROW nStartRow,
     if (ValidTab(nTab) && nTab < static_cast<SCTAB>(maTabs.size()))
         if (maTabs[nTab])
             return maTabs[nTab]->IsBlockEditable( nStartCol, nStartRow, nEndCol,
-                nEndRow, pOnlyNotBecauseOfMatrix );
+                nEndRow, pOnlyNotBecauseOfMatrix, bNoMatrixAtAll );
 
     OSL_FAIL("wrong table number");
     if ( pOnlyNotBecauseOfMatrix )
diff --git a/sc/source/core/data/table2.cxx b/sc/source/core/data/table2.cxx
index a4391ab7ec05..869d255b2b47 100644
--- a/sc/source/core/data/table2.cxx
+++ b/sc/source/core/data/table2.cxx
@@ -2297,7 +2297,8 @@ void ScTable::FindMaxRotCol( RowInfo* pRowInfo, SCSIZE nArrCount, SCCOL nX1, SCC
     }
 }
 
-bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2 ) const
+bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCOL nCol2, SCROW nRow2,
+        bool bNoMatrixAtAll ) const
 {
     using namespace sc;
 
@@ -2311,28 +2312,38 @@ bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCO
     if ( nCol1 == nMaxCol2 )
     {   // left and right column
         const MatrixEdge n = MatrixEdge::Left | MatrixEdge::Right;
-        nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n );
+        nEdges = aCol[nCol1].GetBlockMatrixEdges( nRow1, nRow2, n, bNoMatrixAtAll );
         if ((nEdges != MatrixEdge::Nothing) && (((nEdges & n)!=n) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
             return true;        // left or right edge is missing or open
     }
     else
     {   // left column
-        nEdges = aCol[nCol1].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Left);
+        nEdges = aCol[nCol1].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Left, bNoMatrixAtAll);
         if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Left)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
             return true;        // left edge missing or open
         // right column
-        nEdges = aCol[nMaxCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Right);
+        nEdges = aCol[nMaxCol2].GetBlockMatrixEdges(nRow1, nRow2, MatrixEdge::Right, bNoMatrixAtAll);
         if ((nEdges != MatrixEdge::Nothing) && ((!(nEdges & MatrixEdge::Right)) || (nEdges & (MatrixEdge::Inside|MatrixEdge::Open))))
             return true;        // right edge is missing or open
     }
 
-    if ( nRow1 == nRow2 )
+    if (bNoMatrixAtAll)
+    {
+        for (SCCOL i=nCol1; i<=nMaxCol2; i++)
+        {
+            nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow2, MatrixEdge::Nothing, bNoMatrixAtAll);
+            if (nEdges != MatrixEdge::Nothing
+                    && (nEdges != (MatrixEdge::Top | MatrixEdge::Left | MatrixEdge::Bottom | MatrixEdge::Right)))
+                return true;
+        }
+    }
+    else if ( nRow1 == nRow2 )
     {   // Row on top and on bottom
         bool bOpen = false;
         const MatrixEdge n = MatrixEdge::Bottom | MatrixEdge::Top;
         for ( SCCOL i=nCol1; i<=nMaxCol2; i++)
         {
-            nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n );
+            nEdges = aCol[i].GetBlockMatrixEdges( nRow1, nRow1, n, bNoMatrixAtAll );
             if (nEdges != MatrixEdge::Nothing)
             {
                 if ( (nEdges & n) != n )
@@ -2360,7 +2371,7 @@ bool ScTable::HasBlockMatrixFragment( const SCCOL nCol1, SCROW nRow1, const SCCO
             bool bOpen = false;
             for ( SCCOL i=nCol1; i<=nMaxCol2; i++)
             {
-                nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n );
+                nEdges = aCol[i].GetBlockMatrixEdges( nR, nR, n, bNoMatrixAtAll );
                 if ( nEdges != MatrixEdge::Nothing)
                 {
                     // in top row no top edge respectively
@@ -2399,7 +2410,8 @@ bool ScTable::HasSelectionMatrixFragment( const ScMarkData& rMark ) const
 }
 
 bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
-            SCROW nRow2, bool* pOnlyNotBecauseOfMatrix /* = NULL */ ) const
+            SCROW nRow2, bool* pOnlyNotBecauseOfMatrix /* = NULL */,
+            bool bNoMatrixAtAll ) const
 {
     if ( !ValidColRow( nCol2, nRow2 ) )
     {
@@ -2467,7 +2479,7 @@ bool ScTable::IsBlockEditable( SCCOL nCol1, SCROW nRow1, SCCOL nCol2,
     }
     if ( bIsEditable )
     {
-        if ( HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2 ) )
+        if (HasBlockMatrixFragment( nCol1, nRow1, nCol2, nRow2, bNoMatrixAtAll))
         {
             bIsEditable = false;
             if ( pOnlyNotBecauseOfMatrix )
diff --git a/sc/source/ui/docshell/dbdocfun.cxx b/sc/source/ui/docshell/dbdocfun.cxx
index e57020b93de3..352c77f619e9 100644
--- a/sc/source/ui/docshell/dbdocfun.cxx
+++ b/sc/source/ui/docshell/dbdocfun.cxx
@@ -512,8 +512,8 @@ bool ScDBDocFunc::Sort( SCTAB nTab, const ScSortParam& rSortParam,
         else
             nStartingColToEdit++;
     }
-    ScEditableTester aTester( &rDoc, nTab, nStartingColToEdit,nStartingRowToEdit,
-                                        aLocalParam.nCol2,aLocalParam.nRow2 );
+    ScEditableTester aTester( &rDoc, nTab, nStartingColToEdit, nStartingRowToEdit,
+            aLocalParam.nCol2, aLocalParam.nRow2, true /*bNoMatrixAtAll*/ );
     if (!aTester.IsEditable())
     {
         if (!bApi)
diff --git a/sc/source/ui/docshell/editable.cxx b/sc/source/ui/docshell/editable.cxx
index 8d461a0806b7..ec9f071b9096 100644
--- a/sc/source/ui/docshell/editable.cxx
+++ b/sc/source/ui/docshell/editable.cxx
@@ -29,11 +29,11 @@ ScEditableTester::ScEditableTester() :
 }
 
 ScEditableTester::ScEditableTester( const ScDocument* pDoc, SCTAB nTab,
-                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow ) :
+        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bNoMatrixAtAll ) :
     mbIsEditable(true),
     mbOnlyMatrix(true)
 {
-    TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+    TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow, bNoMatrixAtAll );
 }
 
 ScEditableTester::ScEditableTester( const ScDocument* pDoc,
@@ -80,12 +80,12 @@ ScEditableTester::ScEditableTester(
 }
 
 void ScEditableTester::TestBlock( const ScDocument* pDoc, SCTAB nTab,
-                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow )
+        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, bool bNoMatrixAtAll )
 {
     if (mbIsEditable || mbOnlyMatrix)
     {
         bool bThisMatrix;
-        if ( !pDoc->IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, nEndRow, &bThisMatrix ) )
+        if (!pDoc->IsBlockEditable( nTab, nStartCol, nStartRow, nEndCol, nEndRow, &bThisMatrix, bNoMatrixAtAll))
         {
             mbIsEditable = false;
             if ( !bThisMatrix )
@@ -104,7 +104,7 @@ void ScEditableTester::TestSelectedBlock( const ScDocument* pDoc,
         if (rTab >= nTabCount)
             break;
 
-        TestBlock( pDoc, rTab, nStartCol, nStartRow, nEndCol, nEndRow );
+        TestBlock( pDoc, rTab, nStartCol, nStartRow, nEndCol, nEndRow, false );
     }
 }
 
@@ -117,7 +117,7 @@ void ScEditableTester::TestRange(  const ScDocument* pDoc, const ScRange& rRange
     SCROW nEndRow = rRange.aEnd.Row();
     SCTAB nEndTab = rRange.aEnd.Tab();
     for (SCTAB nTab=nStartTab; nTab<=nEndTab; nTab++)
-        TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow );
+        TestBlock( pDoc, nTab, nStartCol, nStartRow, nEndCol, nEndRow, false );
 }
 
 void ScEditableTester::TestSelection( const ScDocument* pDoc, const ScMarkData& rMark )
diff --git a/sc/source/ui/inc/editable.hxx b/sc/source/ui/inc/editable.hxx
index 05eaa985d04c..97d28ede388f 100644
--- a/sc/source/ui/inc/editable.hxx
+++ b/sc/source/ui/inc/editable.hxx
@@ -41,8 +41,12 @@ public:
             ScEditableTester();
 
             // calls TestBlock
+            /** @param  bNoMatrixAtAll
+                        TRUE if there must not be any matrix, not even entirely
+                        containted; for example in sorting. */
             ScEditableTester( const ScDocument* pDoc, SCTAB nTab,
-                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+                        bool bNoMatrixAtAll = false );
 
             // calls TestSelectedBlock
             ScEditableTester( const ScDocument* pDoc,
@@ -65,7 +69,8 @@ public:
             // Several calls to the Test... methods check if *all* of the ranges
             // are editable. For several independent checks, Reset() has to be used.
     void    TestBlock( const ScDocument* pDoc, SCTAB nTab,
-                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow );
+                        SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
+                        bool bNoMatrixAtAll = false );
     void    TestSelectedBlock( const ScDocument* pDoc,
                         SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow,
                         const ScMarkData& rMark );


More information about the Libreoffice-commits mailing list