[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