1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3efeef26fSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist * or more contributor license agreements. See the NOTICE file
5efeef26fSAndrew Rist * distributed with this work for additional information
6efeef26fSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7efeef26fSAndrew Rist * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist * with the License. You may obtain a copy of the License at
10cdf0e10cSrcweir *
11efeef26fSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir *
13efeef26fSAndrew Rist * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist * software distributed under the License is distributed on an
15efeef26fSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist * KIND, either express or implied. See the License for the
17efeef26fSAndrew Rist * specific language governing permissions and limitations
18efeef26fSAndrew Rist * under the License.
19cdf0e10cSrcweir *
20efeef26fSAndrew Rist *************************************************************/
21efeef26fSAndrew Rist
22efeef26fSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
29cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hpp>
30cdf0e10cSrcweir #include <com/sun/star/util/SearchFlags.hpp>
31cdf0e10cSrcweir #include <i18npool/mslangid.hxx>
32cdf0e10cSrcweir #include <hintids.hxx>
33cdf0e10cSrcweir #include <vcl/svapp.hxx>
34cdf0e10cSrcweir #include <svl/itemiter.hxx>
35cdf0e10cSrcweir #include <svl/whiter.hxx>
36cdf0e10cSrcweir #include <editeng/brkitem.hxx>
37cdf0e10cSrcweir #include <editeng/colritem.hxx>
38cdf0e10cSrcweir #include <editeng/fontitem.hxx>
39cdf0e10cSrcweir #include <fmtpdsc.hxx>
40cdf0e10cSrcweir #include <txatbase.hxx>
41cdf0e10cSrcweir #include <fchrfmt.hxx>
42cdf0e10cSrcweir #include <charfmt.hxx>
43cdf0e10cSrcweir #include <doc.hxx>
44cdf0e10cSrcweir #include <IDocumentUndoRedo.hxx>
45cdf0e10cSrcweir #include <swcrsr.hxx>
46cdf0e10cSrcweir #include <editsh.hxx>
47cdf0e10cSrcweir #include <ndtxt.hxx>
48cdf0e10cSrcweir #include <pamtyp.hxx>
49cdf0e10cSrcweir #include <swundo.hxx>
50cdf0e10cSrcweir #include <crsskip.hxx>
51cdf0e10cSrcweir
52cdf0e10cSrcweir
53cdf0e10cSrcweir using namespace ::com::sun::star;
54cdf0e10cSrcweir using namespace ::com::sun::star::lang;
55cdf0e10cSrcweir using namespace ::com::sun::star::util;
56cdf0e10cSrcweir
57cdf0e10cSrcweir SV_DECL_PTRARR_SORT( SwpFmts, SwFmt*, 0, 4 )
SV_IMPL_PTRARR_SORT(SwpFmts,SwFmt *)58cdf0e10cSrcweir SV_IMPL_PTRARR_SORT( SwpFmts, SwFmt* )
59cdf0e10cSrcweir
60cdf0e10cSrcweir // Sonderbehandlung fuer SvxFontItem, nur den Namen vergleichen:
61cdf0e10cSrcweir int CmpAttr( const SfxPoolItem& rItem1, const SfxPoolItem& rItem2 )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir switch( rItem1.Which() )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir case RES_CHRATR_FONT:
66cdf0e10cSrcweir return ((SvxFontItem&)rItem1).GetFamilyName() ==
67cdf0e10cSrcweir ((SvxFontItem&)rItem2).GetFamilyName();
68cdf0e10cSrcweir
69cdf0e10cSrcweir case RES_CHRATR_COLOR:
70cdf0e10cSrcweir return ((SvxColorItem&)rItem1).GetValue().IsRGBEqual(
71cdf0e10cSrcweir ((SvxColorItem&)rItem2).GetValue() );
72cdf0e10cSrcweir case RES_PAGEDESC:
73cdf0e10cSrcweir return ((SwFmtPageDesc&)rItem1).GetNumOffset() ==
74cdf0e10cSrcweir ((SwFmtPageDesc&)rItem2).GetNumOffset() &&
75cdf0e10cSrcweir ((SwFmtPageDesc&)rItem1).GetPageDesc() ==
76cdf0e10cSrcweir ((SwFmtPageDesc&)rItem2).GetPageDesc();
77cdf0e10cSrcweir }
78cdf0e10cSrcweir return rItem1 == rItem2;
79cdf0e10cSrcweir }
80cdf0e10cSrcweir
81cdf0e10cSrcweir
GetFrwrdTxtHint(const SwpHints & rHtsArr,sal_uInt16 & rPos,xub_StrLen nCntntPos)82cdf0e10cSrcweir const SwTxtAttr* GetFrwrdTxtHint( const SwpHints& rHtsArr, sal_uInt16& rPos,
83cdf0e10cSrcweir xub_StrLen nCntntPos )
84cdf0e10cSrcweir {
85cdf0e10cSrcweir while( rPos < rHtsArr.Count() )
86cdf0e10cSrcweir {
87cdf0e10cSrcweir const SwTxtAttr *pTxtHt = rHtsArr.GetStart( rPos++ );
88cdf0e10cSrcweir // der Start vom Attribut muss innerhalb des Bereiches liegen !!
89cdf0e10cSrcweir if( *pTxtHt->GetStart() >= nCntntPos )
90cdf0e10cSrcweir return pTxtHt; // gueltiges TextAttribut
91cdf0e10cSrcweir }
92cdf0e10cSrcweir return 0; // kein gueltiges TextAttribut
93cdf0e10cSrcweir }
94cdf0e10cSrcweir
95cdf0e10cSrcweir
GetBkwrdTxtHint(const SwpHints & rHtsArr,sal_uInt16 & rPos,xub_StrLen nCntntPos)96cdf0e10cSrcweir const SwTxtAttr* GetBkwrdTxtHint( const SwpHints& rHtsArr, sal_uInt16& rPos,
97cdf0e10cSrcweir xub_StrLen nCntntPos )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir while( rPos > 0 )
100cdf0e10cSrcweir {
101cdf0e10cSrcweir //Hack mit cast fuer das Update
102cdf0e10cSrcweir const SwTxtAttr *pTxtHt = rHtsArr.GetStart( --rPos );
103cdf0e10cSrcweir // der Start vom Attribut muss innerhalb des Bereiches liegen !!
104cdf0e10cSrcweir if( *pTxtHt->GetStart() < nCntntPos )
105cdf0e10cSrcweir return pTxtHt; // gueltiges TextAttribut
106cdf0e10cSrcweir }
107cdf0e10cSrcweir return 0; // kein gueltiges TextAttribut
108cdf0e10cSrcweir }
109cdf0e10cSrcweir
110cdf0e10cSrcweir
lcl_SetAttrPam(SwPaM & rPam,xub_StrLen nStart,const xub_StrLen * pEnde,const sal_Bool bSaveMark)111cdf0e10cSrcweir void lcl_SetAttrPam( SwPaM & rPam, xub_StrLen nStart, const xub_StrLen* pEnde,
112cdf0e10cSrcweir const sal_Bool bSaveMark )
113cdf0e10cSrcweir {
114cdf0e10cSrcweir xub_StrLen nCntntPos;
115cdf0e10cSrcweir if( bSaveMark )
116cdf0e10cSrcweir nCntntPos = rPam.GetMark()->nContent.GetIndex();
117cdf0e10cSrcweir else
118cdf0e10cSrcweir nCntntPos = rPam.GetPoint()->nContent.GetIndex();
119cdf0e10cSrcweir sal_Bool bTstEnde = rPam.GetPoint()->nNode == rPam.GetMark()->nNode;
120cdf0e10cSrcweir
121cdf0e10cSrcweir SwCntntNode* pCNd = rPam.GetCntntNode();
122cdf0e10cSrcweir rPam.GetPoint()->nContent.Assign( pCNd, nStart );
123cdf0e10cSrcweir rPam.SetMark(); // Point == GetMark
124cdf0e10cSrcweir
125cdf0e10cSrcweir // Point zeigt auf das Ende vom SuchBereich oder Ende vom Attribut
126cdf0e10cSrcweir if( pEnde )
127cdf0e10cSrcweir {
128cdf0e10cSrcweir if( bTstEnde && *pEnde > nCntntPos )
129cdf0e10cSrcweir rPam.GetPoint()->nContent = nCntntPos;
130cdf0e10cSrcweir else
131cdf0e10cSrcweir rPam.GetPoint()->nContent = *pEnde;
132cdf0e10cSrcweir }
133cdf0e10cSrcweir }
134cdf0e10cSrcweir
135cdf0e10cSrcweir //------------------ Suche nach einem Text Attribut -----------------------
136cdf0e10cSrcweir
137cdf0e10cSrcweir // diese Funktion sucht in einem TextNode nach dem vorgegebenen Attribut.
138cdf0e10cSrcweir // Wird es gefunden, dann hat der SwPaM den Bereich der das Attribut
139cdf0e10cSrcweir // umspannt, unter Beachtung des Suchbereiches
140cdf0e10cSrcweir
141cdf0e10cSrcweir
lcl_Search(const SwTxtNode & rTxtNd,SwPaM & rPam,const SfxPoolItem & rCmpItem,SwMoveFn fnMove,sal_Bool bValue)142cdf0e10cSrcweir sal_Bool lcl_Search( const SwTxtNode& rTxtNd, SwPaM& rPam,
143cdf0e10cSrcweir const SfxPoolItem& rCmpItem,
144cdf0e10cSrcweir SwMoveFn fnMove, sal_Bool bValue )
145cdf0e10cSrcweir {
146cdf0e10cSrcweir if ( !rTxtNd.HasHints() )
147cdf0e10cSrcweir return sal_False;
148cdf0e10cSrcweir const SwTxtAttr *pTxtHt = 0;
149cdf0e10cSrcweir sal_Bool bForward = fnMove == fnMoveForward;
150cdf0e10cSrcweir sal_uInt16 nPos = bForward ? 0 : rTxtNd.GetSwpHints().Count();
151cdf0e10cSrcweir xub_StrLen nCntntPos = rPam.GetPoint()->nContent.GetIndex();
152cdf0e10cSrcweir
153cdf0e10cSrcweir while( 0 != ( pTxtHt=(*fnMove->fnGetHint)(rTxtNd.GetSwpHints(),nPos,nCntntPos)))
154cdf0e10cSrcweir if( pTxtHt->Which() == rCmpItem.Which() &&
155cdf0e10cSrcweir ( !bValue || CmpAttr( pTxtHt->GetAttr(), rCmpItem )))
156cdf0e10cSrcweir {
15769a74367SOliver-Rainer Wittmann lcl_SetAttrPam( rPam, *pTxtHt->GetStart(), pTxtHt->End(), bForward );
158cdf0e10cSrcweir return sal_True;
159cdf0e10cSrcweir }
160cdf0e10cSrcweir return sal_False;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir
163cdf0e10cSrcweir
164cdf0e10cSrcweir //------------------ Suche nach mehren Text Attributen -------------------
165cdf0e10cSrcweir
166cdf0e10cSrcweir struct _SwSrchChrAttr
167cdf0e10cSrcweir {
168cdf0e10cSrcweir sal_uInt16 nWhich;
169cdf0e10cSrcweir xub_StrLen nStt, nEnd;
170cdf0e10cSrcweir
_SwSrchChrAttr_SwSrchChrAttr171cdf0e10cSrcweir _SwSrchChrAttr( const SfxPoolItem& rItem,
172cdf0e10cSrcweir xub_StrLen nStart, xub_StrLen nAnyEnd )
173cdf0e10cSrcweir : nWhich( rItem.Which() ), nStt( nStart ), nEnd( nAnyEnd )
174cdf0e10cSrcweir {}
175cdf0e10cSrcweir };
176cdf0e10cSrcweir
177cdf0e10cSrcweir class SwAttrCheckArr
178cdf0e10cSrcweir {
179cdf0e10cSrcweir _SwSrchChrAttr *pFndArr, *pStackArr;
180cdf0e10cSrcweir xub_StrLen nNdStt, nNdEnd;
181cdf0e10cSrcweir sal_uInt16 nArrStart, nArrLen;
182cdf0e10cSrcweir sal_uInt16 nFound, nStackCnt;
183cdf0e10cSrcweir SfxItemSet aCmpSet;
184cdf0e10cSrcweir sal_Bool bNoColls;
185cdf0e10cSrcweir sal_Bool bForward;
186cdf0e10cSrcweir
187cdf0e10cSrcweir public:
188cdf0e10cSrcweir SwAttrCheckArr( const SfxItemSet& rSet, int bForward, int bNoCollections );
189cdf0e10cSrcweir ~SwAttrCheckArr();
190cdf0e10cSrcweir
191cdf0e10cSrcweir void SetNewSet( const SwTxtNode& rTxtNd, const SwPaM& rPam );
192cdf0e10cSrcweir
193cdf0e10cSrcweir // wieviele Attribute ueberhaupt ??
Count() const194cdf0e10cSrcweir sal_uInt16 Count() const { return aCmpSet.Count(); }
Found() const195cdf0e10cSrcweir int Found() const { return nFound == aCmpSet.Count(); }
196cdf0e10cSrcweir int CheckStack();
197cdf0e10cSrcweir
198cdf0e10cSrcweir xub_StrLen Start() const;
199cdf0e10cSrcweir xub_StrLen End() const;
200cdf0e10cSrcweir
GetNdStt() const201cdf0e10cSrcweir xub_StrLen GetNdStt() const { return nNdStt; }
GetNdEnd() const202cdf0e10cSrcweir xub_StrLen GetNdEnd() const { return nNdEnd; }
203cdf0e10cSrcweir
204cdf0e10cSrcweir int SetAttrFwd( const SwTxtAttr& rAttr );
205cdf0e10cSrcweir int SetAttrBwd( const SwTxtAttr& rAttr );
206cdf0e10cSrcweir };
207cdf0e10cSrcweir
208cdf0e10cSrcweir
209cdf0e10cSrcweir
SwAttrCheckArr(const SfxItemSet & rSet,int bFwd,int bNoCollections)210cdf0e10cSrcweir SwAttrCheckArr::SwAttrCheckArr( const SfxItemSet& rSet, int bFwd,
211cdf0e10cSrcweir int bNoCollections )
212cdf0e10cSrcweir : aCmpSet( *rSet.GetPool(), RES_CHRATR_BEGIN, RES_TXTATR_END-1 )
213cdf0e10cSrcweir {
214cdf0e10cSrcweir aCmpSet.Put( rSet, sal_False );
215cdf0e10cSrcweir bNoColls = 0 != bNoCollections;
216cdf0e10cSrcweir
217cdf0e10cSrcweir bForward = 0 != bFwd;
218cdf0e10cSrcweir
219cdf0e10cSrcweir // Bestimmen den Bereich des Fnd/Stack-Arrays (Min/Max)
220cdf0e10cSrcweir SfxItemIter aIter( aCmpSet );
221cdf0e10cSrcweir nArrStart = aCmpSet.GetWhichByPos( aIter.GetFirstPos() );
222cdf0e10cSrcweir nArrLen = aCmpSet.GetWhichByPos( aIter.GetLastPos() ) - nArrStart+1;
223cdf0e10cSrcweir
224cdf0e10cSrcweir char* pFndChar = new char[ nArrLen * sizeof(_SwSrchChrAttr) ];
225cdf0e10cSrcweir char* pStackChar = new char[ nArrLen * sizeof(_SwSrchChrAttr) ];
226cdf0e10cSrcweir
227cdf0e10cSrcweir pFndArr = (_SwSrchChrAttr*)pFndChar;
228cdf0e10cSrcweir pStackArr = (_SwSrchChrAttr*)pStackChar;
229cdf0e10cSrcweir }
230cdf0e10cSrcweir
~SwAttrCheckArr()231cdf0e10cSrcweir SwAttrCheckArr::~SwAttrCheckArr()
232cdf0e10cSrcweir {
233cdf0e10cSrcweir delete[] (char*)pFndArr;
234cdf0e10cSrcweir delete[] (char*)pStackArr;
235cdf0e10cSrcweir }
236cdf0e10cSrcweir
SetNewSet(const SwTxtNode & rTxtNd,const SwPaM & rPam)237cdf0e10cSrcweir void SwAttrCheckArr::SetNewSet( const SwTxtNode& rTxtNd, const SwPaM& rPam )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir memset( pFndArr, 0, nArrLen * sizeof(_SwSrchChrAttr) );
240cdf0e10cSrcweir memset( pStackArr, 0, nArrLen * sizeof(_SwSrchChrAttr) );
241cdf0e10cSrcweir nFound = 0;
242cdf0e10cSrcweir nStackCnt = 0;
243cdf0e10cSrcweir
244cdf0e10cSrcweir if( bForward )
245cdf0e10cSrcweir {
246cdf0e10cSrcweir nNdStt = rPam.GetPoint()->nContent.GetIndex();
247cdf0e10cSrcweir nNdEnd = rPam.GetPoint()->nNode == rPam.GetMark()->nNode
248cdf0e10cSrcweir ? rPam.GetMark()->nContent.GetIndex()
249cdf0e10cSrcweir : rTxtNd.GetTxt().Len();
250cdf0e10cSrcweir }
251cdf0e10cSrcweir else
252cdf0e10cSrcweir {
253cdf0e10cSrcweir nNdEnd = rPam.GetPoint()->nContent.GetIndex();
254cdf0e10cSrcweir nNdStt = rPam.GetPoint()->nNode == rPam.GetMark()->nNode
255cdf0e10cSrcweir ? rPam.GetMark()->nContent.GetIndex()
256cdf0e10cSrcweir : 0;
257cdf0e10cSrcweir }
258cdf0e10cSrcweir
259cdf0e10cSrcweir if( bNoColls && !rTxtNd.HasSwAttrSet() )
260cdf0e10cSrcweir return ;
261cdf0e10cSrcweir
262cdf0e10cSrcweir const SfxItemSet& rSet = rTxtNd.GetSwAttrSet();
263cdf0e10cSrcweir // if( !rSet.Count() )
264cdf0e10cSrcweir // return;
265cdf0e10cSrcweir
266cdf0e10cSrcweir SfxItemIter aIter( aCmpSet );
267cdf0e10cSrcweir const SfxPoolItem* pItem = aIter.GetCurItem();
268cdf0e10cSrcweir const SfxPoolItem* pFndItem;
269cdf0e10cSrcweir sal_uInt16 nWhich;
270cdf0e10cSrcweir
271cdf0e10cSrcweir while( sal_True )
272cdf0e10cSrcweir {
273cdf0e10cSrcweir // nur testen, ob vorhanden ist ?
274cdf0e10cSrcweir if( IsInvalidItem( pItem ) )
275cdf0e10cSrcweir {
276cdf0e10cSrcweir nWhich = aCmpSet.GetWhichByPos( aIter.GetCurPos() );
277cdf0e10cSrcweir if( RES_TXTATR_END <= nWhich )
278cdf0e10cSrcweir break; // Ende der TextAttribute
279cdf0e10cSrcweir
280cdf0e10cSrcweir if( SFX_ITEM_SET == rSet.GetItemState( nWhich, !bNoColls, &pFndItem )
281cdf0e10cSrcweir && !CmpAttr( *pFndItem, rSet.GetPool()->GetDefaultItem( nWhich ) ))
282cdf0e10cSrcweir {
283cdf0e10cSrcweir pFndArr[ nWhich - nArrStart ] =
284cdf0e10cSrcweir _SwSrchChrAttr( *pFndItem, nNdStt, nNdEnd );
285cdf0e10cSrcweir nFound++;
286cdf0e10cSrcweir }
287cdf0e10cSrcweir }
288cdf0e10cSrcweir else
289cdf0e10cSrcweir {
290cdf0e10cSrcweir if( RES_TXTATR_END <= (nWhich = pItem->Which() ))
291cdf0e10cSrcweir break; // Ende der TextAttribute
292cdf0e10cSrcweir
293cdf0e10cSrcweir //JP 27.02.95: wenn nach defaults gesucht wird, dann muss man bis zum Pool
294cdf0e10cSrcweir // runter
295cdf0e10cSrcweir // if( SFX_ITEM_SET == rSet.GetItemState( nWhich, !bNoColls, &pFndItem )
296cdf0e10cSrcweir // && *pFndItem == *pItem )
297cdf0e10cSrcweir if( CmpAttr( rSet.Get( nWhich, !bNoColls ), *pItem ) )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir pFndArr[ nWhich - nArrStart ] =
300cdf0e10cSrcweir _SwSrchChrAttr( *pItem, nNdStt, nNdEnd );
301cdf0e10cSrcweir nFound++;
302cdf0e10cSrcweir }
303cdf0e10cSrcweir }
304cdf0e10cSrcweir
305cdf0e10cSrcweir if( aIter.IsAtEnd() )
306cdf0e10cSrcweir break;
307cdf0e10cSrcweir pItem = aIter.NextItem();
308cdf0e10cSrcweir }
309cdf0e10cSrcweir }
310cdf0e10cSrcweir
311cdf0e10cSrcweir static bool
lcl_IsAttributeIgnorable(xub_StrLen const nNdStart,xub_StrLen const nNdEnd,_SwSrchChrAttr const & rTmp)312cdf0e10cSrcweir lcl_IsAttributeIgnorable(xub_StrLen const nNdStart, xub_StrLen const nNdEnd,
313cdf0e10cSrcweir _SwSrchChrAttr const& rTmp)
314cdf0e10cSrcweir {
315cdf0e10cSrcweir // #i115528#: if there is a paragraph attribute, it has been added by the
316cdf0e10cSrcweir // SwAttrCheckArr ctor, and nFound is 1.
317cdf0e10cSrcweir // if the paragraph is entirely covered by hints that override the paragraph
318cdf0e10cSrcweir // attribute, then this function must find an attribute to decrement nFound!
319cdf0e10cSrcweir // so check for an empty search range, let attributes that start/end there
320cdf0e10cSrcweir // cover it, and hope for the best...
321cdf0e10cSrcweir return ((nNdEnd == nNdStart)
322cdf0e10cSrcweir ? ((rTmp.nEnd < nNdStart) || (nNdEnd < rTmp.nStt))
323cdf0e10cSrcweir : ((rTmp.nEnd <= nNdStart) || (nNdEnd <= rTmp.nStt)));
324cdf0e10cSrcweir }
325cdf0e10cSrcweir
SetAttrFwd(const SwTxtAttr & rAttr)326cdf0e10cSrcweir int SwAttrCheckArr::SetAttrFwd( const SwTxtAttr& rAttr )
327cdf0e10cSrcweir {
328cdf0e10cSrcweir _SwSrchChrAttr aTmp( rAttr.GetAttr(), *rAttr.GetStart(), *rAttr.GetAnyEnd() );
329cdf0e10cSrcweir
330cdf0e10cSrcweir // ignore all attributes not in search range
331cdf0e10cSrcweir if (lcl_IsAttributeIgnorable(nNdStt, nNdEnd, aTmp))
332cdf0e10cSrcweir {
333cdf0e10cSrcweir return Found();
334cdf0e10cSrcweir }
335cdf0e10cSrcweir
336cdf0e10cSrcweir const SfxPoolItem* pItem;
337cdf0e10cSrcweir // --------------------------------------------------------------
338cdf0e10cSrcweir // Hier wird jetzt ausdruecklich auch in Zeichenvorlagen gesucht
339cdf0e10cSrcweir // --------------------------------------------------------------
340cdf0e10cSrcweir sal_uInt16 nWhch = rAttr.Which();
341cdf0e10cSrcweir SfxWhichIter* pIter = NULL;
342cdf0e10cSrcweir const SfxPoolItem* pTmpItem = NULL;
343cdf0e10cSrcweir const SfxItemSet* pSet = NULL;
344cdf0e10cSrcweir if( RES_TXTATR_CHARFMT == nWhch || RES_TXTATR_AUTOFMT == nWhch )
345cdf0e10cSrcweir {
346cdf0e10cSrcweir if( bNoColls && RES_TXTATR_CHARFMT == nWhch )
347cdf0e10cSrcweir return Found();
348cdf0e10cSrcweir pTmpItem = NULL;
349cdf0e10cSrcweir pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
350cdf0e10cSrcweir if ( pSet )
351cdf0e10cSrcweir {
352cdf0e10cSrcweir pIter = new SfxWhichIter( *pSet );
353cdf0e10cSrcweir nWhch = pIter->FirstWhich();
354cdf0e10cSrcweir while( nWhch &&
355cdf0e10cSrcweir SFX_ITEM_SET != pSet->GetItemState( nWhch, sal_True, &pTmpItem ) )
356cdf0e10cSrcweir nWhch = pIter->NextWhich();
357cdf0e10cSrcweir if( !nWhch )
358cdf0e10cSrcweir pTmpItem = NULL;
359cdf0e10cSrcweir }
360cdf0e10cSrcweir }
361cdf0e10cSrcweir else
362cdf0e10cSrcweir pTmpItem = &rAttr.GetAttr();
363cdf0e10cSrcweir while( pTmpItem )
364cdf0e10cSrcweir {
365cdf0e10cSrcweir SfxItemState eState = aCmpSet.GetItemState( nWhch, sal_False, &pItem );
366cdf0e10cSrcweir if( SFX_ITEM_DONTCARE == eState || SFX_ITEM_SET == eState )
367cdf0e10cSrcweir {
368cdf0e10cSrcweir sal_uInt16 n;
369cdf0e10cSrcweir _SwSrchChrAttr* pCmp;
370cdf0e10cSrcweir
371cdf0e10cSrcweir // loesche erstmal alle, die bis zu der Start Position schon wieder
372cdf0e10cSrcweir // ungueltig sind:
373cdf0e10cSrcweir
374cdf0e10cSrcweir _SwSrchChrAttr* pArrPtr;
375cdf0e10cSrcweir if( nFound )
376cdf0e10cSrcweir for( pArrPtr = pFndArr, n = 0; n < nArrLen;
377cdf0e10cSrcweir ++n, ++pArrPtr )
378cdf0e10cSrcweir if( pArrPtr->nWhich && pArrPtr->nEnd <= aTmp.nStt )
379cdf0e10cSrcweir {
380cdf0e10cSrcweir pArrPtr->nWhich = 0; // geloescht
381cdf0e10cSrcweir nFound--;
382cdf0e10cSrcweir }
383cdf0e10cSrcweir
384cdf0e10cSrcweir // loesche erstmal alle, die bis zu der Start Position schon wieder
385cdf0e10cSrcweir // ungueltig sind. Und verschiebe alle die "offen" sind, heisst ueber
386cdf0e10cSrcweir // die Start Position ragen, vom Stack in den FndSet
387cdf0e10cSrcweir
388cdf0e10cSrcweir if( nStackCnt )
389cdf0e10cSrcweir for( pArrPtr = pStackArr, n=0; n < nArrLen; ++n, ++pArrPtr )
390cdf0e10cSrcweir {
391cdf0e10cSrcweir if( !pArrPtr->nWhich )
392cdf0e10cSrcweir continue;
393cdf0e10cSrcweir
394cdf0e10cSrcweir if( pArrPtr->nEnd <= aTmp.nStt )
395cdf0e10cSrcweir {
396cdf0e10cSrcweir pArrPtr->nWhich = 0; // geloescht
397cdf0e10cSrcweir if( !--nStackCnt )
398cdf0e10cSrcweir break;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir else if( pArrPtr->nStt <= aTmp.nStt )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir if( ( pCmp = &pFndArr[ n ])->nWhich )
403cdf0e10cSrcweir {
404cdf0e10cSrcweir if( pCmp->nEnd < pArrPtr->nEnd ) // erweitern
405cdf0e10cSrcweir pCmp->nEnd = pArrPtr->nEnd;
406cdf0e10cSrcweir }
407cdf0e10cSrcweir else
408cdf0e10cSrcweir {
409cdf0e10cSrcweir *pCmp = *pArrPtr;
410cdf0e10cSrcweir nFound++;
411cdf0e10cSrcweir }
412cdf0e10cSrcweir pArrPtr->nWhich = 0;
413cdf0e10cSrcweir if( !--nStackCnt )
414cdf0e10cSrcweir break;
415cdf0e10cSrcweir }
416cdf0e10cSrcweir }
417cdf0e10cSrcweir
418cdf0e10cSrcweir sal_Bool bContinue = sal_False;
419cdf0e10cSrcweir
420cdf0e10cSrcweir if( SFX_ITEM_DONTCARE == eState )
421cdf0e10cSrcweir {
422cdf0e10cSrcweir // wird Attribut gueltig ?
423cdf0e10cSrcweir if( !CmpAttr( aCmpSet.GetPool()->GetDefaultItem( nWhch ),
424cdf0e10cSrcweir *pTmpItem ))
425cdf0e10cSrcweir {
426cdf0e10cSrcweir // suche das Attribut und erweiter es gegebenenfalls
427cdf0e10cSrcweir if( !( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich )
428cdf0e10cSrcweir {
429cdf0e10cSrcweir *pCmp = aTmp; // nicht gefunden, eintragen
430cdf0e10cSrcweir nFound++;
431cdf0e10cSrcweir }
432cdf0e10cSrcweir else if( pCmp->nEnd < aTmp.nEnd ) // erweitern ?
433cdf0e10cSrcweir pCmp->nEnd = aTmp.nEnd;
434cdf0e10cSrcweir
435cdf0e10cSrcweir bContinue = sal_True;
436cdf0e10cSrcweir }
437cdf0e10cSrcweir }
438cdf0e10cSrcweir // wird Attribut gueltig ?
439cdf0e10cSrcweir else if( CmpAttr( *pItem, *pTmpItem ) )
440cdf0e10cSrcweir {
441cdf0e10cSrcweir pFndArr[ nWhch - nArrStart ] = aTmp;
442cdf0e10cSrcweir ++nFound;
443cdf0e10cSrcweir bContinue = sal_True;
444cdf0e10cSrcweir }
445cdf0e10cSrcweir
446cdf0e10cSrcweir // tja, dann muss es auf den Stack
447cdf0e10cSrcweir if( !bContinue && ( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich )
448cdf0e10cSrcweir {
449cdf0e10cSrcweir // vorhanden, auf den Stack. Aber nur wenn es noch grosser ist
450cdf0e10cSrcweir if( pCmp->nEnd > aTmp.nEnd )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir ASSERT( !pStackArr[ nWhch - nArrStart ].nWhich,
453cdf0e10cSrcweir "Stack-Platz ist noch belegt" );
454cdf0e10cSrcweir
455cdf0e10cSrcweir // ---------
456cdf0e10cSrcweir // JP 22.08.96: nur Ende manipulieren reicht nicht. Bug 30547
457cdf0e10cSrcweir // pCmp->nStt = aTmp.nEnd;
458cdf0e10cSrcweir if( aTmp.nStt <= pCmp->nStt )
459cdf0e10cSrcweir pCmp->nStt = aTmp.nEnd;
460cdf0e10cSrcweir else
461cdf0e10cSrcweir pCmp->nEnd = aTmp.nStt;
462cdf0e10cSrcweir // ---------
463cdf0e10cSrcweir
464cdf0e10cSrcweir pStackArr[ nWhch - nArrStart ] = *pCmp;
465cdf0e10cSrcweir nStackCnt++;
466cdf0e10cSrcweir }
467cdf0e10cSrcweir pCmp->nWhich = 0;
468cdf0e10cSrcweir nFound--;
469cdf0e10cSrcweir }
470cdf0e10cSrcweir }
471cdf0e10cSrcweir if( pIter )
472cdf0e10cSrcweir {
473cdf0e10cSrcweir nWhch = pIter->NextWhich();
474cdf0e10cSrcweir while( nWhch &&
475cdf0e10cSrcweir SFX_ITEM_SET != pSet->GetItemState( nWhch, sal_True, &pTmpItem ) )
476cdf0e10cSrcweir nWhch = pIter->NextWhich();
477cdf0e10cSrcweir if( !nWhch )
478cdf0e10cSrcweir break;
479cdf0e10cSrcweir }
480cdf0e10cSrcweir else
481cdf0e10cSrcweir break;
482cdf0e10cSrcweir }
483*47d45a94SPedro Giffuni delete pIter;
484cdf0e10cSrcweir return Found();
485cdf0e10cSrcweir }
486cdf0e10cSrcweir
487cdf0e10cSrcweir
SetAttrBwd(const SwTxtAttr & rAttr)488cdf0e10cSrcweir int SwAttrCheckArr::SetAttrBwd( const SwTxtAttr& rAttr )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir _SwSrchChrAttr aTmp( rAttr.GetAttr(), *rAttr.GetStart(), *rAttr.GetAnyEnd() );
491cdf0e10cSrcweir
492cdf0e10cSrcweir // ignore all attributes not in search range
493cdf0e10cSrcweir if (lcl_IsAttributeIgnorable(nNdStt, nNdEnd, aTmp))
494cdf0e10cSrcweir {
495cdf0e10cSrcweir return Found();
496cdf0e10cSrcweir }
497cdf0e10cSrcweir
498cdf0e10cSrcweir const SfxPoolItem* pItem;
499cdf0e10cSrcweir // --------------------------------------------------------------
500cdf0e10cSrcweir // Hier wird jetzt ausdruecklich auch in Zeichenvorlagen gesucht
501cdf0e10cSrcweir // --------------------------------------------------------------
502cdf0e10cSrcweir sal_uInt16 nWhch = rAttr.Which();
503cdf0e10cSrcweir SfxWhichIter* pIter = NULL;
504cdf0e10cSrcweir const SfxPoolItem* pTmpItem = NULL;
505cdf0e10cSrcweir const SfxItemSet* pSet = NULL;
506cdf0e10cSrcweir if( RES_TXTATR_CHARFMT == nWhch || RES_TXTATR_AUTOFMT == nWhch )
507cdf0e10cSrcweir {
508cdf0e10cSrcweir if( bNoColls && RES_TXTATR_CHARFMT == nWhch )
509cdf0e10cSrcweir return Found();
510cdf0e10cSrcweir
511cdf0e10cSrcweir pSet = CharFmt::GetItemSet( rAttr.GetAttr() );
512cdf0e10cSrcweir if ( pSet )
513cdf0e10cSrcweir {
514cdf0e10cSrcweir pIter = new SfxWhichIter( *pSet );
515cdf0e10cSrcweir nWhch = pIter->FirstWhich();
516cdf0e10cSrcweir while( nWhch &&
517cdf0e10cSrcweir SFX_ITEM_SET != pSet->GetItemState( nWhch, sal_True, &pTmpItem ) )
518cdf0e10cSrcweir nWhch = pIter->NextWhich();
519cdf0e10cSrcweir if( !nWhch )
520cdf0e10cSrcweir pTmpItem = NULL;
521cdf0e10cSrcweir }
522cdf0e10cSrcweir }
523cdf0e10cSrcweir else
524cdf0e10cSrcweir pTmpItem = &rAttr.GetAttr();
525cdf0e10cSrcweir while( pTmpItem )
526cdf0e10cSrcweir {
527cdf0e10cSrcweir SfxItemState eState = aCmpSet.GetItemState( nWhch, sal_False, &pItem );
528cdf0e10cSrcweir if( SFX_ITEM_DONTCARE == eState || SFX_ITEM_SET == eState )
529cdf0e10cSrcweir {
530cdf0e10cSrcweir sal_uInt16 n;
531cdf0e10cSrcweir _SwSrchChrAttr* pCmp;
532cdf0e10cSrcweir
533cdf0e10cSrcweir // loesche erstmal alle, die bis zu der Start Position schon wieder
534cdf0e10cSrcweir // ungueltig sind:
535cdf0e10cSrcweir
536cdf0e10cSrcweir _SwSrchChrAttr* pArrPtr;
537cdf0e10cSrcweir if( nFound )
538cdf0e10cSrcweir for( pArrPtr = pFndArr, n = 0; n < nArrLen; ++n, ++pArrPtr )
539cdf0e10cSrcweir if( pArrPtr->nWhich && pArrPtr->nStt >= aTmp.nEnd )
540cdf0e10cSrcweir {
541cdf0e10cSrcweir pArrPtr->nWhich = 0; // geloescht
542cdf0e10cSrcweir nFound--;
543cdf0e10cSrcweir }
544cdf0e10cSrcweir
545cdf0e10cSrcweir // loesche erstmal alle, die bis zu der Start Position schon wieder
546cdf0e10cSrcweir // ungueltig sind. Und verschiebe alle die "offen" sind, heisst ueber
547cdf0e10cSrcweir // die Start Position ragen, vom Stack in den FndSet
548cdf0e10cSrcweir
549cdf0e10cSrcweir if( nStackCnt )
550cdf0e10cSrcweir for( pArrPtr = pStackArr, n = 0; n < nArrLen; ++n, ++pArrPtr )
551cdf0e10cSrcweir {
552cdf0e10cSrcweir if( !pArrPtr->nWhich )
553cdf0e10cSrcweir continue;
554cdf0e10cSrcweir
555cdf0e10cSrcweir if( pArrPtr->nStt >= aTmp.nEnd )
556cdf0e10cSrcweir {
557cdf0e10cSrcweir pArrPtr->nWhich = 0; // geloescht
558cdf0e10cSrcweir if( !--nStackCnt )
559cdf0e10cSrcweir break;
560cdf0e10cSrcweir }
561cdf0e10cSrcweir else if( pArrPtr->nEnd >= aTmp.nEnd )
562cdf0e10cSrcweir {
563cdf0e10cSrcweir if( ( pCmp = &pFndArr[ n ])->nWhich )
564cdf0e10cSrcweir {
565cdf0e10cSrcweir if( pCmp->nStt > pArrPtr->nStt ) // erweitern
566cdf0e10cSrcweir pCmp->nStt = pArrPtr->nStt;
567cdf0e10cSrcweir }
568cdf0e10cSrcweir else
569cdf0e10cSrcweir {
570cdf0e10cSrcweir *pCmp = *pArrPtr;
571cdf0e10cSrcweir nFound++;
572cdf0e10cSrcweir }
573cdf0e10cSrcweir pArrPtr->nWhich = 0;
574cdf0e10cSrcweir if( !--nStackCnt )
575cdf0e10cSrcweir break;
576cdf0e10cSrcweir }
577cdf0e10cSrcweir }
578cdf0e10cSrcweir
579cdf0e10cSrcweir sal_Bool bContinue = sal_False;
580cdf0e10cSrcweir if( SFX_ITEM_DONTCARE == eState )
581cdf0e10cSrcweir {
582cdf0e10cSrcweir // wird Attribut gueltig ?
583cdf0e10cSrcweir if( !CmpAttr( aCmpSet.GetPool()->GetDefaultItem( nWhch ),
584cdf0e10cSrcweir *pTmpItem ) )
585cdf0e10cSrcweir {
586cdf0e10cSrcweir // suche das Attribut und erweiter es gegebenenfalls
587cdf0e10cSrcweir if( !( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich )
588cdf0e10cSrcweir {
589cdf0e10cSrcweir *pCmp = aTmp; // nicht gefunden, eintragen
590cdf0e10cSrcweir nFound++;
591cdf0e10cSrcweir }
592cdf0e10cSrcweir else if( pCmp->nStt > aTmp.nStt ) // erweitern ?
593cdf0e10cSrcweir pCmp->nStt = aTmp.nStt;
594cdf0e10cSrcweir
595cdf0e10cSrcweir bContinue = sal_True;
596cdf0e10cSrcweir }
597cdf0e10cSrcweir }
598cdf0e10cSrcweir // wird Attribut gueltig ?
599cdf0e10cSrcweir else if( CmpAttr( *pItem, *pTmpItem ))
600cdf0e10cSrcweir {
601cdf0e10cSrcweir pFndArr[ nWhch - nArrStart ] = aTmp;
602cdf0e10cSrcweir ++nFound;
603cdf0e10cSrcweir bContinue = sal_True;
604cdf0e10cSrcweir }
605cdf0e10cSrcweir
606cdf0e10cSrcweir // tja, dann muss es auf den Stack
607cdf0e10cSrcweir if( !bContinue && ( pCmp = &pFndArr[ nWhch - nArrStart ])->nWhich )
608cdf0e10cSrcweir {
609cdf0e10cSrcweir // vorhanden, auf den Stack. Aber nur wenn es noch grosser ist
610cdf0e10cSrcweir if( pCmp->nStt < aTmp.nStt )
611cdf0e10cSrcweir {
612cdf0e10cSrcweir ASSERT( !pStackArr[ nWhch - nArrStart ].nWhich,
613cdf0e10cSrcweir "Stack-Platz ist noch belegt" );
614cdf0e10cSrcweir
615cdf0e10cSrcweir // ---------
616cdf0e10cSrcweir // JP 22.08.96: nur Ende manipulieren reicht nicht. Bug 30547
617cdf0e10cSrcweir // pCmp->nEnd = aTmp.nStt;
618cdf0e10cSrcweir if( aTmp.nEnd <= pCmp->nEnd )
619cdf0e10cSrcweir pCmp->nEnd = aTmp.nStt;
620cdf0e10cSrcweir else
621cdf0e10cSrcweir pCmp->nStt = aTmp.nEnd;
622cdf0e10cSrcweir // ---------
623cdf0e10cSrcweir
624cdf0e10cSrcweir pStackArr[ nWhch - nArrStart ] = *pCmp;
625cdf0e10cSrcweir nStackCnt++;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir pCmp->nWhich = 0;
628cdf0e10cSrcweir nFound--;
629cdf0e10cSrcweir }
630cdf0e10cSrcweir }
631cdf0e10cSrcweir if( pIter )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir nWhch = pIter->NextWhich();
634cdf0e10cSrcweir while( nWhch &&
635cdf0e10cSrcweir SFX_ITEM_SET != pSet->GetItemState( nWhch, sal_True, &pTmpItem ) )
636cdf0e10cSrcweir nWhch = pIter->NextWhich();
637cdf0e10cSrcweir if( !nWhch )
638cdf0e10cSrcweir break;
639cdf0e10cSrcweir }
640cdf0e10cSrcweir else
641cdf0e10cSrcweir break;
642cdf0e10cSrcweir }
643*47d45a94SPedro Giffuni delete pIter;
644cdf0e10cSrcweir return Found();
645cdf0e10cSrcweir }
646cdf0e10cSrcweir
647cdf0e10cSrcweir
Start() const648cdf0e10cSrcweir xub_StrLen SwAttrCheckArr::Start() const
649cdf0e10cSrcweir {
650cdf0e10cSrcweir xub_StrLen nStart = nNdStt;
651cdf0e10cSrcweir _SwSrchChrAttr* pArrPtr = pFndArr;
652cdf0e10cSrcweir for( sal_uInt16 n = 0; n < nArrLen; ++n, ++pArrPtr )
653cdf0e10cSrcweir if( pArrPtr->nWhich && pArrPtr->nStt > nStart )
654cdf0e10cSrcweir nStart = pArrPtr->nStt;
655cdf0e10cSrcweir
656cdf0e10cSrcweir return nStart;
657cdf0e10cSrcweir }
658cdf0e10cSrcweir
659cdf0e10cSrcweir
End() const660cdf0e10cSrcweir xub_StrLen SwAttrCheckArr::End() const
661cdf0e10cSrcweir {
662cdf0e10cSrcweir _SwSrchChrAttr* pArrPtr = pFndArr;
663cdf0e10cSrcweir xub_StrLen nEnd = nNdEnd;
664cdf0e10cSrcweir for( sal_uInt16 n = 0; n < nArrLen; ++n, ++pArrPtr )
665cdf0e10cSrcweir if( pArrPtr->nWhich && pArrPtr->nEnd < nEnd )
666cdf0e10cSrcweir nEnd = pArrPtr->nEnd;
667cdf0e10cSrcweir
668cdf0e10cSrcweir return nEnd;
669cdf0e10cSrcweir }
670cdf0e10cSrcweir
671cdf0e10cSrcweir
CheckStack()672cdf0e10cSrcweir int SwAttrCheckArr::CheckStack()
673cdf0e10cSrcweir {
674cdf0e10cSrcweir if( !nStackCnt )
675cdf0e10cSrcweir return sal_False;
676cdf0e10cSrcweir
677cdf0e10cSrcweir sal_uInt16 n;
678cdf0e10cSrcweir xub_StrLen nSttPos = Start(), nEndPos = End();
679cdf0e10cSrcweir _SwSrchChrAttr* pArrPtr;
680cdf0e10cSrcweir for( pArrPtr = pStackArr, n = 0; n < nArrLen; ++n, ++pArrPtr )
681cdf0e10cSrcweir {
682cdf0e10cSrcweir if( !pArrPtr->nWhich )
683cdf0e10cSrcweir continue;
684cdf0e10cSrcweir
685cdf0e10cSrcweir if( bForward ? pArrPtr->nEnd <= nSttPos : pArrPtr->nStt >= nEndPos )
686cdf0e10cSrcweir {
687cdf0e10cSrcweir pArrPtr->nWhich = 0; // geloescht
688cdf0e10cSrcweir if( !--nStackCnt )
689cdf0e10cSrcweir return nFound == aCmpSet.Count();
690cdf0e10cSrcweir }
691cdf0e10cSrcweir else if( bForward ? pArrPtr->nStt < nEndPos : pArrPtr->nEnd > nSttPos )
692cdf0e10cSrcweir {
693cdf0e10cSrcweir // alle die "offen" sind, heisst ueber die Start Position ragen,
694cdf0e10cSrcweir // im FndSet setzen
695cdf0e10cSrcweir ASSERT( !pFndArr[ n ].nWhich, "Array-Platz ist noch belegt" );
696cdf0e10cSrcweir pFndArr[ n ] = *pArrPtr;
697cdf0e10cSrcweir pArrPtr->nWhich = 0;
698cdf0e10cSrcweir nFound++;
699cdf0e10cSrcweir if( !--nStackCnt )
700cdf0e10cSrcweir return nFound == aCmpSet.Count();
701cdf0e10cSrcweir }
702cdf0e10cSrcweir }
703cdf0e10cSrcweir return nFound == aCmpSet.Count();
704cdf0e10cSrcweir }
705cdf0e10cSrcweir
706cdf0e10cSrcweir
707cdf0e10cSrcweir
lcl_SearchForward(const SwTxtNode & rTxtNd,SwAttrCheckArr & rCmpArr,SwPaM & rPam)708cdf0e10cSrcweir int lcl_SearchForward( const SwTxtNode& rTxtNd, SwAttrCheckArr& rCmpArr,
709cdf0e10cSrcweir SwPaM& rPam )
710cdf0e10cSrcweir {
711cdf0e10cSrcweir xub_StrLen nEndPos, nSttPos;
712cdf0e10cSrcweir rCmpArr.SetNewSet( rTxtNd, rPam );
713cdf0e10cSrcweir if( !rTxtNd.HasHints() )
714cdf0e10cSrcweir {
715cdf0e10cSrcweir if( !rCmpArr.Found() )
716cdf0e10cSrcweir return sal_False;
717cdf0e10cSrcweir nEndPos = rCmpArr.GetNdEnd();
718cdf0e10cSrcweir lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, sal_True );
719cdf0e10cSrcweir return sal_True;
720cdf0e10cSrcweir }
721cdf0e10cSrcweir
722cdf0e10cSrcweir // dann gehe mal durch das nach "Start" sortierte Array
723cdf0e10cSrcweir const SwpHints& rHtArr = rTxtNd.GetSwpHints();
724cdf0e10cSrcweir const SwTxtAttr* pAttr;
725cdf0e10cSrcweir sal_uInt16 nPos = 0;
726cdf0e10cSrcweir
727cdf0e10cSrcweir // sollte jetzt schon alles vorhanden sein, dann teste, mit welchem
728cdf0e10cSrcweir // das wieder beendet wird.
729cdf0e10cSrcweir if( rCmpArr.Found() )
730cdf0e10cSrcweir {
731cdf0e10cSrcweir for( ; nPos < rHtArr.Count(); ++nPos )
732cdf0e10cSrcweir if( !rCmpArr.SetAttrFwd( *( pAttr = rHtArr.GetStart( nPos )) ) )
733cdf0e10cSrcweir {
734cdf0e10cSrcweir if( rCmpArr.GetNdStt() < *pAttr->GetStart() )
735cdf0e10cSrcweir {
736cdf0e10cSrcweir // dann haben wir unser Ende:
737cdf0e10cSrcweir lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(),
738cdf0e10cSrcweir pAttr->GetStart(), sal_True );
739cdf0e10cSrcweir return sal_True;
740cdf0e10cSrcweir }
741cdf0e10cSrcweir // ansonsten muessen wir weiter suchen
742cdf0e10cSrcweir break;
743cdf0e10cSrcweir }
744cdf0e10cSrcweir
745cdf0e10cSrcweir if( nPos == rHtArr.Count() && rCmpArr.Found() )
746cdf0e10cSrcweir {
747cdf0e10cSrcweir // dann haben wir unseren Bereich
748cdf0e10cSrcweir nEndPos = rCmpArr.GetNdEnd();
749cdf0e10cSrcweir lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, sal_True );
750cdf0e10cSrcweir return sal_True;
751cdf0e10cSrcweir }
752cdf0e10cSrcweir }
753cdf0e10cSrcweir
754cdf0e10cSrcweir for( ; nPos < rHtArr.Count(); ++nPos )
755cdf0e10cSrcweir if( rCmpArr.SetAttrFwd( *( pAttr = rHtArr.GetStart( nPos )) ) )
756cdf0e10cSrcweir {
757cdf0e10cSrcweir // sollten noch mehr auf der gleichen Position anfangen ??
758cdf0e10cSrcweir // auch die noch mit testen !!
759cdf0e10cSrcweir nSttPos = *pAttr->GetStart();
760cdf0e10cSrcweir while( ++nPos < rHtArr.Count() && nSttPos ==
761cdf0e10cSrcweir *( pAttr = rHtArr.GetStart( nPos ))->GetStart() &&
762cdf0e10cSrcweir rCmpArr.SetAttrFwd( *pAttr ) )
763cdf0e10cSrcweir ;
764cdf0e10cSrcweir if( !rCmpArr.Found() )
765cdf0e10cSrcweir continue;
766cdf0e10cSrcweir
767cdf0e10cSrcweir // dann haben wir den Bereich zusammen
768cdf0e10cSrcweir if( (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) )
769cdf0e10cSrcweir return sal_False;
770cdf0e10cSrcweir lcl_SetAttrPam( rPam, nSttPos, &nEndPos, sal_True );
771cdf0e10cSrcweir return sal_True;
772cdf0e10cSrcweir }
773cdf0e10cSrcweir
774cdf0e10cSrcweir if( !rCmpArr.CheckStack() ||
775cdf0e10cSrcweir (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) )
776cdf0e10cSrcweir return sal_False;
777cdf0e10cSrcweir lcl_SetAttrPam( rPam, nSttPos, &nEndPos, sal_True );
778cdf0e10cSrcweir return sal_True;
779cdf0e10cSrcweir }
780cdf0e10cSrcweir
781cdf0e10cSrcweir
lcl_SearchBackward(const SwTxtNode & rTxtNd,SwAttrCheckArr & rCmpArr,SwPaM & rPam)782cdf0e10cSrcweir int lcl_SearchBackward( const SwTxtNode& rTxtNd, SwAttrCheckArr& rCmpArr,
783cdf0e10cSrcweir SwPaM& rPam )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir xub_StrLen nEndPos, nSttPos;
786cdf0e10cSrcweir rCmpArr.SetNewSet( rTxtNd, rPam );
787cdf0e10cSrcweir if( !rTxtNd.HasHints() )
788cdf0e10cSrcweir {
789cdf0e10cSrcweir if( !rCmpArr.Found() )
790cdf0e10cSrcweir return sal_False;
791cdf0e10cSrcweir nEndPos = rCmpArr.GetNdEnd();
792cdf0e10cSrcweir lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, sal_False );
793cdf0e10cSrcweir return sal_True;
794cdf0e10cSrcweir }
795cdf0e10cSrcweir
796cdf0e10cSrcweir // dann gehe mal durch das nach "Start" sortierte Array
797cdf0e10cSrcweir const SwpHints& rHtArr = rTxtNd.GetSwpHints();
798cdf0e10cSrcweir const SwTxtAttr* pAttr;
799cdf0e10cSrcweir sal_uInt16 nPos = rHtArr.Count();
800cdf0e10cSrcweir
801cdf0e10cSrcweir // sollte jetzt schon alles vorhanden sein, dann teste, mit welchem
802cdf0e10cSrcweir // das wieder beendet wird.
803cdf0e10cSrcweir if( rCmpArr.Found() )
804cdf0e10cSrcweir {
805cdf0e10cSrcweir while( nPos )
806cdf0e10cSrcweir if( !rCmpArr.SetAttrBwd( *( pAttr = rHtArr.GetEnd( --nPos )) ) )
807cdf0e10cSrcweir {
808cdf0e10cSrcweir nSttPos = *pAttr->GetAnyEnd();
809cdf0e10cSrcweir if( nSttPos < rCmpArr.GetNdEnd() )
810cdf0e10cSrcweir {
811cdf0e10cSrcweir // dann haben wir unser Ende:
812cdf0e10cSrcweir nEndPos = rCmpArr.GetNdEnd();
813cdf0e10cSrcweir lcl_SetAttrPam( rPam, nSttPos, &nEndPos, sal_False );
814cdf0e10cSrcweir return sal_True;
815cdf0e10cSrcweir }
816cdf0e10cSrcweir
817cdf0e10cSrcweir // ansonsten muessen wir weiter suchen
818cdf0e10cSrcweir break;
819cdf0e10cSrcweir }
820cdf0e10cSrcweir
821cdf0e10cSrcweir if( !nPos && rCmpArr.Found() )
822cdf0e10cSrcweir {
823cdf0e10cSrcweir // dann haben wir unseren Bereich
824cdf0e10cSrcweir nEndPos = rCmpArr.GetNdEnd();
825cdf0e10cSrcweir lcl_SetAttrPam( rPam, rCmpArr.GetNdStt(), &nEndPos, sal_False );
826cdf0e10cSrcweir return sal_True;
827cdf0e10cSrcweir }
828cdf0e10cSrcweir }
829cdf0e10cSrcweir
830cdf0e10cSrcweir while( nPos )
831cdf0e10cSrcweir if( rCmpArr.SetAttrBwd( *( pAttr = rHtArr.GetEnd( --nPos )) ) )
832cdf0e10cSrcweir {
833cdf0e10cSrcweir // sollten noch mehr auf der gleichen Position anfangen ??
834cdf0e10cSrcweir // auch die noch mit testen !!
835cdf0e10cSrcweir if( nPos )
836cdf0e10cSrcweir {
837cdf0e10cSrcweir nEndPos = *pAttr->GetAnyEnd();
838cdf0e10cSrcweir while( --nPos && nEndPos ==
839cdf0e10cSrcweir *( pAttr = rHtArr.GetEnd( nPos ))->GetAnyEnd() &&
840cdf0e10cSrcweir rCmpArr.SetAttrBwd( *pAttr ) )
841cdf0e10cSrcweir ;
842cdf0e10cSrcweir }
843cdf0e10cSrcweir if( !rCmpArr.Found() )
844cdf0e10cSrcweir continue;
845cdf0e10cSrcweir
846cdf0e10cSrcweir
847cdf0e10cSrcweir // dann haben wir den Bereich zusammen
848cdf0e10cSrcweir if( (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) )
849cdf0e10cSrcweir return sal_False;
850cdf0e10cSrcweir lcl_SetAttrPam( rPam, nSttPos, &nEndPos, sal_False );
851cdf0e10cSrcweir return sal_True;
852cdf0e10cSrcweir }
853cdf0e10cSrcweir
854cdf0e10cSrcweir if( !rCmpArr.CheckStack() ||
855cdf0e10cSrcweir (nSttPos = rCmpArr.Start()) > (nEndPos = rCmpArr.End()) )
856cdf0e10cSrcweir return sal_False;
857cdf0e10cSrcweir lcl_SetAttrPam( rPam, nSttPos, &nEndPos, sal_False );
858cdf0e10cSrcweir return sal_True;
859cdf0e10cSrcweir }
860cdf0e10cSrcweir
861cdf0e10cSrcweir
lcl_Search(const SwCntntNode & rCNd,const SfxItemSet & rCmpSet,sal_Bool bNoColls)862cdf0e10cSrcweir int lcl_Search( const SwCntntNode& rCNd, const SfxItemSet& rCmpSet, sal_Bool bNoColls )
863cdf0e10cSrcweir {
864cdf0e10cSrcweir // nur die harte Attributierung suchen ?
865cdf0e10cSrcweir if( bNoColls && !rCNd.HasSwAttrSet() )
866cdf0e10cSrcweir return sal_False;
867cdf0e10cSrcweir
868cdf0e10cSrcweir const SfxItemSet& rNdSet = rCNd.GetSwAttrSet();
869cdf0e10cSrcweir SfxItemIter aIter( rCmpSet );
870cdf0e10cSrcweir const SfxPoolItem* pItem = aIter.GetCurItem();
871cdf0e10cSrcweir const SfxPoolItem* pNdItem;
872cdf0e10cSrcweir sal_uInt16 nWhich;
873cdf0e10cSrcweir
874cdf0e10cSrcweir while( sal_True )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir // nur testen, ob vorhanden ist ?
877cdf0e10cSrcweir if( IsInvalidItem( pItem ))
878cdf0e10cSrcweir {
879cdf0e10cSrcweir nWhich = rCmpSet.GetWhichByPos( aIter.GetCurPos() );
880cdf0e10cSrcweir if( SFX_ITEM_SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem )
881cdf0e10cSrcweir || CmpAttr( *pNdItem, rNdSet.GetPool()->GetDefaultItem( nWhich ) ))
882cdf0e10cSrcweir return sal_False;
883cdf0e10cSrcweir }
884cdf0e10cSrcweir else
885cdf0e10cSrcweir {
886cdf0e10cSrcweir nWhich = pItem->Which();
887cdf0e10cSrcweir //JP 27.02.95: wenn nach defaults gesucht wird, dann muss man bis zum Pool
888cdf0e10cSrcweir // runter
889cdf0e10cSrcweir // if( SFX_ITEM_SET != rNdSet.GetItemState( nWhich, !bNoColls, &pNdItem )
890cdf0e10cSrcweir // || *pNdItem != *pItem )
891cdf0e10cSrcweir if( !CmpAttr( rNdSet.Get( nWhich, !bNoColls ), *pItem ))
892cdf0e10cSrcweir return sal_False;
893cdf0e10cSrcweir }
894cdf0e10cSrcweir
895cdf0e10cSrcweir if( aIter.IsAtEnd() )
896cdf0e10cSrcweir break;
897cdf0e10cSrcweir pItem = aIter.NextItem();
898cdf0e10cSrcweir }
899cdf0e10cSrcweir return sal_True; // wurde gefunden
900cdf0e10cSrcweir }
901cdf0e10cSrcweir
902cdf0e10cSrcweir
Find(const SfxPoolItem & rAttr,sal_Bool bValue,SwMoveFn fnMove,const SwPaM * pRegion,sal_Bool bInReadOnly)903cdf0e10cSrcweir sal_Bool SwPaM::Find( const SfxPoolItem& rAttr, sal_Bool bValue, SwMoveFn fnMove,
904cdf0e10cSrcweir const SwPaM *pRegion, sal_Bool bInReadOnly )
905cdf0e10cSrcweir {
906cdf0e10cSrcweir // stelle fest welches Attribut gesucht wird:
90769a74367SOliver-Rainer Wittmann const sal_uInt16 nWhich = rAttr.Which();
908cdf0e10cSrcweir int bCharAttr = isCHRATR(nWhich) || isTXTATR(nWhich);
909cdf0e10cSrcweir
910cdf0e10cSrcweir SwPaM* pPam = MakeRegion( fnMove, pRegion );
911cdf0e10cSrcweir
912cdf0e10cSrcweir sal_Bool bFound = sal_False;
913cdf0e10cSrcweir sal_Bool bFirst = sal_True;
914cdf0e10cSrcweir sal_Bool bSrchForward = fnMove == fnMoveForward;
915cdf0e10cSrcweir SwCntntNode * pNode;
916cdf0e10cSrcweir const SfxPoolItem* pItem;
917cdf0e10cSrcweir SwpFmts aFmtArr;
918cdf0e10cSrcweir
919cdf0e10cSrcweir // Wenn am Anfang/Ende, aus dem Node moven
920cdf0e10cSrcweir if( bSrchForward
921cdf0e10cSrcweir ? pPam->GetPoint()->nContent.GetIndex() == pPam->GetCntntNode()->Len()
922cdf0e10cSrcweir : !pPam->GetPoint()->nContent.GetIndex() )
923cdf0e10cSrcweir {
924cdf0e10cSrcweir if( !(*fnMove->fnNds)( &pPam->GetPoint()->nNode, sal_False ))
925cdf0e10cSrcweir {
926cdf0e10cSrcweir delete pPam;
927cdf0e10cSrcweir return sal_False;
928cdf0e10cSrcweir }
929cdf0e10cSrcweir SwCntntNode *pNd = pPam->GetCntntNode();
930cdf0e10cSrcweir xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len();
931cdf0e10cSrcweir pPam->GetPoint()->nContent.Assign( pNd, nTmpPos );
932cdf0e10cSrcweir }
933cdf0e10cSrcweir
934cdf0e10cSrcweir while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ) )
935cdf0e10cSrcweir {
936cdf0e10cSrcweir if( bCharAttr )
937cdf0e10cSrcweir {
938cdf0e10cSrcweir if( !pNode->IsTxtNode() ) // CharAttr sind nur in TextNodes
939cdf0e10cSrcweir continue;
940cdf0e10cSrcweir
941cdf0e10cSrcweir if( ((SwTxtNode*)pNode)->HasHints() &&
942cdf0e10cSrcweir lcl_Search( *(SwTxtNode*)pNode, *pPam, rAttr, fnMove, bValue ))
943cdf0e10cSrcweir {
944cdf0e10cSrcweir // setze auf die Werte vom Attribut
945cdf0e10cSrcweir SetMark();
946cdf0e10cSrcweir *GetPoint() = *pPam->GetPoint();
947cdf0e10cSrcweir *GetMark() = *pPam->GetMark();
948cdf0e10cSrcweir bFound = sal_True;
949cdf0e10cSrcweir break;
950cdf0e10cSrcweir }
951cdf0e10cSrcweir else if (isTXTATR(nWhich))
952cdf0e10cSrcweir continue; // --> also weiter
953cdf0e10cSrcweir }
954cdf0e10cSrcweir
955cdf0e10cSrcweir // keine harte Attributierung, dann pruefe, ob die Vorlage schon
956cdf0e10cSrcweir // mal nach dem Attribut befragt wurde
957cdf0e10cSrcweir if( !pNode->HasSwAttrSet() )
958cdf0e10cSrcweir {
959cdf0e10cSrcweir const SwFmt* pTmpFmt = pNode->GetFmtColl();
960cdf0e10cSrcweir if( aFmtArr.Count() && aFmtArr.Seek_Entry( pTmpFmt ))
961cdf0e10cSrcweir continue; // die Collection wurde schon mal befragt
962cdf0e10cSrcweir aFmtArr.Insert( pTmpFmt );
963cdf0e10cSrcweir }
964cdf0e10cSrcweir
965cdf0e10cSrcweir if( SFX_ITEM_SET == pNode->GetSwAttrSet().GetItemState( nWhich,
966cdf0e10cSrcweir sal_True, &pItem ) && ( !bValue || *pItem == rAttr ) )
967cdf0e10cSrcweir {
968cdf0e10cSrcweir // FORWARD: Point an das Ende, GetMark zum Anfanf vom Node
969cdf0e10cSrcweir // BACKWARD: Point zum Anfang, GetMark an das Ende vom Node
970cdf0e10cSrcweir // und immer nach der Logik: inkl. Start, exkl. End !!!
971cdf0e10cSrcweir *GetPoint() = *pPam->GetPoint();
972cdf0e10cSrcweir SetMark();
973cdf0e10cSrcweir pNode->MakeEndIndex( &GetPoint()->nContent );
974cdf0e10cSrcweir bFound = sal_True;
975cdf0e10cSrcweir break;
976cdf0e10cSrcweir }
977cdf0e10cSrcweir }
978cdf0e10cSrcweir
979cdf0e10cSrcweir // beim rueckwaerts Suchen noch Point und Mark vertauschen
980cdf0e10cSrcweir if( bFound && !bSrchForward )
981cdf0e10cSrcweir Exchange();
982cdf0e10cSrcweir
983cdf0e10cSrcweir delete pPam;
984cdf0e10cSrcweir return bFound;
985cdf0e10cSrcweir }
986cdf0e10cSrcweir
987cdf0e10cSrcweir
988cdf0e10cSrcweir typedef int (*FnSearchAttr)( const SwTxtNode&, SwAttrCheckArr&, SwPaM& );
989cdf0e10cSrcweir
Find(const SfxItemSet & rSet,sal_Bool bNoColls,SwMoveFn fnMove,const SwPaM * pRegion,sal_Bool bInReadOnly,sal_Bool bMoveFirst)990cdf0e10cSrcweir sal_Bool SwPaM::Find( const SfxItemSet& rSet, sal_Bool bNoColls, SwMoveFn fnMove,
991cdf0e10cSrcweir const SwPaM *pRegion, sal_Bool bInReadOnly, sal_Bool bMoveFirst )
992cdf0e10cSrcweir {
993cdf0e10cSrcweir SwPaM* pPam = MakeRegion( fnMove, pRegion );
994cdf0e10cSrcweir
995cdf0e10cSrcweir sal_Bool bFound = sal_False;
996cdf0e10cSrcweir sal_Bool bFirst = sal_True;
997cdf0e10cSrcweir sal_Bool bSrchForward = fnMove == fnMoveForward;
998cdf0e10cSrcweir SwCntntNode * pNode;
999cdf0e10cSrcweir SwpFmts aFmtArr;
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir // teste doch mal welche Text/Char-Attribute gesucht werden
1002cdf0e10cSrcweir SwAttrCheckArr aCmpArr( rSet, bSrchForward, bNoColls );
1003cdf0e10cSrcweir SfxItemSet aOtherSet( GetDoc()->GetAttrPool(),
1004cdf0e10cSrcweir RES_PARATR_BEGIN, RES_GRFATR_END-1 );
1005cdf0e10cSrcweir aOtherSet.Put( rSet, sal_False ); // alle Invalid-Items erhalten!
1006cdf0e10cSrcweir
1007cdf0e10cSrcweir FnSearchAttr fnSearch = bSrchForward
1008cdf0e10cSrcweir ? (&::lcl_SearchForward)
1009cdf0e10cSrcweir : (&::lcl_SearchBackward);
1010cdf0e10cSrcweir
1011cdf0e10cSrcweir // Wenn am Anfang/Ende, aus dem Node moven
1012cdf0e10cSrcweir // Wenn am Anfang/Ende, aus dem Node moven
1013cdf0e10cSrcweir if( bMoveFirst &&
1014cdf0e10cSrcweir ( bSrchForward
1015cdf0e10cSrcweir ? pPam->GetPoint()->nContent.GetIndex() == pPam->GetCntntNode()->Len()
1016cdf0e10cSrcweir : !pPam->GetPoint()->nContent.GetIndex() ) )
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir if( !(*fnMove->fnNds)( &pPam->GetPoint()->nNode, sal_False ))
1019cdf0e10cSrcweir {
1020cdf0e10cSrcweir delete pPam;
1021cdf0e10cSrcweir return sal_False;
1022cdf0e10cSrcweir }
1023cdf0e10cSrcweir SwCntntNode *pNd = pPam->GetCntntNode();
1024cdf0e10cSrcweir xub_StrLen nTmpPos = bSrchForward ? 0 : pNd->Len();
1025cdf0e10cSrcweir pPam->GetPoint()->nContent.Assign( pNd, nTmpPos );
1026cdf0e10cSrcweir }
1027cdf0e10cSrcweir
1028cdf0e10cSrcweir
1029cdf0e10cSrcweir while( 0 != ( pNode = ::GetNode( *pPam, bFirst, fnMove, bInReadOnly ) ) )
1030cdf0e10cSrcweir {
1031cdf0e10cSrcweir if( aCmpArr.Count() )
1032cdf0e10cSrcweir {
1033cdf0e10cSrcweir if( !pNode->IsTxtNode() ) // CharAttr sind nur in TextNodes
1034cdf0e10cSrcweir continue;
1035cdf0e10cSrcweir
1036cdf0e10cSrcweir if( (!aOtherSet.Count() ||
1037cdf0e10cSrcweir lcl_Search( *pNode, aOtherSet, bNoColls )) &&
1038cdf0e10cSrcweir (*fnSearch)( *(SwTxtNode*)pNode, aCmpArr, *pPam ))
1039cdf0e10cSrcweir {
1040cdf0e10cSrcweir // setze auf die Werte vom Attribut
1041cdf0e10cSrcweir SetMark();
1042cdf0e10cSrcweir *GetPoint() = *pPam->GetPoint();
1043cdf0e10cSrcweir *GetMark() = *pPam->GetMark();
1044cdf0e10cSrcweir bFound = sal_True;
1045cdf0e10cSrcweir break;
1046cdf0e10cSrcweir }
1047cdf0e10cSrcweir continue; // TextAttribute
1048cdf0e10cSrcweir }
1049cdf0e10cSrcweir
1050cdf0e10cSrcweir if( !aOtherSet.Count() )
1051cdf0e10cSrcweir continue;
1052cdf0e10cSrcweir
1053cdf0e10cSrcweir // keine harte Attributierung, dann pruefe, ob die Vorlage schon
1054cdf0e10cSrcweir // mal nach dem Attribut befragt wurde
1055cdf0e10cSrcweir if( !pNode->HasSwAttrSet() )
1056cdf0e10cSrcweir {
1057cdf0e10cSrcweir const SwFmt* pTmpFmt = pNode->GetFmtColl();
1058cdf0e10cSrcweir if( aFmtArr.Count() && aFmtArr.Seek_Entry( pTmpFmt ))
1059cdf0e10cSrcweir continue; // die Collection wurde schon mal befragt
1060cdf0e10cSrcweir aFmtArr.Insert( pTmpFmt );
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir
1063cdf0e10cSrcweir if( lcl_Search( *pNode, aOtherSet, bNoColls ))
1064cdf0e10cSrcweir {
1065cdf0e10cSrcweir // FORWARD: Point an das Ende, GetMark zum Anfanf vom Node
1066cdf0e10cSrcweir // BACKWARD: Point zum Anfang, GetMark an das Ende vom Node
1067cdf0e10cSrcweir // und immer nach der Logik: inkl. Start, exkl. End !!!
1068cdf0e10cSrcweir *GetPoint() = *pPam->GetPoint();
1069cdf0e10cSrcweir SetMark();
1070cdf0e10cSrcweir pNode->MakeEndIndex( &GetPoint()->nContent );
1071cdf0e10cSrcweir bFound = sal_True;
1072cdf0e10cSrcweir break;
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir }
1075cdf0e10cSrcweir
1076cdf0e10cSrcweir // beim rueckwaerts Suchen noch Point und Mark vertauschen
1077cdf0e10cSrcweir if( bFound && !bSrchForward )
1078cdf0e10cSrcweir Exchange();
1079cdf0e10cSrcweir
1080cdf0e10cSrcweir delete pPam;
1081cdf0e10cSrcweir return bFound;
1082cdf0e10cSrcweir }
1083cdf0e10cSrcweir
1084cdf0e10cSrcweir //------------------ Methoden vom SwCursor ---------------------------
1085cdf0e10cSrcweir
1086cdf0e10cSrcweir // Parameter fuer das Suchen vom Attributen
1087cdf0e10cSrcweir struct SwFindParaAttr : public SwFindParas
1088cdf0e10cSrcweir {
1089cdf0e10cSrcweir sal_Bool bValue;
1090cdf0e10cSrcweir const SfxItemSet *pSet, *pReplSet;
1091cdf0e10cSrcweir const SearchOptions *pSearchOpt;
1092cdf0e10cSrcweir SwCursor& rCursor;
1093cdf0e10cSrcweir utl::TextSearch* pSTxt;
1094cdf0e10cSrcweir
SwFindParaAttrSwFindParaAttr1095cdf0e10cSrcweir SwFindParaAttr( const SfxItemSet& rSet, sal_Bool bNoCollection,
1096cdf0e10cSrcweir const SearchOptions* pOpt, const SfxItemSet* pRSet,
1097cdf0e10cSrcweir SwCursor& rCrsr )
1098cdf0e10cSrcweir : bValue( bNoCollection ), pSet( &rSet ), pReplSet( pRSet ),
1099cdf0e10cSrcweir pSearchOpt( pOpt ), rCursor( rCrsr ),pSTxt( 0 ) {}
1100cdf0e10cSrcweir
~SwFindParaAttrSwFindParaAttr1101cdf0e10cSrcweir virtual ~SwFindParaAttr() { delete pSTxt; }
1102cdf0e10cSrcweir
1103cdf0e10cSrcweir virtual int Find( SwPaM* , SwMoveFn , const SwPaM*, sal_Bool bInReadOnly );
1104cdf0e10cSrcweir virtual int IsReplaceMode() const;
1105cdf0e10cSrcweir };
1106cdf0e10cSrcweir
1107cdf0e10cSrcweir
Find(SwPaM * pCrsr,SwMoveFn fnMove,const SwPaM * pRegion,sal_Bool bInReadOnly)1108cdf0e10cSrcweir int SwFindParaAttr::Find( SwPaM* pCrsr, SwMoveFn fnMove, const SwPaM* pRegion,
1109cdf0e10cSrcweir sal_Bool bInReadOnly )
1110cdf0e10cSrcweir {
1111cdf0e10cSrcweir // String ersetzen ?? (nur wenn Text angegeben oder nicht attributiert
1112cdf0e10cSrcweir // gesucht wird)
1113cdf0e10cSrcweir sal_Bool bReplaceTxt = pSearchOpt && ( pSearchOpt->replaceString.getLength() ||
1114cdf0e10cSrcweir !pSet->Count() );
1115cdf0e10cSrcweir sal_Bool bReplaceAttr = pReplSet && pReplSet->Count();
1116cdf0e10cSrcweir sal_Bool bMoveFirst = !bReplaceAttr;
1117cdf0e10cSrcweir if( bInReadOnly && (bReplaceAttr || bReplaceTxt ))
1118cdf0e10cSrcweir bInReadOnly = sal_False;
1119cdf0e10cSrcweir
1120cdf0e10cSrcweir // wir suchen nach Attributen, soll zusaetzlich Text gesucht werden ?
1121cdf0e10cSrcweir {
1122cdf0e10cSrcweir SwPaM aRegion( *pRegion->GetMark(), *pRegion->GetPoint() );
1123cdf0e10cSrcweir SwPaM* pTextRegion = &aRegion;
1124cdf0e10cSrcweir SwPaM aSrchPam( *pCrsr->GetPoint() );
1125cdf0e10cSrcweir
1126cdf0e10cSrcweir while( sal_True )
1127cdf0e10cSrcweir {
1128cdf0e10cSrcweir if( pSet->Count() ) // gibts ueberhaupt Attributierung?
1129cdf0e10cSrcweir {
1130cdf0e10cSrcweir // zuerst die Attributierung
1131cdf0e10cSrcweir if( !aSrchPam.Find( *pSet, bValue, fnMove, &aRegion, bInReadOnly, bMoveFirst ) )
1132cdf0e10cSrcweir //JP 17.11.95: was ist mit Attributen in leeren Absaetzen !!
1133cdf0e10cSrcweir // || *pCrsr->GetMark() == *pCrsr->GetPoint() ) // kein Bereich ??
1134cdf0e10cSrcweir return FIND_NOT_FOUND;
1135cdf0e10cSrcweir bMoveFirst = sal_True;
1136cdf0e10cSrcweir
1137cdf0e10cSrcweir if( !pSearchOpt )
1138cdf0e10cSrcweir break; // ok, nur Attribute, also gefunden
1139cdf0e10cSrcweir
1140cdf0e10cSrcweir pTextRegion = &aSrchPam;
1141cdf0e10cSrcweir }
1142cdf0e10cSrcweir else if( !pSearchOpt )
1143cdf0e10cSrcweir return FIND_NOT_FOUND;
1144cdf0e10cSrcweir
1145cdf0e10cSrcweir // dann darin den Text
1146cdf0e10cSrcweir if( !pSTxt )
1147cdf0e10cSrcweir {
1148cdf0e10cSrcweir SearchOptions aTmp( *pSearchOpt );
1149cdf0e10cSrcweir
1150cdf0e10cSrcweir // search in selection
1151cdf0e10cSrcweir aTmp.searchFlag |= (SearchFlags::REG_NOT_BEGINOFLINE |
1152cdf0e10cSrcweir SearchFlags::REG_NOT_ENDOFLINE);
1153cdf0e10cSrcweir
1154cdf0e10cSrcweir MsLangId::convertLanguageToLocale( LANGUAGE_SYSTEM, aTmp.Locale );
1155cdf0e10cSrcweir
1156cdf0e10cSrcweir pSTxt = new utl::TextSearch( aTmp );
1157cdf0e10cSrcweir }
1158cdf0e10cSrcweir
1159cdf0e10cSrcweir // todo/mba: searching for attributes in Outliner text?!
1160cdf0e10cSrcweir sal_Bool bSearchInNotes = sal_False;
1161cdf0e10cSrcweir
1162cdf0e10cSrcweir // Bug 24665: suche im richtigen Bereich weiter (pTextRegion!)
1163cdf0e10cSrcweir if( aSrchPam.Find( *pSearchOpt, bSearchInNotes, *pSTxt, fnMove, pTextRegion, bInReadOnly ) &&
1164cdf0e10cSrcweir *aSrchPam.GetMark() != *aSrchPam.GetPoint() ) // gefunden ?
1165cdf0e10cSrcweir break; // also raus
1166cdf0e10cSrcweir else if( !pSet->Count() )
1167cdf0e10cSrcweir return FIND_NOT_FOUND; // nur Text und nicht gefunden
1168cdf0e10cSrcweir
1169cdf0e10cSrcweir /* // --> FME 2007-4-12 #i74765 # Why should we move the position?
1170cdf0e10cSrcweir Moving the position results in bugs when there are two adjacent
1171cdf0e10cSrcweir portions which both have the requested attributes set. I suspect this
1172cdf0e10cSrcweir should be only be an optimization. Therefore I boldly remove it now!
1173cdf0e10cSrcweir
1174cdf0e10cSrcweir // JP: und wieder neu aufsetzen, aber eine Position weiter
1175cdf0e10cSrcweir //JP 04.11.97: Bug 44897 - aber den Mark wieder aufheben, damit
1176cdf0e10cSrcweir // weiterbewegt werden kann!
1177cdf0e10cSrcweir {
1178cdf0e10cSrcweir sal_Bool bCheckRegion = sal_True;
1179cdf0e10cSrcweir SwPosition* pPos = aSrchPam.GetPoint();
1180cdf0e10cSrcweir if( !(*fnMove->fnNd)( &pPos->nNode.GetNode(),
1181cdf0e10cSrcweir &pPos->nContent, CRSR_SKIP_CHARS ))
1182cdf0e10cSrcweir {
1183cdf0e10cSrcweir if( (*fnMove->fnNds)( &pPos->nNode, sal_False ))
1184cdf0e10cSrcweir {
1185cdf0e10cSrcweir SwCntntNode *pNd = pPos->nNode.GetNode().GetCntntNode();
1186cdf0e10cSrcweir xub_StrLen nCPos;
1187cdf0e10cSrcweir if( fnMove == fnMoveForward )
1188cdf0e10cSrcweir nCPos = 0;
1189cdf0e10cSrcweir else
1190cdf0e10cSrcweir nCPos = pNd->Len();
1191cdf0e10cSrcweir pPos->nContent.Assign( pNd, nCPos );
1192cdf0e10cSrcweir }
1193cdf0e10cSrcweir else
1194cdf0e10cSrcweir bCheckRegion = sal_False;
1195cdf0e10cSrcweir }
1196cdf0e10cSrcweir if( !bCheckRegion || *aRegion.GetPoint() <= *pPos )
1197cdf0e10cSrcweir return FIND_NOT_FOUND; // nicht gefunden
1198cdf0e10cSrcweir }*/
1199cdf0e10cSrcweir *aRegion.GetMark() = *aSrchPam.GetPoint();
1200cdf0e10cSrcweir }
1201cdf0e10cSrcweir
1202cdf0e10cSrcweir *pCrsr->GetPoint() = *aSrchPam.GetPoint();
1203cdf0e10cSrcweir pCrsr->SetMark();
1204cdf0e10cSrcweir *pCrsr->GetMark() = *aSrchPam.GetMark();
1205cdf0e10cSrcweir }
1206cdf0e10cSrcweir
1207cdf0e10cSrcweir if( bReplaceTxt )
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir const bool bRegExp(
1210cdf0e10cSrcweir SearchAlgorithms_REGEXP == pSearchOpt->algorithmType);
1211cdf0e10cSrcweir SwIndex& rSttCntIdx = pCrsr->Start()->nContent;
1212cdf0e10cSrcweir xub_StrLen nSttCnt = rSttCntIdx.GetIndex();
1213cdf0e10cSrcweir
1214cdf0e10cSrcweir // damit die Region auch verschoben wird, in den Shell-Cursr-Ring
1215cdf0e10cSrcweir // mit aufnehmen !!
1216cdf0e10cSrcweir Ring *pPrevRing = 0;
1217cdf0e10cSrcweir if( bRegExp )
1218cdf0e10cSrcweir {
1219cdf0e10cSrcweir pPrevRing = pRegion->GetPrev();
1220cdf0e10cSrcweir ((Ring*)pRegion)->MoveRingTo( &rCursor );
1221cdf0e10cSrcweir }
1222cdf0e10cSrcweir
1223cdf0e10cSrcweir ::std::auto_ptr<String> pRepl( (bRegExp) ?
1224cdf0e10cSrcweir ReplaceBackReferences( *pSearchOpt, pCrsr ) : 0 );
1225cdf0e10cSrcweir rCursor.GetDoc()->ReplaceRange( *pCrsr,
1226cdf0e10cSrcweir (pRepl.get()) ? *pRepl : String(pSearchOpt->replaceString),
1227cdf0e10cSrcweir bRegExp );
1228cdf0e10cSrcweir rCursor.SaveTblBoxCntnt( pCrsr->GetPoint() );
1229cdf0e10cSrcweir
1230cdf0e10cSrcweir if( bRegExp )
1231cdf0e10cSrcweir {
1232cdf0e10cSrcweir // und die Region wieder herausnehmen:
1233cdf0e10cSrcweir Ring *p, *pNext = (Ring*)pRegion;
1234cdf0e10cSrcweir do {
1235cdf0e10cSrcweir p = pNext;
1236cdf0e10cSrcweir pNext = p->GetNext();
1237cdf0e10cSrcweir p->MoveTo( (Ring*)pRegion );
1238cdf0e10cSrcweir } while( p != pPrevRing );
1239cdf0e10cSrcweir }
1240cdf0e10cSrcweir rSttCntIdx = nSttCnt;
1241cdf0e10cSrcweir }
1242cdf0e10cSrcweir
1243cdf0e10cSrcweir if( bReplaceAttr )
1244cdf0e10cSrcweir {
1245cdf0e10cSrcweir // --- Ist die Selection noch da ??????
1246cdf0e10cSrcweir
1247cdf0e10cSrcweir // und noch die Attribute setzen
1248cdf0e10cSrcweir #ifdef OLD
1249cdf0e10cSrcweir pCrsr->GetDoc()->Insert( *pCrsr, *pReplSet, 0 );
1250cdf0e10cSrcweir #else
1251cdf0e10cSrcweir //JP 13.07.95: alle gesuchten Attribute werden, wenn nicht im
1252cdf0e10cSrcweir // ReplaceSet angegeben, auf Default zurueck gesetzt
1253cdf0e10cSrcweir
1254cdf0e10cSrcweir if( !pSet->Count() )
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir pCrsr->GetDoc()->InsertItemSet( *pCrsr, *pReplSet, 0 );
1257cdf0e10cSrcweir }
1258cdf0e10cSrcweir else
1259cdf0e10cSrcweir {
1260cdf0e10cSrcweir SfxItemPool* pPool = pReplSet->GetPool();
1261cdf0e10cSrcweir SfxItemSet aSet( *pPool, pReplSet->GetRanges() );
1262cdf0e10cSrcweir
1263cdf0e10cSrcweir SfxItemIter aIter( *pSet );
1264cdf0e10cSrcweir const SfxPoolItem* pItem = aIter.GetCurItem();
1265cdf0e10cSrcweir while( sal_True )
1266cdf0e10cSrcweir {
1267cdf0e10cSrcweir // alle die nicht gesetzt sind mit Pool-Defaults aufuellen
1268cdf0e10cSrcweir if( !IsInvalidItem( pItem ) && SFX_ITEM_SET !=
1269cdf0e10cSrcweir pReplSet->GetItemState( pItem->Which(), sal_False ))
1270cdf0e10cSrcweir aSet.Put( pPool->GetDefaultItem( pItem->Which() ));
1271cdf0e10cSrcweir
1272cdf0e10cSrcweir if( aIter.IsAtEnd() )
1273cdf0e10cSrcweir break;
1274cdf0e10cSrcweir pItem = aIter.NextItem();
1275cdf0e10cSrcweir }
1276cdf0e10cSrcweir aSet.Put( *pReplSet );
1277cdf0e10cSrcweir pCrsr->GetDoc()->InsertItemSet( *pCrsr, aSet, 0 );
1278cdf0e10cSrcweir }
1279cdf0e10cSrcweir #endif
1280cdf0e10cSrcweir return FIND_NO_RING;
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir
1283cdf0e10cSrcweir else
1284cdf0e10cSrcweir return FIND_FOUND;
1285cdf0e10cSrcweir }
1286cdf0e10cSrcweir
1287cdf0e10cSrcweir
IsReplaceMode() const1288cdf0e10cSrcweir int SwFindParaAttr::IsReplaceMode() const
1289cdf0e10cSrcweir {
1290cdf0e10cSrcweir return ( pSearchOpt && pSearchOpt->replaceString.getLength() ) ||
1291cdf0e10cSrcweir ( pReplSet && pReplSet->Count() );
1292cdf0e10cSrcweir }
1293cdf0e10cSrcweir
1294cdf0e10cSrcweir // Suchen nach Attributen
1295cdf0e10cSrcweir
1296cdf0e10cSrcweir
Find(const SfxItemSet & rSet,sal_Bool bNoCollections,SwDocPositions nStart,SwDocPositions nEnde,sal_Bool & bCancel,FindRanges eFndRngs,const SearchOptions * pSearchOpt,const SfxItemSet * pReplSet)1297cdf0e10cSrcweir sal_uLong SwCursor::Find( const SfxItemSet& rSet, sal_Bool bNoCollections,
1298cdf0e10cSrcweir SwDocPositions nStart, SwDocPositions nEnde, sal_Bool& bCancel,
1299cdf0e10cSrcweir FindRanges eFndRngs,
1300cdf0e10cSrcweir const SearchOptions* pSearchOpt, const SfxItemSet* pReplSet )
1301cdf0e10cSrcweir {
1302cdf0e10cSrcweir // OLE-Benachrichtigung abschalten !!
1303cdf0e10cSrcweir SwDoc* pDoc = GetDoc();
1304cdf0e10cSrcweir Link aLnk( pDoc->GetOle2Link() );
1305cdf0e10cSrcweir pDoc->SetOle2Link( Link() );
1306cdf0e10cSrcweir
1307cdf0e10cSrcweir sal_Bool bReplace = ( pSearchOpt && ( pSearchOpt->replaceString.getLength() ||
1308cdf0e10cSrcweir !rSet.Count() ) ) ||
1309cdf0e10cSrcweir (pReplSet && pReplSet->Count());
1310cdf0e10cSrcweir bool const bStartUndo = pDoc->GetIDocumentUndoRedo().DoesUndo() && bReplace;
1311cdf0e10cSrcweir if (bStartUndo)
1312cdf0e10cSrcweir {
1313cdf0e10cSrcweir pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_REPLACE, NULL );
1314cdf0e10cSrcweir }
1315cdf0e10cSrcweir
1316cdf0e10cSrcweir SwFindParaAttr aSwFindParaAttr( rSet, bNoCollections, pSearchOpt,
1317cdf0e10cSrcweir pReplSet, *this );
1318cdf0e10cSrcweir
1319cdf0e10cSrcweir sal_uLong nRet = FindAll(aSwFindParaAttr, nStart, nEnde, eFndRngs, bCancel );
1320cdf0e10cSrcweir pDoc->SetOle2Link( aLnk );
1321cdf0e10cSrcweir if( nRet && bReplace )
1322cdf0e10cSrcweir pDoc->SetModified();
1323cdf0e10cSrcweir
1324cdf0e10cSrcweir if (bStartUndo)
1325cdf0e10cSrcweir {
1326cdf0e10cSrcweir pDoc->GetIDocumentUndoRedo().EndUndo( UNDO_REPLACE, NULL );
1327cdf0e10cSrcweir }
1328cdf0e10cSrcweir
1329cdf0e10cSrcweir return nRet;
1330cdf0e10cSrcweir }
1331