[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