1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: table6.cxx,v $
10 * $Revision: 1.18.128.3 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
34 // INCLUDE ---------------------------------------------------------------
36 #include <com/sun/star/i18n/TransliterationModules.hpp>
38 #include <unotools/textsearch.hxx>
39 #include <svx/srchitem.hxx>
40 #include <svx/editobj.hxx>
43 #include "collect.hxx"
45 #include "document.hxx"
46 #include "stlpool.hxx"
47 #include "markdata.hxx"
48 #include "editutil.hxx"
49 #include "detfunc.hxx"
52 //--------------------------------------------------------------------------
55 using ::com::sun::star::util::SearchOptions
;
57 BOOL
lcl_GetTextWithBreaks( const ScEditCell
& rCell
, ScDocument
* pDoc
, String
& rVal
)
59 // TRUE = more than 1 paragraph
61 const EditTextObject
* pData
= NULL
;
62 rCell
.GetData( pData
);
63 EditEngine
& rEngine
= pDoc
->GetEditEngine();
64 rEngine
.SetText( *pData
);
65 rVal
= rEngine
.GetText( LINEEND_LF
);
66 return ( rEngine
.GetParagraphCount() > 1 );
69 BOOL
ScTable::SearchCell(const SvxSearchItem
& rSearchItem
, SCCOL nCol
, SCROW nRow
,
70 const ScMarkData
& rMark
, String
& rUndoStr
, ScDocument
* pUndoDoc
)
73 BOOL bDoSearch
= TRUE
;
74 BOOL bDoBack
= rSearchItem
.GetBackward();
78 if (rSearchItem
.GetSelection())
79 bDoSearch
= rMark
.IsCellMarked(nCol
, nRow
);
80 if ( bDoSearch
&& ((pCell
= aCol
[nCol
].GetCell( nRow
)) != NULL
) )
82 BOOL bMultiLine
= FALSE
;
83 CellType eCellType
= pCell
->GetCellType();
84 switch (rSearchItem
.GetCellType())
86 case SVX_SEARCHIN_FORMULA
:
88 if ( eCellType
== CELLTYPE_FORMULA
)
89 ((ScFormulaCell
*)pCell
)->GetFormula( aString
,
90 formula::FormulaGrammar::GRAM_NATIVE_UI
);
91 else if ( eCellType
== CELLTYPE_EDIT
)
92 bMultiLine
= lcl_GetTextWithBreaks(
93 *(const ScEditCell
*)pCell
, pDocument
, aString
);
95 aCol
[nCol
].GetInputString( nRow
, aString
);
98 case SVX_SEARCHIN_VALUE
:
99 if ( eCellType
== CELLTYPE_EDIT
)
100 bMultiLine
= lcl_GetTextWithBreaks(
101 *(const ScEditCell
*)pCell
, pDocument
, aString
);
103 aCol
[nCol
].GetInputString( nRow
, aString
);
105 case SVX_SEARCHIN_NOTE
:
107 if(const ScPostIt
* pNote
= pCell
->GetNote())
109 aString
= pNote
->GetText();
110 bMultiLine
= pNote
->HasMultiLineText();
117 xub_StrLen nStart
= 0;
118 xub_StrLen nEnd
= aString
.Len();
119 ::com::sun::star::util::SearchResult aSearchResult
;
124 xub_StrLen nTemp
=nStart
; nStart
=nEnd
; nEnd
=nTemp
;
125 bFound
= (BOOL
)(pSearchText
->SearchBkwrd(aString
, &nStart
, &nEnd
, &aSearchResult
));
126 // change results to definition before 614:
131 bFound
= (BOOL
)(pSearchText
->SearchFrwrd(aString
, &nStart
, &nEnd
, &aSearchResult
));
132 // change results to definition before 614:
136 if (bFound
&& rSearchItem
.GetWordOnly())
137 bFound
= (nStart
== 0 && nEnd
== aString
.Len() - 1);
141 DBG_ERROR("pSearchText == NULL");
145 BYTE cMatrixFlag
= MM_NONE
;
147 ( (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
)
148 ||(rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL
) ) &&
149 // #60558# Matrix nicht zerreissen, nur Matrixformel ersetzen
150 !( (eCellType
== CELLTYPE_FORMULA
&&
151 ((cMatrixFlag
= ((ScFormulaCell
*)pCell
)->GetMatrixFlag()) == MM_REFERENCE
))
152 // kein UndoDoc => Matrix nicht wiederherstellbar => nicht ersetzen
153 || (cMatrixFlag
!= MM_NONE
&& !pUndoDoc
) )
156 if ( cMatrixFlag
== MM_NONE
&& rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
)
160 ScAddress
aAdr( nCol
, nRow
, nTab
);
161 ScBaseCell
* pUndoCell
= pCell
->CloneWithoutNote( *pUndoDoc
);
162 pUndoDoc
->PutCell( aAdr
, pUndoCell
);
164 BOOL bRepeat
= !rSearchItem
.GetWordOnly();
167 // wenn der gefundene Text leer ist, nicht weitersuchen,
168 // sonst wuerde man nie mehr aufhoeren (#35410#)
169 if ( nEnd
< nStart
|| nEnd
== STRING_MAXLEN
)
172 String sReplStr
= rSearchItem
.GetReplaceString();
173 if (rSearchItem
.GetRegExp())
175 String sFndStr
= aString
.Copy(nStart
, nEnd
-nStart
+1);
176 pSearchText
->ReplaceBackReferences( sReplStr
, aString
, aSearchResult
);
177 aString
.Erase(nStart
, nEnd
-nStart
+1);
178 aString
.Insert(sReplStr
, nStart
);
182 aString
.Erase(nStart
, nEnd
- nStart
+ 1);
183 aString
.Insert(rSearchItem
.GetReplaceString(), nStart
);
194 nStart
= sal::static_int_cast
<xub_StrLen
>( nStart
+ sReplStr
.Len() );
195 nEnd
= aString
.Len();
201 if ( rSearchItem
.GetCommand() != SVX_SEARCHCMD_REPLACE_ALL
|| nStart
>= nEnd
)
205 xub_StrLen nTemp
=nStart
; nStart
=nEnd
; nEnd
=nTemp
;
206 bRepeat
= ((BOOL
)(pSearchText
->SearchBkwrd(aString
, &nStart
, &nEnd
)));
207 // change results to definition before 614:
212 bRepeat
= ((BOOL
)(pSearchText
->SearchFrwrd(aString
, &nStart
, &nEnd
)));
213 // change results to definition before 614:
219 if (rSearchItem
.GetCellType() == SVX_SEARCHIN_NOTE
)
221 // NB: rich text format is lost.
222 // This is also true of Cells.
223 if( ScPostIt
* pNote
= pCell
->GetNote() )
224 pNote
->SetText( ScAddress( nCol
, nRow
, nTab
), aString
);
226 else if ( cMatrixFlag
!= MM_NONE
)
227 { // #60558# Matrix nicht zerreissen
228 if ( aString
.Len() > 2 )
229 { // {} raus, erst hier damit auch "{=" durch "{=..." ersetzt werden kann
230 if ( aString
.GetChar( aString
.Len()-1 ) == '}' )
231 aString
.Erase( aString
.Len()-1, 1 );
232 if ( aString
.GetChar(0) == '{' )
233 aString
.Erase( 0, 1 );
235 ScAddress
aAdr( nCol
, nRow
, nTab
);
236 ScFormulaCell
* pFCell
= new ScFormulaCell( pDocument
, aAdr
,
237 aString
,formula::FormulaGrammar::GRAM_NATIVE_UI
, cMatrixFlag
);
240 ((ScFormulaCell
*)pCell
)->GetMatColsRows( nMatCols
, nMatRows
);
241 pFCell
->SetMatColsRows( nMatCols
, nMatRows
);
242 aCol
[nCol
].Insert( nRow
, pFCell
);
244 else if ( bMultiLine
&& aString
.Search('\n') != STRING_NOTFOUND
)
245 PutCell( nCol
, nRow
, new ScEditCell( aString
, pDocument
) );
247 aCol
[nCol
].SetString(nRow
, nTab
, aString
);
248 // pCell is invalid now (deleted)
254 BOOL
ScTable::Search(const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
,
255 const ScMarkData
& rMark
, String
& rUndoStr
, ScDocument
* pUndoDoc
)
258 BOOL bAll
= (rSearchItem
.GetCommand() == SVX_SEARCHCMD_FIND_ALL
)
259 ||(rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL
);
264 GetLastDataPos(nLastCol
, nLastRow
);
265 if (!bAll
&& rSearchItem
.GetBackward())
267 nCol
= Min(nCol
, (SCCOL
)(nLastCol
+ 1));
268 nRow
= Min(nRow
, (SCROW
)(nLastRow
+ 1));
269 if (rSearchItem
.GetRowDirection())
272 while (!bFound
&& ((SCsROW
)nRow
>= 0))
274 while (!bFound
&& ((SCsCOL
)nCol
>= 0))
276 bFound
= SearchCell(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
283 if ((SCsCOL
)nCol
>= 0)
284 bIsEmpty
= aCol
[nCol
].IsEmptyData();
288 while (((SCsCOL
)nCol
>= 0) && bIsEmpty
);
301 while (!bFound
&& ((SCsCOL
)nCol
>= 0))
303 while (!bFound
&& ((SCsROW
)nRow
>= 0))
305 bFound
= SearchCell(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
308 if (!aCol
[nCol
].GetPrevDataPos(nRow
))
319 if ((SCsCOL
)nCol
>= 0)
320 bIsEmpty
= aCol
[nCol
].IsEmptyData();
324 while (((SCsCOL
)nCol
>= 0) && bIsEmpty
);
331 if (!bAll
&& rSearchItem
.GetRowDirection())
334 while (!bFound
&& (nRow
<= nLastRow
))
336 while (!bFound
&& (nCol
<= nLastCol
))
338 bFound
= SearchCell(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
342 while ((nCol
<= nLastCol
) && aCol
[nCol
].IsEmptyData()) nCol
++;
355 while (!bFound
&& (nCol
<= nLastCol
))
357 while (!bFound
&& (nRow
<= nLastRow
))
359 bFound
= SearchCell(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
362 if (!aCol
[nCol
].GetNextDataPos(nRow
))
370 while ((nCol
<= nLastCol
) && aCol
[nCol
].IsEmptyData()) nCol
++;
383 BOOL
ScTable::SearchAll(const SvxSearchItem
& rSearchItem
, ScMarkData
& rMark
,
384 String
& rUndoStr
, ScDocument
* pUndoDoc
)
390 ScMarkData
aNewMark( rMark
); // Tabellen-Markierungen kopieren
391 aNewMark
.ResetMark();
394 bFound
= Search(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
396 aNewMark
.SetMultiMarkArea( ScRange( nCol
, nRow
, nTab
) );
400 rMark
= aNewMark
; // Markierung kopieren
403 return (aNewMark
.IsMultiMarked());
406 BOOL
ScTable::Replace(const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
,
407 const ScMarkData
& rMark
, String
& rUndoStr
, ScDocument
* pUndoDoc
)
412 if (rSearchItem
.GetBackward())
414 if (rSearchItem
.GetRowDirection())
421 if (rSearchItem
.GetRowDirection())
426 bFound
= Search(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
435 BOOL
ScTable::ReplaceAll(const SvxSearchItem
& rSearchItem
, ScMarkData
& rMark
,
436 String
& rUndoStr
, ScDocument
* pUndoDoc
)
438 BOOL bOldDouble
= ScColumn::bDoubleAlloc
; // sollte immer FALSE sein?
439 DBG_ASSERT(!bOldDouble
,"bDoubleAlloc ???");
440 ScColumn::bDoubleAlloc
= TRUE
; // fuer Undo-Doc
446 ScMarkData
aNewMark( rMark
); // Tabellen-Markierungen kopieren
447 aNewMark
.ResetMark();
450 bFound
= Search(rSearchItem
, nCol
, nRow
, rMark
, rUndoStr
, pUndoDoc
);
452 aNewMark
.SetMultiMarkArea( ScRange( nCol
, nRow
, nTab
) );
456 ScColumn::bDoubleAlloc
= bOldDouble
;
458 rMark
= aNewMark
; // Markierung kopieren
461 return (aNewMark
.IsMultiMarked());
464 BOOL
ScTable::SearchStyle(const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
,
467 const ScStyleSheet
* pSearchStyle
= (const ScStyleSheet
*)
468 pDocument
->GetStyleSheetPool()->Find(
469 rSearchItem
.GetSearchString(), SFX_STYLE_FAMILY_PARA
);
475 BOOL bSelect
= rSearchItem
.GetSelection();
476 BOOL bRows
= rSearchItem
.GetRowDirection();
477 BOOL bBack
= rSearchItem
.GetBackward();
478 short nAdd
= bBack
? -1 : 1;
480 if (bRows
) // zeilenweise
485 SCsROW nNextRow
= aCol
[nCol
].SearchStyle( nRow
, pSearchStyle
, bBack
, bSelect
, rMark
);
486 if (!ValidRow(nNextRow
))
488 nRow
= bBack
? MAXROW
: 0;
489 nCol
= sal::static_int_cast
<SCsCOL
>( nCol
+ nAdd
);
497 while (!bFound
&& ValidCol(nCol
));
501 SCsROW nNextRows
[MAXCOLCOUNT
];
503 for (i
=0; i
<=MAXCOL
; i
++)
506 if (bBack
) { if (i
>=nCol
) --nSRow
; }
507 else { if (i
<=nCol
) ++nSRow
; }
508 nNextRows
[i
] = aCol
[i
].SearchStyle( nSRow
, pSearchStyle
, bBack
, bSelect
, rMark
);
510 if (bBack
) // rueckwaerts
513 for (i
=MAXCOL
; i
>=0; i
--)
514 if (nNextRows
[i
]>nRow
)
524 for (i
=0; i
<=MAXCOL
; i
++)
525 if (nNextRows
[i
]<nRow
)
542 //! einzelnes Pattern fuer Undo zurueckgeben
544 BOOL
ScTable::ReplaceStyle(const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
,
545 ScMarkData
& rMark
, BOOL bIsUndo
)
551 bRet
= SearchStyle(rSearchItem
, rCol
, rRow
, rMark
);
554 const ScStyleSheet
* pReplaceStyle
= (const ScStyleSheet
*)
555 pDocument
->GetStyleSheetPool()->Find(
556 rSearchItem
.GetReplaceString(), SFX_STYLE_FAMILY_PARA
);
559 ApplyStyle( rCol
, rRow
, *pReplaceStyle
);
562 DBG_ERROR("pReplaceStyle==0");
569 BOOL
ScTable::SearchAllStyle(const SvxSearchItem
& rSearchItem
, ScMarkData
& rMark
)
571 const ScStyleSheet
* pSearchStyle
= (const ScStyleSheet
*)
572 pDocument
->GetStyleSheetPool()->Find(
573 rSearchItem
.GetSearchString(), SFX_STYLE_FAMILY_PARA
);
574 BOOL bSelect
= rSearchItem
.GetSelection();
575 BOOL bBack
= rSearchItem
.GetBackward();
577 ScMarkData
aNewMark( rMark
); // Tabellen-Markierungen kopieren
578 aNewMark
.ResetMark();
579 for (SCCOL i
=0; i
<=MAXCOL
; i
++)
584 while (bFound
&& nRow
<= MAXROW
)
586 bFound
= aCol
[i
].SearchStyleRange( nRow
, nEndRow
, pSearchStyle
, bBack
, bSelect
, rMark
);
595 aNewMark
.SetMultiMarkArea( ScRange( i
,nRow
,nTab
, i
,nEndRow
,nTab
) );
601 rMark
= aNewMark
; // Markierung kopieren
604 return (aNewMark
.IsMultiMarked());
607 BOOL
ScTable::ReplaceAllStyle(const SvxSearchItem
& rSearchItem
, ScMarkData
& rMark
,
608 ScDocument
* pUndoDoc
)
610 BOOL bRet
= SearchAllStyle(rSearchItem
, rMark
);
613 const ScStyleSheet
* pReplaceStyle
= (const ScStyleSheet
*)
614 pDocument
->GetStyleSheetPool()->Find(
615 rSearchItem
.GetReplaceString(), SFX_STYLE_FAMILY_PARA
);
620 pDocument
->CopyToDocument( 0,0,nTab
, MAXCOL
,MAXROW
,nTab
,
621 IDF_ATTRIB
, TRUE
, pUndoDoc
, &rMark
);
622 ApplySelectionStyle( *pReplaceStyle
, rMark
);
626 DBG_ERROR("pReplaceStyle==0");
633 BOOL
ScTable::SearchAndReplace(const SvxSearchItem
& rSearchItem
,
634 SCCOL
& rCol
, SCROW
& rRow
, ScMarkData
& rMark
,
635 String
& rUndoStr
, ScDocument
* pUndoDoc
)
637 USHORT nCommand
= rSearchItem
.GetCommand();
639 if ( ValidColRow(rCol
, rRow
) ||
640 ((nCommand
== SVX_SEARCHCMD_FIND
|| nCommand
== SVX_SEARCHCMD_REPLACE
) &&
641 (((rCol
== MAXCOLCOUNT
|| rCol
== -1) && VALIDROW(rRow
)) ||
642 ((rRow
== MAXROWCOUNT
|| rRow
== -1) && VALIDCOL(rCol
))
647 BOOL bStyles
= rSearchItem
.GetPattern();
650 if (nCommand
== SVX_SEARCHCMD_FIND
)
651 bFound
= SearchStyle(rSearchItem
, rCol
, rRow
, rMark
);
652 else if (nCommand
== SVX_SEARCHCMD_REPLACE
)
653 bFound
= ReplaceStyle(rSearchItem
, rCol
, rRow
, rMark
, FALSE
);
654 else if (nCommand
== SVX_SEARCHCMD_FIND_ALL
)
655 bFound
= SearchAllStyle(rSearchItem
, rMark
);
656 else if (nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
657 bFound
= ReplaceAllStyle(rSearchItem
, rMark
, pUndoDoc
);
661 // SearchParam no longer needed - SearchOptions contains all settings
662 com::sun::star::util::SearchOptions aSearchOptions
= rSearchItem
.GetSearchOptions();
663 aSearchOptions
.Locale
= *ScGlobal::pLocale
;
665 if (!aSearchOptions
.searchString
.getLength())
667 // Search for empty cells.
668 return SearchAndReplaceEmptyCells(rSearchItem
, rCol
, rRow
, rMark
, rUndoStr
, pUndoDoc
);
671 // #107259# reflect UseAsianOptions flag in SearchOptions
672 // (use only ignore case and width if asian options are disabled).
673 // This is also done in SvxSearchDialog CommandHdl, but not in API object.
674 if ( !rSearchItem
.IsUseAsianOptions() )
675 aSearchOptions
.transliterateFlags
&=
676 ( com::sun::star::i18n::TransliterationModules_IGNORE_CASE
|
677 com::sun::star::i18n::TransliterationModules_IGNORE_WIDTH
);
679 pSearchText
= new utl::TextSearch( aSearchOptions
);
681 if (nCommand
== SVX_SEARCHCMD_FIND
)
682 bFound
= Search(rSearchItem
, rCol
, rRow
, rMark
, rUndoStr
, pUndoDoc
);
683 else if (nCommand
== SVX_SEARCHCMD_FIND_ALL
)
684 bFound
= SearchAll(rSearchItem
, rMark
, rUndoStr
, pUndoDoc
);
685 else if (nCommand
== SVX_SEARCHCMD_REPLACE
)
686 bFound
= Replace(rSearchItem
, rCol
, rRow
, rMark
, rUndoStr
, pUndoDoc
);
687 else if (nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
688 bFound
= ReplaceAll(rSearchItem
, rMark
, rUndoStr
, pUndoDoc
);
697 bool ScTable::SearchAndReplaceEmptyCells(
698 const SvxSearchItem
& rSearchItem
, SCCOL
& rCol
, SCROW
& rRow
, ScMarkData
& rMark
,
699 String
& rUndoStr
, ScDocument
* pUndoDoc
)
701 SCCOL nColStart
, nColEnd
;
702 SCROW nRowStart
, nRowEnd
;
703 GetFirstDataPos(nColStart
, nRowStart
);
704 GetLastDataPos(nColEnd
, nRowEnd
);
707 aRanges
.Append(ScRange(nColStart
, nRowStart
, nTab
, nColEnd
, nRowEnd
, nTab
));
709 if (rSearchItem
.GetSelection())
711 // current selection only.
712 if (!rMark
.IsMarked() && !rMark
.IsMultiMarked())
713 // There is no selection. Bail out.
716 ScRangeList aMarkedRanges
, aNewRanges
;
717 rMark
.FillRangeListWithMarks(&aMarkedRanges
, true);
718 for (ScRangePtr p
= aMarkedRanges
.First(); p
; p
= aMarkedRanges
.Next())
720 if (p
->aStart
.Col() > nColEnd
|| p
->aStart
.Row() > nRowEnd
)
721 // This range is outside the data area. Skip it.
724 // Shrink the range into data area only.
725 if (p
->aStart
.Col() < nColStart
)
726 p
->aStart
.SetCol(rCol
);
727 if (p
->aStart
.Row() < nRowStart
)
728 p
->aStart
.SetRow(rRow
);
730 if (p
->aEnd
.Col() > nColEnd
)
731 p
->aEnd
.SetCol(nColEnd
);
732 if (p
->aEnd
.Row() > nRowEnd
)
733 p
->aEnd
.SetRow(nRowEnd
);
735 aNewRanges
.Append(*p
);
737 aRanges
= aNewRanges
;
740 sal_uInt16 nCommand
= rSearchItem
.GetCommand();
741 if (nCommand
== SVX_SEARCHCMD_FIND
|| nCommand
== SVX_SEARCHCMD_REPLACE
)
743 if (rSearchItem
.GetBackward())
745 for (ScRangePtr p
= aRanges
.Last(); p
; p
= aRanges
.Prev())
747 if (SearchRangeForEmptyCell(*p
, rSearchItem
, rCol
, rRow
, rUndoStr
, pUndoDoc
))
753 for (ScRangePtr p
= aRanges
.First(); p
; p
= aRanges
.Next())
755 if (SearchRangeForEmptyCell(*p
, rSearchItem
, rCol
, rRow
, rUndoStr
, pUndoDoc
))
760 else if (nCommand
== SVX_SEARCHCMD_FIND_ALL
|| nCommand
== SVX_SEARCHCMD_REPLACE_ALL
)
763 ScMarkData
aNewMark(rMark
);
764 aNewMark
.ResetMark();
765 for (ScRangePtr p
= aRanges
.First(); p
; p
= aRanges
.Next())
766 bFound
|= SearchRangeForAllEmptyCells(*p
, rSearchItem
, aNewMark
, rUndoStr
, pUndoDoc
);
773 bool ScTable::SearchRangeForEmptyCell(
774 const ScRange
& rRange
, const SvxSearchItem
& rSearchItem
,
775 SCCOL
& rCol
, SCROW
& rRow
, String
& rUndoStr
, ScDocument
* /*pUndoDoc*/)
777 sal_uInt16 nCmd
= rSearchItem
.GetCommand();
778 if (rSearchItem
.GetBackward())
781 if (rSearchItem
.GetRowDirection())
784 SCROW nBeginRow
= rRange
.aEnd
.Row() > rRow
? rRow
: rRange
.aEnd
.Row();
785 for (SCROW nRow
= nBeginRow
; nRow
>= rRange
.aStart
.Row(); --nRow
)
787 SCCOL nBeginCol
= rRange
.aEnd
.Col();
788 if (nRow
== rRow
&& nBeginCol
>= rCol
)
789 // always start from one cell before the cursor.
790 nBeginCol
= rCol
- (nCmd
== SVX_SEARCHCMD_FIND
) ? 1 : 0;
792 for (SCCOL nCol
= nBeginCol
; nCol
>= rRange
.aStart
.Col(); --nCol
)
794 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
800 if (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
&&
801 rSearchItem
.GetReplaceString().Len())
803 aCol
[nCol
].Insert(nRow
, new ScStringCell(rSearchItem
.GetReplaceString()));
814 SCCOL nBeginCol
= rRange
.aEnd
.Col() > rCol
? rCol
: rRange
.aEnd
.Col();
815 for (SCCOL nCol
= nBeginCol
; nCol
>= rRange
.aStart
.Col(); --nCol
)
817 SCROW nBeginRow
= rRange
.aEnd
.Row();
818 if (nCol
== rCol
&& nBeginRow
>= rRow
)
819 // always start from one cell before the cursor.
820 nBeginRow
= rRow
- (nCmd
== SVX_SEARCHCMD_FIND
) ? 1 : 0;
821 for (SCROW nRow
= nBeginRow
; nRow
>= rRange
.aStart
.Row(); --nRow
)
823 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
829 if (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
&&
830 rSearchItem
.GetReplaceString().Len())
832 aCol
[nCol
].Insert(nRow
, new ScStringCell(rSearchItem
.GetReplaceString()));
844 if (rSearchItem
.GetRowDirection())
847 SCROW nBeginRow
= rRange
.aStart
.Row() < rRow
? rRow
: rRange
.aStart
.Row();
848 for (SCROW nRow
= nBeginRow
; nRow
<= rRange
.aEnd
.Row(); ++nRow
)
850 SCCOL nBeginCol
= rRange
.aStart
.Col();
851 if (nRow
== rRow
&& nBeginCol
<= rCol
)
852 // always start from one cell past the cursor.
853 nBeginCol
= rCol
+ (nCmd
== SVX_SEARCHCMD_FIND
) ? 1 : 0;
854 for (SCCOL nCol
= nBeginCol
; nCol
<= rRange
.aEnd
.Col(); ++nCol
)
856 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
862 if (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
&&
863 rSearchItem
.GetReplaceString().Len())
865 aCol
[nCol
].Insert(nRow
, new ScStringCell(rSearchItem
.GetReplaceString()));
876 SCCOL nBeginCol
= rRange
.aStart
.Col() < rCol
? rCol
: rRange
.aStart
.Col();
877 for (SCCOL nCol
= nBeginCol
; nCol
<= rRange
.aEnd
.Col(); ++nCol
)
879 SCROW nBeginRow
= rRange
.aStart
.Row();
880 if (nCol
== rCol
&& nBeginRow
<= rRow
)
881 // always start from one cell past the cursor.
882 nBeginRow
= rRow
+ (nCmd
== SVX_SEARCHCMD_FIND
) ? 1 : 0;
883 for (SCROW nRow
= nBeginRow
; nRow
<= rRange
.aEnd
.Row(); ++nRow
)
885 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
891 if (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE
&&
892 rSearchItem
.GetReplaceString().Len())
894 aCol
[nCol
].Insert(nRow
, new ScStringCell(rSearchItem
.GetReplaceString()));
906 bool ScTable::SearchRangeForAllEmptyCells(
907 const ScRange
& rRange
, const SvxSearchItem
& rSearchItem
, ScMarkData
& rMark
,
908 String
& rUndoStr
, ScDocument
* pUndoDoc
)
911 bool bReplace
= (rSearchItem
.GetCommand() == SVX_SEARCHCMD_REPLACE_ALL
) &&
912 (rSearchItem
.GetReplaceString().Len() > 0);
914 for (SCCOL nCol
= rRange
.aStart
.Col(); nCol
<= rRange
.aEnd
.Col(); ++nCol
)
916 if (aCol
[nCol
].IsEmptyData())
918 // The entire column is empty. Add the whole column and move on.
919 rMark
.SetMultiMarkArea(
920 ScRange(nCol
, rRange
.aStart
.Row(), nTab
, nCol
, rRange
.aEnd
.Row(), nTab
));
925 const String
& rNewStr
= rSearchItem
.GetReplaceString();
926 for (SCROW nRow
= rRange
.aStart
.Row(); nRow
<= rRange
.aEnd
.Row(); ++nRow
)
928 aCol
[nCol
].Insert(nRow
, new ScStringCell(rNewStr
));
930 // TODO: I'm using a string cell with empty content to
931 // trigger deletion of cell instance on undo. Maybe I
932 // should create a new cell type for this?
933 pUndoDoc
->PutCell(nCol
, nRow
, nTab
, new ScStringCell(String()));
940 for (SCROW nRow
= rRange
.aStart
.Row(); nRow
<= rRange
.aEnd
.Row(); ++nRow
)
942 ScBaseCell
* pCell
= aCol
[nCol
].GetCell(nRow
);
946 rMark
.SetMultiMarkArea(ScRange(nCol
, nRow
, nTab
));
951 aCol
[nCol
].Insert(nRow
, new ScStringCell(rSearchItem
.GetReplaceString()));
953 // TODO: I'm using a string cell with empty content to
954 // trigger deletion of cell instance on undo. Maybe I
955 // should create a new cell type for this?
956 pUndoDoc
->PutCell(nCol
, nRow
, nTab
, new ScStringCell(String()));