ooo-build r15396 - in trunk: . patches/dev300
- From: kyoshida svn gnome org
- To: svn-commits-list gnome org
- Subject: ooo-build r15396 - in trunk: . patches/dev300
- Date: Sun, 22 Feb 2009 03:49:12 +0000 (UTC)
Author: kyoshida
Date: Sun Feb 22 03:49:12 2009
New Revision: 15396
URL: http://svn.gnome.org/viewvc/ooo-build?rev=15396&view=rev
Log:
2009-02-21 Kohei Yoshida <kyoshida novell com>
* patches/dev300/calc-find-replace-empty-cells-sc.diff:
* patches/dev300/calc-find-replace-empty-cells-svx.diff:
* patches/dev300/apply: allow finding and replacing empty cells in Calc.
(i#49380, n#415352)
Added:
trunk/patches/dev300/calc-find-replace-empty-cells-sc.diff
trunk/patches/dev300/calc-find-replace-empty-cells-svx.diff
Modified:
trunk/ChangeLog
trunk/patches/dev300/apply
Modified: trunk/patches/dev300/apply
==============================================================================
--- trunk/patches/dev300/apply (original)
+++ trunk/patches/dev300/apply Sun Feb 22 03:49:12 2009
@@ -1892,6 +1892,9 @@
# Make it easier to un-select tabs when multiple tabs are selected.
calc-single-click-unselect-tabs.diff, i#70320, kohei/rail
+# Support finding and replacing empty cells.
+calc-find-replace-empty-cells-sc.diff i#49380, n#415352, kohei
+calc-find-replace-empty-cells-svx.diff i#49380, n#415352, kohei
[ CalcRowLimit ]
# The work to increase Calc's row size limit, and any work associated with it.
Added: trunk/patches/dev300/calc-find-replace-empty-cells-sc.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/calc-find-replace-empty-cells-sc.diff Sun Feb 22 03:49:12 2009
@@ -0,0 +1,399 @@
+diff --git sc/inc/table.hxx sc/inc/table.hxx
+index 8141561..4c7bae5 100644
+--- sc/inc/table.hxx
++++ sc/inc/table.hxx
+@@ -274,6 +274,7 @@ public:
+ { return aCol[rPos.Col()].GetCell( rPos.Row() ); }
+ ScBaseCell* GetCell( SCCOL nCol, SCROW nRow ) const;
+
++ void GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const;
+ void GetLastDataPos(SCCOL& rCol, SCROW& rRow) const;
+
+ BOOL TestInsertRow( SCCOL nStartCol, SCCOL nEndCol, SCSIZE nSize );
+@@ -656,6 +657,16 @@ private:
+ BOOL SearchAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark);
+ BOOL ReplaceAllStyle(const SvxSearchItem& rSearchItem, ScMarkData& rMark,
+ ScDocument* pUndoDoc);
++ bool SearchAndReplaceEmptyCells(
++ const SvxSearchItem& rSearchItem,
++ SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
++ String& rUndoStr, ScDocument* pUndoDoc);
++ bool SearchRangeForEmptyCell(const ScRange& rRange,
++ const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow,
++ String& rUndoStr, ScDocument* pUndoDoc);
++ bool SearchRangeForAllEmptyCells(const ScRange& rRange,
++ const SvxSearchItem& rSearchItem, ScMarkData& rMark,
++ String& rUndoStr, ScDocument* pUndoDoc);
+
+ // benutzen globalen SortParam:
+ BOOL IsSorted(SCCOLROW nStart, SCCOLROW nEnd);
+diff --git sc/source/core/data/column.cxx sc/source/core/data/column.cxx
+index 2c95181..9c8a55c 100644
+--- sc/source/core/data/column.cxx
++++ sc/source/core/data/column.cxx
+@@ -1476,7 +1476,24 @@ void ScColumn::CopyToColumn(SCROW nRow1, SCROW nRow2, USHORT nFlags, BOOL bMarke
+ }
+
+ if (pNew)
+- rColumn.Insert(pItems[i].nRow, pNew);
++ {
++ // Special case to allow removing of cell instances. A
++ // string cell with empty content is used to indicate an
++ // empty cell.
++ if (pNew->GetCellType() == CELLTYPE_STRING)
++ {
++ String aStr;
++ static_cast<ScStringCell*>(pNew)->GetString(aStr);
++ if (aStr.Len() == 0)
++ // A string cell with empty string. Delete the cell itself.
++ rColumn.Delete(pItems[i].nRow);
++ else
++ // non-empty string cell
++ rColumn.Insert(pItems[i].nRow, pNew);
++ }
++ else
++ rColumn.Insert(pItems[i].nRow, pNew);
++ }
+ }
+ }
+ }
+diff --git sc/source/core/data/table2.cxx sc/source/core/data/table2.cxx
+index ed7dc94..da620bf 100644
+--- sc/source/core/data/table2.cxx
++++ sc/source/core/data/table2.cxx
+@@ -923,6 +923,11 @@ ScBaseCell* ScTable::GetCell( SCCOL nCol, SCROW nRow ) const
+ return NULL;
+ }
+
++void ScTable::GetFirstDataPos(SCCOL& rCol, SCROW& rRow) const
++{
++ rCol = 0;
++ rRow = 0;
++}
+
+ void ScTable::GetLastDataPos(SCCOL& rCol, SCROW& rRow) const
+ {
+diff --git sc/source/core/data/table6.cxx sc/source/core/data/table6.cxx
+index 1ce8075..5650236 100644
+--- sc/source/core/data/table6.cxx
++++ sc/source/core/data/table6.cxx
+@@ -51,6 +51,8 @@
+ //--------------------------------------------------------------------------
+
+
++using ::com::sun::star::util::SearchOptions;
++
+ BOOL lcl_GetTextWithBreaks( const ScEditCell& rCell, ScDocument* pDoc, String& rVal )
+ {
+ // TRUE = more than 1 paragraph
+@@ -672,6 +674,12 @@ BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
+ com::sun::star::util::SearchOptions aSearchOptions = rSearchItem.GetSearchOptions();
+ aSearchOptions.Locale = *ScGlobal::pLocale;
+
++ if (!aSearchOptions.searchString.getLength())
++ {
++ // Search for empty cells.
++ return SearchAndReplaceEmptyCells(rSearchItem, rCol, rRow, rMark, rUndoStr, pUndoDoc);
++ }
++
+ // #107259# reflect UseAsianOptions flag in SearchOptions
+ // (use only ignore case and width if asian options are disabled).
+ // This is also done in SvxSearchDialog CommandHdl, but not in API object.
+@@ -698,6 +706,274 @@ BOOL ScTable::SearchAndReplace(const SvxSearchItem& rSearchItem,
+ return bFound;
+ }
+
++bool ScTable::SearchAndReplaceEmptyCells(
++ const SvxSearchItem& rSearchItem, SCCOL& rCol, SCROW& rRow, ScMarkData& rMark,
++ String& rUndoStr, ScDocument* pUndoDoc)
++{
++ SCCOL nColStart, nColEnd;
++ SCROW nRowStart, nRowEnd;
++ GetFirstDataPos(nColStart, nRowStart);
++ GetLastDataPos(nColEnd, nRowEnd);
++
++ ScRangeList aRanges;
++ aRanges.Append(ScRange(nColStart, nRowStart, nTab, nColEnd, nRowEnd, nTab));
++
++ if (rSearchItem.GetSelection())
++ {
++ // current selection only.
++ if (!rMark.IsMarked() && !rMark.IsMultiMarked())
++ // There is no selection. Bail out.
++ return false;
++
++ ScRangeList aMarkedRanges, aNewRanges;
++ rMark.FillRangeListWithMarks(&aMarkedRanges, true);
++ for (ScRangePtr p = aMarkedRanges.First(); p; p = aMarkedRanges.Next())
++ {
++ if (p->aStart.Col() > nColEnd || p->aStart.Row() > nRowEnd)
++ // This range is outside the data area. Skip it.
++ continue;
++
++ // Shrink the range into data area only.
++ if (p->aStart.Col() < nColStart)
++ p->aStart.SetCol(rCol);
++ if (p->aStart.Row() < nRowStart)
++ p->aStart.SetRow(rRow);
++
++ if (p->aEnd.Col() > nColEnd)
++ p->aEnd.SetCol(nColEnd);
++ if (p->aEnd.Row() > nRowEnd)
++ p->aEnd.SetRow(nRowEnd);
++
++ aNewRanges.Append(*p);
++ }
++ aRanges = aNewRanges;
++ }
++
++ sal_uInt16 nCommand = rSearchItem.GetCommand();
++ if (nCommand == SVX_SEARCHCMD_FIND || nCommand == SVX_SEARCHCMD_REPLACE)
++ {
++ if (rSearchItem.GetBackward())
++ {
++ for (ScRangePtr p = aRanges.Last(); p; p = aRanges.Prev())
++ {
++ if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
++ return true;
++ }
++ }
++ else
++ {
++ for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
++ {
++ if (SearchRangeForEmptyCell(*p, rSearchItem, rCol, rRow, rUndoStr, pUndoDoc))
++ return true;
++ }
++ }
++ }
++ else if (nCommand == SVX_SEARCHCMD_FIND_ALL || nCommand == SVX_SEARCHCMD_REPLACE_ALL)
++ {
++ bool bFound = false;
++ ScMarkData aNewMark(rMark);
++ aNewMark.ResetMark();
++ for (ScRangePtr p = aRanges.First(); p; p = aRanges.Next())
++ bFound |= SearchRangeForAllEmptyCells(*p, rSearchItem, aNewMark, rUndoStr, pUndoDoc);
++ rMark = aNewMark;
++ return bFound;
++ }
++ return false;
++}
++
++bool ScTable::SearchRangeForEmptyCell(
++ const ScRange& rRange, const SvxSearchItem& rSearchItem,
++ SCCOL& rCol, SCROW& rRow, String& rUndoStr, ScDocument* pUndoDoc)
++{
++ sal_uInt16 nCmd = rSearchItem.GetCommand();
++ if (rSearchItem.GetBackward())
++ {
++ // backward search
++ if (rSearchItem.GetRowDirection())
++ {
++ // row direction.
++ SCROW nBeginRow = rRange.aEnd.Row() > rRow ? rRow : rRange.aEnd.Row();
++ for (SCROW nRow = nBeginRow; nRow >= rRange.aStart.Row(); --nRow)
++ {
++ SCCOL nBeginCol = rRange.aEnd.Col();
++ if (nRow == rRow && nBeginCol >= rCol)
++ // always start from one cell before the cursor.
++ nBeginCol = rCol - (nCmd == SVX_SEARCHCMD_FIND) ? 1 : 0;
++
++ 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();
++ }
++ return true;
++ }
++ }
++ }
++ }
++ else
++ {
++ // column direction.
++ SCCOL nBeginCol = rRange.aEnd.Col() > rCol ? rCol : rRange.aEnd.Col();
++ for (SCCOL nCol = nBeginCol; nCol >= rRange.aStart.Col(); --nCol)
++ {
++ 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();
++ }
++ return true;
++ }
++ }
++ }
++ }
++ }
++ else
++ {
++ // forward search
++ if (rSearchItem.GetRowDirection())
++ {
++ // row direction.
++ SCROW nBeginRow = rRange.aStart.Row() < rRow ? rRow : rRange.aStart.Row();
++ for (SCROW nRow = nBeginRow; nRow <= rRange.aEnd.Row(); ++nRow)
++ {
++ 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();
++ }
++ return true;
++ }
++ }
++ }
++ }
++ else
++ {
++ // column direction.
++ SCCOL nBeginCol = rRange.aStart.Col() < rCol ? rCol : rRange.aStart.Col();
++ for (SCCOL nCol = nBeginCol; nCol <= rRange.aEnd.Col(); ++nCol)
++ {
++ 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();
++ }
++ return true;
++ }
++ }
++ }
++ }
++ }
++ return false;
++}
++
++bool ScTable::SearchRangeForAllEmptyCells(
++ const ScRange& rRange, const SvxSearchItem& rSearchItem, ScMarkData& rMark,
++ String& rUndoStr, ScDocument* pUndoDoc)
++{
++ bool bFound = false;
++ bool bReplace = (rSearchItem.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL) &&
++ (rSearchItem.GetReplaceString().Len() > 0);
++
++ for (SCCOL nCol = rRange.aStart.Col(); nCol <= rRange.aEnd.Col(); ++nCol)
++ {
++ 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)
++ {
++ const String& rNewStr = rSearchItem.GetReplaceString();
++ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
++ {
++ 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()));
++ }
++ rUndoStr = String();
++ }
++ continue;
++ }
++
++ for (SCROW nRow = rRange.aStart.Row(); nRow <= rRange.aEnd.Row(); ++nRow)
++ {
++ ScBaseCell* pCell = aCol[nCol].GetCell(nRow);
++ if (!pCell)
++ {
++ // empty cell found
++ rMark.SetMultiMarkArea(ScRange(nCol, nRow, nTab));
++ bFound = true;
++
++ if (bReplace)
++ {
++ aCol[nCol].Insert(nRow, new ScStringCell(rSearchItem.GetReplaceString()));
++ 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()));
++ }
++ }
++ }
++ }
++ return bFound;
++}
++
++
+
+
+
+diff --git sc/source/ui/view/tabvwsha.cxx sc/source/ui/view/tabvwsha.cxx
+index 3036eb9..6c60863 100644
+--- sc/source/ui/view/tabvwsha.cxx
++++ sc/source/ui/view/tabvwsha.cxx
+@@ -223,9 +223,15 @@ void __EXPORT ScTabViewShell::GetState( SfxItemSet& rSet )
+ GetViewData()->GetDocShell()->GetStatePageStyle( *this, rSet, nTab );
+ break;
+
+- case SID_SEARCH_ITEM:
+- rSet.Put( ScGlobal::GetSearchItem() );
+- break;
++ case SID_SEARCH_ITEM:
++ {
++ const ScMarkData& rMark = GetViewData()->GetMarkData();
++ SvxSearchItem aItem(ScGlobal::GetSearchItem()); // make a copy.
++ // Search on current selection if a range is marked.
++ aItem.SetSelection(rMark.IsMarked());
++ rSet.Put(aItem);
++ break;
++ }
+
+ case SID_SEARCH_OPTIONS:
+ {
Added: trunk/patches/dev300/calc-find-replace-empty-cells-svx.diff
==============================================================================
--- (empty file)
+++ trunk/patches/dev300/calc-find-replace-empty-cells-svx.diff Sun Feb 22 03:49:12 2009
@@ -0,0 +1,105 @@
+diff --git svx/inc/srchdlg.hxx svx/inc/srchdlg.hxx
+index 69b5315..5cf88d0 100644
+--- svx/inc/srchdlg.hxx
++++ svx/inc/srchdlg.hxx
+@@ -177,6 +177,8 @@ public:
+
+ INT32 GetTransliterationFlags() const;
+
++ void SetSaveToModule(bool b);
++
+ private:
+ FixedText aSearchText;
+ ComboBox aSearchLB;
+diff --git svx/source/dialog/srchdlg.cxx svx/source/dialog/srchdlg.cxx
+index d57c0a1..ddceeab 100644
+--- svx/source/dialog/srchdlg.cxx
++++ svx/source/dialog/srchdlg.cxx
+@@ -704,6 +704,11 @@ INT32 SvxSearchDialog::GetTransliterationFlags() const
+ return nTransliterationFlags;
+ }
+
++void SvxSearchDialog::SetSaveToModule(bool b)
++{
++ pImpl->bSaveToModule = b;
++}
++
+ // -----------------------------------------------------------------------
+
+ void SvxSearchDialog::ApplyTransliterationFlags_Impl( INT32 nSettings )
+@@ -956,9 +961,36 @@ void SvxSearchDialog::CalculateDelta_Impl()
+
+ // -----------------------------------------------------------------------
+
++namespace {
++
++class ToggleSaveToModule
++{
++public:
++ ToggleSaveToModule(SvxSearchDialog& rDialog, bool bValue) :
++ mrDialog(rDialog), mbValue(bValue)
++ {
++ mrDialog.SetSaveToModule(mbValue);
++ }
++
++ ~ToggleSaveToModule()
++ {
++ mrDialog.SetSaveToModule(!mbValue);
++ }
++private:
++ SvxSearchDialog& mrDialog;
++ bool mbValue;
++};
++
++}
++
+ void SvxSearchDialog::Init_Impl( int bSearchPattern )
+ {
+ DBG_ASSERT( pSearchItem, "SearchItem == 0" );
++
++ // We don't want to save any intermediate state to the module while the
++ // dialog is being initialized.
++ ToggleSaveToModule aNoModuleSave(*this, false);
++
+ bWriter = ( pSearchItem->GetAppFlag() == SVX_SEARCHAPP_WRITER );
+
+ pImpl->bMultiLineEdit = FALSE;
+@@ -1106,10 +1138,8 @@ void SvxSearchDialog::Init_Impl( int bSearchPattern )
+ aSimilarityBox.Check( pSearchItem->IsLevenshtein() );
+ bSet = TRUE;
+
+- pImpl->bSaveToModule = FALSE;
+ FlagHdl_Impl( &aSimilarityBox );
+ FlagHdl_Impl( &aJapOptionsCB );
+- pImpl->bSaveToModule = TRUE;
+
+ FASTBOOL bDisableSearch = FALSE;
+ SfxViewShell* pViewShell = SfxViewShell::Current();
+@@ -1638,16 +1668,23 @@ IMPL_LINK( SvxSearchDialog, ModifyHdl_Impl, ComboBox *, pEd )
+ else
+ bSet = FALSE;
+
++ // Calc allows searching for empty cells.
++ bool bAllowEmptySearch = (pSearchItem->GetAppFlag() == SVX_SEARCHAPP_CALC);
++
+ if ( pEd == &aSearchLB || pEd == &aReplaceLB )
+ {
+- xub_StrLen nLBTxtLen = aSearchLB.GetText().Len(), nTxtLen;
++ xub_StrLen nSrchTxtLen = aSearchLB.GetText().Len();
++ xub_StrLen nReplTxtLen = 0;
++ if (bAllowEmptySearch)
++ nReplTxtLen = aReplaceLB.GetText().Len();
++ xub_StrLen nAttrTxtLen = 0;
+
+ if ( !pImpl->bMultiLineEdit )
+- nTxtLen = aSearchAttrText.GetText().Len();
++ nAttrTxtLen = aSearchAttrText.GetText().Len();
+ else
+- nTxtLen = pImpl->aSearchFormats.GetText().Len();
++ nAttrTxtLen = pImpl->aSearchFormats.GetText().Len();
+
+- if ( nLBTxtLen || nTxtLen )
++ if (nSrchTxtLen || nReplTxtLen || nAttrTxtLen)
+ {
+ EnableControl_Impl( &aSearchBtn );
+ EnableControl_Impl( &aReplaceBtn );
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]