ooo-build r15396 - in trunk: . patches/dev300



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]