[ooo-build-commit] Branch 'ooo-build-3-1-1' - patches/dev300

Kohei Yoshida kohei at kemper.freedesktop.org
Mon Sep 21 11:01:44 PDT 2009


 patches/dev300/apply                                |    4 
 patches/dev300/calc-find-replace-skip-filtered.diff |  380 ++++++++++++++++++++
 2 files changed, 383 insertions(+), 1 deletion(-)

New commits:
commit f297c9dce8809122a715c50320055445919c1bff
Author: Kohei Yoshida <kyoshida at novell.com>
Date:   Mon Sep 21 13:55:43 2009 -0400

    [experimental] Skip filtered cells when finding or replacing cells.
    
    * patches/dev300/apply: Add this patch to CalcExperimental, disabled
      in the default build.
    
    * patches/dev300/calc-find-replace-skip-filtered.diff: Skip filtered
      cells when finding or replacing cell contents. (n#539282)

diff --git a/patches/dev300/apply b/patches/dev300/apply
index c20c8f2..e329fd4 100644
--- a/patches/dev300/apply
+++ b/patches/dev300/apply
@@ -3400,7 +3400,6 @@ desktop-cmd-bulk-conversion.diff, flr
 # It's empty but please don't remove this section.
 SectionOwner => kohei
 
-[ CalcExperimental ]
 # when reading csv file, don't read multiple physical lines for one logical 
 # line even if matching quotes are on separate lines.
 stream-read-csv-always-single-line.diff, n#523517, kohei
@@ -3409,6 +3408,9 @@ stream-read-csv-always-single-line.diff, n#523517, kohei
 # prepend ' in front of the value.
 calc-html-csv-import-force-text-cell.diff, n#523414, i#103939, kohei
 
+# When finding or replacing cell contents, skip filtered cells.
+calc-find-replace-skip-filtered.diff, n#539282, kohei
+
 [ AutoLayout ]
 sd-layoutcode.diff, cocofan
 offapi-layoutcode.diff, cocofan
diff --git a/patches/dev300/calc-find-replace-skip-filtered.diff b/patches/dev300/calc-find-replace-skip-filtered.diff
new file mode 100644
index 0000000..3754411
--- /dev/null
+++ b/patches/dev300/calc-find-replace-skip-filtered.diff
@@ -0,0 +1,380 @@
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index 62207fb..192ca18 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -826,6 +826,8 @@ private:
+     // also invalidates script type, broadcasts for "calc as shown"
+     void        InvalidateTextWidth( const ScAddress* pAdrFrom, const ScAddress* pAdrTo,
+                                      BOOL bNumFormatChanged, BOOL bBroadcast );
++
++    void        SkipFilteredRows(SCROW& rRow, SCROW& rLastNonFilteredRow, bool bForward);
+ };
+ 
+ 
+diff --git sc/source/core/data/table6.cxx sc/source/core/data/table6.cxx
+index 272e049..be44ff1 100644
+--- sc/source/core/data/table6.cxx
++++ sc/source/core/data/table6.cxx
+@@ -251,6 +251,42 @@ BOOL ScTable::SearchCell(const SvxSearchItem& rSearchItem, SCCOL nCol, SCROW nRo
+     return bFound;
+ }
+ 
++void ScTable::SkipFilteredRows(SCROW& rRow, SCROW& rLastNonFilteredRow, bool bForward)
++{
++    if (bForward)
++    {
++        // forward search
++
++        if (rRow <= rLastNonFilteredRow)
++            return;
++    
++        SCROW nLastRow = rRow;
++        if (RowFiltered(rRow, NULL, &nLastRow))
++            // move to the first non-filtered row.
++            rRow = nLastRow + 1;
++        else
++            // record the last non-filtered row to avoid checking 
++            // the filtered state for each and every row.
++            rLastNonFilteredRow = nLastRow;
++    }
++    else
++    {
++        // backward search
++
++        if (rRow >= rLastNonFilteredRow)
++            return;
++    
++        SCROW nFirstRow = rRow;
++        if (RowFiltered(rRow, &nFirstRow, NULL))
++            // move to the first non-filtered row.
++            rRow = nFirstRow - 1;
++        else
++            // record the last non-filtered row to avoid checking 
++            // the filtered state for each and every row.
++            rLastNonFilteredRow = nFirstRow;
++    }
++}
++
+ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+                         const ScMarkData& rMark, String& rUndoStr, ScDocument* pUndoDoc)
+ {
+@@ -264,6 +300,7 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+     GetLastDataPos(nLastCol, nLastRow);
+     if (!bAll && rSearchItem.GetBackward())
+     {
++        SCROW nLastNonFilteredRow = MAXROW + 1;
+         nCol = Min(nCol, (SCCOL)(nLastCol + 1));
+         nRow = Min(nRow, (SCROW)(nLastRow + 1));
+         if (rSearchItem.GetRowDirection())
+@@ -271,6 +308,8 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+             nCol--;
+             while (!bFound && ((SCsROW)nRow >= 0))
+             {
++                SkipFilteredRows(nRow, nLastNonFilteredRow, false);
++
+                 while (!bFound && ((SCsCOL)nCol >= 0))
+                 {
+                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+@@ -302,6 +341,8 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+             {
+                 while (!bFound && ((SCsROW)nRow >= 0))
+                 {
++                    SkipFilteredRows(nRow, nLastNonFilteredRow, false);
++
+                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                     if (!bFound)
+                     {
+@@ -311,8 +352,10 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+                 }
+                 if (!bFound)
+                 {
++                    // Not found in this column.  Move to the next column.
+                     BOOL bIsEmpty;
+                     nRow = nLastRow;
++                    nLastNonFilteredRow = MAXROW + 1;
+                     do
+                     {
+                         nCol--;
+@@ -328,11 +371,14 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+     }
+     else
+     {
++        SCROW nLastNonFilteredRow = -1;
+         if (!bAll && rSearchItem.GetRowDirection())
+         {
+             nCol++;
+             while (!bFound && (nRow <= nLastRow))
+             {
++                SkipFilteredRows(nRow, nLastNonFilteredRow, true);
++
+                 while (!bFound && (nCol <= nLastCol))
+                 {
+                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+@@ -356,6 +402,8 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+             {
+                 while (!bFound && (nRow <= nLastRow))
+                 {
++                    SkipFilteredRows(nRow, nLastNonFilteredRow, true);
++
+                     bFound = SearchCell(rSearchItem, nCol, nRow, rMark, rUndoStr, pUndoDoc);
+                     if (!bFound)
+                     {
+@@ -365,7 +413,9 @@ BOOL ScTable::Search(const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
+                 }
+                 if (!bFound)
+                 {
++                    // Not found in this column.  Move to the next column.
+                     nRow = 0;
++                    nLastNonFilteredRow = -1;
+                     nCol++;
+                     while ((nCol <= nLastCol) && aCol[nCol].IsEmptyData()) nCol++;
+                 }
+@@ -770,6 +820,30 @@ bool ScTable::SearchAndReplaceEmptyCells(
+     return false;
+ }
+ 
++namespace {
++
++bool lcl_maybeReplaceCellString(
++    ScColumn& rColObj, SCCOL& rCol, SCROW& rRow, String& rUndoStr, SCCOL nCol, SCROW nRow, const SvxSearchItem& rSearchItem)
++{
++    ScBaseCell* pCell = rColObj.GetCell(nRow);
++    if (!pCell || pCell->GetCellType() == CELLTYPE_NOTE)
++    {
++        // empty cell found.
++        rCol = nCol;
++        rRow = nRow;
++        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
++            rSearchItem.GetReplaceString().Len())
++        {
++            rColObj.Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
++            rUndoStr = String();
++        }
++        return true;
++    }
++    return false;
++}
++
++}
++
+ bool ScTable::SearchRangeForEmptyCell(
+     const ScRange& rRange, const SvxSearchItem& rSearchItem, 
+     SCCOL& rCol, SCROW& rRow, String& rUndoStr, ScDocument* /*pUndoDoc*/)
+@@ -781,9 +855,14 @@ bool ScTable::SearchRangeForEmptyCell(
+         if (rSearchItem.GetRowDirection())
+         {
+             // row direction.
++            SCROW nLastNonFilteredRow = MAXROW + 1;
+             SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
+             for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
+             {
++                SkipFilteredRows(nRow, nLastNonFilteredRow, false);
++                if (nRow < rRange.aStart.Row())
++                    break;
++
+                 SCCOL nBeginCol = rRange.aEnd.Col();
+                 if (nRow == rRow && nBeginCol >= rCol)
+                     // always start from one cell before the cursor.
+@@ -791,20 +870,8 @@ bool ScTable::SearchRangeForEmptyCell(
+ 
+                 for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
+                 {
+-                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+-                    if (!pCell)
+-                    {
+-                        // empty cell found.
+-                        rCol = nCol;
+-                        rRow = nRow;
+-                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+-                            rSearchItem.GetReplaceString().Len())
+-                        {
+-                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+-                            rUndoStr = String();
+-                        }
++                    if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
+                         return true;
+-                    }
+                 }
+             }
+         }
+@@ -814,26 +881,19 @@ bool ScTable::SearchRangeForEmptyCell(
+             SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
+             for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
+             {
++                SCROW nLastNonFilteredRow = MAXROW + 1;
+                 SCROW nBeginRow = rRange.aEnd.Row();
+                 if (nCol == rCol && nBeginRow >= rRow)
+                     // always start from one cell before the cursor.
+                     nBeginRow = rRow - (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                 for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
+                 {   
+-                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+-                    if (!pCell)
+-                    {
+-                        // empty cell found.
+-                        rCol = nCol;
+-                        rRow = nRow;
+-                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+-                            rSearchItem.GetReplaceString().Len())
+-                        {
+-                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+-                            rUndoStr = String();
+-                        }
++                    SkipFilteredRows(nRow, nLastNonFilteredRow, false);
++                    if (nRow < rRange.aStart.Row())
++                        break;
++
++                    if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
+                         return true;
+-                    }
+                 }
+             }
+         }
+@@ -844,29 +904,22 @@ bool ScTable::SearchRangeForEmptyCell(
+         if (rSearchItem.GetRowDirection())
+         {
+             // row direction.
++            SCROW nLastNonFilteredRow = -1;
+             SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
+             for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
+             {
++                SkipFilteredRows(nRow, nLastNonFilteredRow, true);
++                if (nRow > rRange.aEnd.Row())
++                    break;
++
+                 SCCOL nBeginCol = rRange.aStart.Col();
+                 if (nRow == rRow && nBeginCol <= rCol)
+                     // always start from one cell past the cursor.
+                     nBeginCol = rCol + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                 for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
+                 {
+-                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+-                    if (!pCell)
+-                    {
+-                        // empty cell found.
+-                        rCol = nCol;
+-                        rRow = nRow;
+-                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+-                            rSearchItem.GetReplaceString().Len())
+-                        {
+-                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+-                            rUndoStr = String();
+-                        }
++                    if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
+                         return true;
+-                    }
+                 }
+             }
+         }
+@@ -876,26 +929,19 @@ bool ScTable::SearchRangeForEmptyCell(
+             SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
+             for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
+             {
++                SCROW nLastNonFilteredRow = -1;
+                 SCROW nBeginRow = rRange.aStart.Row();
+                 if (nCol == rCol && nBeginRow <= rRow)
+                     // always start from one cell past the cursor.
+                     nBeginRow = rRow + (nCmd == SVX_SEARCHCMD_FIND ? 1 : 0);
+                 for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
+                 {   
+-                    ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+-                    if (!pCell)
+-                    {
+-                        // empty cell found.
+-                        rCol = nCol;
+-                        rRow = nRow;
+-                        if (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE &&
+-                            rSearchItem.GetReplaceString().Len())
+-                        {
+-                            aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
+-                            rUndoStr = String();
+-                        }
++                    SkipFilteredRows(nRow, nLastNonFilteredRow, true);
++                    if (nRow > rRange.aEnd.Row())
++                        break;
++
++                    if (lcl_maybeReplaceCellString(aCol[nCol], rCol, rRow, rUndoStr, nCol, nRow, rSearchItem))
+                         return true;
+-                    }
+                 }
+             }
+         }
+@@ -913,32 +959,44 @@ bool ScTable::SearchRangeForAllEmptyCells(
+ 
+     for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
+     {
++        SCROW nLastNonFilteredRow = -1;
+         if (aCol[nCol].IsEmptyData())
+         {
+-            // The entire column is empty.  Add the whole column and move on.
+-            rMark.SetMultiMarkArea(
+-                ScRange(nCol, rRange.aStart.Row(), nTab, nCol, rRange.aEnd.Row(), nTab));
+-            bFound = true;
+-
+-            if (bReplace)
++            // The entire column is empty.
++            for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+             {
+-                const String& rNewStr = rSearchItem.GetReplaceString();
+-                for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
++                SCROW nLastRow;
++                if (!RowFiltered(nRow, NULL, &nLastRow))
+                 {    
+-                    aCol[nCol].Insert(nRow, new ScStringCell(rNewStr));
+-                    if (pUndoDoc)
+-                        // TODO: I'm using a string cell with empty content to 
+-                        // trigger deletion of cell instance on undo.  Maybe I
+-                        // should create a new cell type for this?
+-                        pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
++                    rMark.SetMultiMarkArea(ScRange(nCol, nRow, nTab, nCol, nLastRow, nTab));
++                    if (bReplace)
++                    {
++                        const String& rNewStr = rSearchItem.GetReplaceString();
++                        for (SCROW i = nRow; i <= nLastRow; ++i)
++                        {    
++                            aCol[nCol].Insert(i, new ScStringCell(rNewStr));
++                            if (pUndoDoc)
++                                // TODO: I'm using a string cell with empty content to 
++                                // trigger deletion of cell instance on undo.  Maybe I
++                                // should create a new cell type for this?
++                                pUndoDoc->PutCell(nCol, i, nTab, new ScStringCell(String()));
++                        }
++                        rUndoStr = String();
++                    }
+                 }
+-                rUndoStr = String();
++
++                nRow = nLastRow; // move to the last filtered row.
+             }
++            bFound = true;
+             continue;
+         }
+ 
+         for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
+         {
++            SkipFilteredRows(nRow, nLastNonFilteredRow, true);
++            if (nRow > rRange.aEnd.Row())
++                break;
++
+             ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
+             if (!pCell)
+             {    
+@@ -956,6 +1014,18 @@ bool ScTable::SearchRangeForAllEmptyCells(
+                         pUndoDoc->PutCell(nCol, nRow, nTab, new ScStringCell(String()));
+                 }
+             }
++            else if (pCell->GetCellType() == CELLTYPE_NOTE)
++            {
++                rMark.SetMultiMarkArea(ScRange(nCol, nRow, nTab));
++                bFound = true;
++
++                if (bReplace)
++                {    
++                    if (pUndoDoc)
++                        pUndoDoc->PutCell(nCol, nRow, nTab, pCell->CloneWithNote(*pUndoDoc, ScAddress(nCol, nRow, nTab)));
++                    aCol[nCol].SetString(nRow, nTab, rSearchItem.GetReplaceString());
++                }
++            }
+         }
+     }
+     return bFound;


More information about the ooo-build-commit mailing list