xref: /aoo41x/main/sw/source/core/text/wrong.cxx (revision 46f38707)
1efeef26fSAndrew Rist /**************************************************************
2efeef26fSAndrew Rist  *
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
10efeef26fSAndrew Rist  *
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.
19efeef26fSAndrew Rist  *
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 <tools/string.hxx>
29cdf0e10cSrcweir #include <tools/debug.hxx>
30cdf0e10cSrcweir #include "errhdl.hxx"
31cdf0e10cSrcweir #include "swtypes.hxx"
32cdf0e10cSrcweir #include "txttypes.hxx"
33cdf0e10cSrcweir 
34cdf0e10cSrcweir #include "SwGrammarMarkUp.hxx"
35cdf0e10cSrcweir 
36*46f38707SJürgen Schmidt /*************************************************************************
37*46f38707SJürgen Schmidt  *SwWrongArea::SwWrongArea
38*46f38707SJürgen Schmidt  *************************************************************************/
39*46f38707SJürgen Schmidt 
SwWrongArea(const rtl::OUString & rType,WrongListType listType,com::sun::star::uno::Reference<com::sun::star::container::XStringKeyMap> xPropertyBag,xub_StrLen nPos,xub_StrLen nLen)40*46f38707SJürgen Schmidt SwWrongArea::SwWrongArea( const rtl::OUString& rType, WrongListType listType,
41*46f38707SJürgen Schmidt         com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
42*46f38707SJürgen Schmidt         xub_StrLen nPos,
43*46f38707SJürgen Schmidt         xub_StrLen nLen)
44*46f38707SJürgen Schmidt : maType(rType), mxPropertyBag(xPropertyBag), mnPos(nPos), mnLen(nLen), mpSubList(0)
45*46f38707SJürgen Schmidt {
46*46f38707SJürgen Schmidt     mColor =  getWrongAreaColor(listType, xPropertyBag);
47*46f38707SJürgen Schmidt     mLineType = getWrongAreaLineType(listType, xPropertyBag);
48*46f38707SJürgen Schmidt }
49*46f38707SJürgen Schmidt 
SwWrongArea(const rtl::OUString & rType,com::sun::star::uno::Reference<com::sun::star::container::XStringKeyMap> xPropertyBag,xub_StrLen nPos,xub_StrLen nLen,SwWrongList * pSubList)50*46f38707SJürgen Schmidt SwWrongArea::SwWrongArea( const rtl::OUString& rType,
51*46f38707SJürgen Schmidt         com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
52*46f38707SJürgen Schmidt         xub_StrLen nPos,
53*46f38707SJürgen Schmidt         xub_StrLen nLen,
54*46f38707SJürgen Schmidt         SwWrongList* pSubList)
55*46f38707SJürgen Schmidt : maType(rType), mxPropertyBag(xPropertyBag), mnPos(nPos), mnLen(nLen), mpSubList(pSubList), mLineType(WRONGAREA_NONE)
56*46f38707SJürgen Schmidt {
57*46f38707SJürgen Schmidt     if (pSubList != 0)
58*46f38707SJürgen Schmidt     {
59*46f38707SJürgen Schmidt         mColor =  getWrongAreaColor(pSubList->GetWrongListType(), xPropertyBag);
60*46f38707SJürgen Schmidt         mLineType = getWrongAreaLineType(pSubList->GetWrongListType(), xPropertyBag);
61*46f38707SJürgen Schmidt     }
62*46f38707SJürgen Schmidt }
63cdf0e10cSrcweir 
64cdf0e10cSrcweir /*************************************************************************
65cdf0e10cSrcweir  * SwWrongList::SwWrongList()
66cdf0e10cSrcweir  *************************************************************************/
SwWrongList(WrongListType eType)67cdf0e10cSrcweir SwWrongList::SwWrongList( WrongListType eType ) :
68cdf0e10cSrcweir     meType       (eType),
69cdf0e10cSrcweir     nBeginInvalid(STRING_LEN),  // everything correct... (the invalid area starts beyond the string)
70cdf0e10cSrcweir     nEndInvalid  (STRING_LEN)
71cdf0e10cSrcweir {
72cdf0e10cSrcweir     maList.reserve( 5 );
73cdf0e10cSrcweir }
74cdf0e10cSrcweir 
~SwWrongList()75cdf0e10cSrcweir SwWrongList::~SwWrongList()
76cdf0e10cSrcweir {
77cdf0e10cSrcweir     ClearList();
78cdf0e10cSrcweir }
79cdf0e10cSrcweir 
80cdf0e10cSrcweir /*************************************************************************
81cdf0e10cSrcweir  * SwWrongList* SwWrongList::Clone()
82cdf0e10cSrcweir  *************************************************************************/
83cdf0e10cSrcweir 
Clone()84cdf0e10cSrcweir SwWrongList* SwWrongList::Clone()
85cdf0e10cSrcweir {
86cdf0e10cSrcweir     SwWrongList* pClone = new SwWrongList( meType );
87cdf0e10cSrcweir     pClone->CopyFrom( *this );
88cdf0e10cSrcweir     return pClone;
89cdf0e10cSrcweir }
90cdf0e10cSrcweir 
91cdf0e10cSrcweir /*************************************************************************
92cdf0e10cSrcweir  * void SwWrongList::CopyFrom( const SwWrongList& rCopy )
93cdf0e10cSrcweir  *************************************************************************/
94cdf0e10cSrcweir 
CopyFrom(const SwWrongList & rCopy)95cdf0e10cSrcweir void SwWrongList::CopyFrom( const SwWrongList& rCopy )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir     maList = rCopy.maList;
98cdf0e10cSrcweir     meType = rCopy.meType;
99cdf0e10cSrcweir     nBeginInvalid = rCopy.nBeginInvalid;
100cdf0e10cSrcweir     nEndInvalid = rCopy.nEndInvalid;
101cdf0e10cSrcweir     for( size_t i = 0; i < maList.size(); ++i )
102cdf0e10cSrcweir     {
103cdf0e10cSrcweir         if( maList[i].mpSubList )
104cdf0e10cSrcweir             maList[i].mpSubList = maList[i].mpSubList->Clone();
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir }
107cdf0e10cSrcweir 
108cdf0e10cSrcweir /*************************************************************************
109cdf0e10cSrcweir  * SwWrongList::ClearList()
110cdf0e10cSrcweir  *************************************************************************/
ClearList()111cdf0e10cSrcweir void SwWrongList::ClearList()
112cdf0e10cSrcweir {
113cdf0e10cSrcweir     for ( size_t i = 0; i < maList.size(); ++i)
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         if (maList[i].mpSubList)
116cdf0e10cSrcweir             delete maList[i].mpSubList;
117cdf0e10cSrcweir         maList[i].mpSubList = NULL;
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir     maList.clear();
120cdf0e10cSrcweir }
121cdf0e10cSrcweir 
122cdf0e10cSrcweir /*************************************************************************
123cdf0e10cSrcweir  * sal_Bool SwWrongList::InWrongWord() gibt den Anfang und die Laenge des
124cdf0e10cSrcweir  * Wortes zurueck, wenn es als falsch markiert ist.
125cdf0e10cSrcweir  *************************************************************************/
InWrongWord(xub_StrLen & rChk,xub_StrLen & rLn) const126cdf0e10cSrcweir sal_Bool SwWrongList::InWrongWord( xub_StrLen &rChk, xub_StrLen &rLn ) const
127cdf0e10cSrcweir {
128cdf0e10cSrcweir     MSHORT nPos = GetWrongPos( rChk );
129cdf0e10cSrcweir     xub_StrLen nWrPos;
130cdf0e10cSrcweir     if( nPos < Count() && ( nWrPos = Pos( nPos ) ) <= rChk )
131cdf0e10cSrcweir     {
132cdf0e10cSrcweir         rLn = Len( nPos );
133cdf0e10cSrcweir         if( nWrPos + rLn <= rChk )
134cdf0e10cSrcweir 			return sal_False;
135cdf0e10cSrcweir 		rChk = nWrPos;
136cdf0e10cSrcweir 		return sal_True;
137cdf0e10cSrcweir 	}
138cdf0e10cSrcweir 	return sal_False;
139cdf0e10cSrcweir }
140cdf0e10cSrcweir 
141cdf0e10cSrcweir /*************************************************************************
142cdf0e10cSrcweir  * sal_Bool SwWrongList::Check() liefert den ersten falschen Bereich
143cdf0e10cSrcweir  *************************************************************************/
Check(xub_StrLen & rChk,xub_StrLen & rLn) const144cdf0e10cSrcweir sal_Bool SwWrongList::Check( xub_StrLen &rChk, xub_StrLen &rLn ) const
145cdf0e10cSrcweir {
146cdf0e10cSrcweir     MSHORT nPos = GetWrongPos( rChk );
147cdf0e10cSrcweir     rLn = rLn + rChk;
148cdf0e10cSrcweir     xub_StrLen nWrPos;
149cdf0e10cSrcweir 
150cdf0e10cSrcweir     if( nPos == Count() )
151cdf0e10cSrcweir         return sal_False;
152cdf0e10cSrcweir 
153cdf0e10cSrcweir     xub_StrLen nEnd = Len( nPos );
154cdf0e10cSrcweir     nEnd = nEnd + ( nWrPos = Pos( nPos ) );
155cdf0e10cSrcweir 	if( nEnd == rChk )
156cdf0e10cSrcweir 	{
157cdf0e10cSrcweir 		++nPos;
158cdf0e10cSrcweir 		if( nPos == Count()	)
159cdf0e10cSrcweir 			return sal_False;
160cdf0e10cSrcweir 		else
161cdf0e10cSrcweir 		{
162cdf0e10cSrcweir             nEnd = Len( nPos );
163cdf0e10cSrcweir             nEnd = nEnd + ( nWrPos = Pos( nPos ) );
164cdf0e10cSrcweir 		}
165cdf0e10cSrcweir 	}
166cdf0e10cSrcweir 	if( nEnd > rChk && nWrPos < rLn )
167cdf0e10cSrcweir 	{
168cdf0e10cSrcweir 		if( nWrPos > rChk )
169cdf0e10cSrcweir 			rChk = nWrPos;
170cdf0e10cSrcweir 		if( nEnd < rLn )
171cdf0e10cSrcweir 			rLn = nEnd;
172cdf0e10cSrcweir 		rLn = rLn - rChk;
173cdf0e10cSrcweir 		return 0 != rLn;
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 	return sal_False;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir /*************************************************************************
179cdf0e10cSrcweir  * xub_StrLen SwWrongList::NextWrong() liefert die naechste Fehlerposition
180cdf0e10cSrcweir  *************************************************************************/
181cdf0e10cSrcweir 
NextWrong(xub_StrLen nChk) const182cdf0e10cSrcweir xub_StrLen SwWrongList::NextWrong( xub_StrLen nChk ) const
183cdf0e10cSrcweir {
184cdf0e10cSrcweir     xub_StrLen nRet;
185cdf0e10cSrcweir     xub_StrLen nPos = GetWrongPos( nChk );
186cdf0e10cSrcweir     if( nPos < Count() )
187cdf0e10cSrcweir     {
188cdf0e10cSrcweir         nRet = Pos( nPos );
189cdf0e10cSrcweir         if( nRet < nChk && nRet + Len( nPos ) <= nChk )
190cdf0e10cSrcweir         {
191cdf0e10cSrcweir             if( ++nPos < Count() )
192cdf0e10cSrcweir                 nRet = Pos( nPos );
193cdf0e10cSrcweir             else
194cdf0e10cSrcweir                 nRet = STRING_LEN;
195cdf0e10cSrcweir         }
196cdf0e10cSrcweir     }
197cdf0e10cSrcweir     else
198cdf0e10cSrcweir         nRet = STRING_LEN;
199cdf0e10cSrcweir     if( nRet > GetBeginInv() && nChk < GetEndInv() )
200cdf0e10cSrcweir         nRet = nChk > GetBeginInv() ? nChk : GetBeginInv();
201cdf0e10cSrcweir     return nRet;
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir /*************************************************************************
205cdf0e10cSrcweir  *                 MSHORT SwWrongList::GetWrongPos( xub_StrLen nValue )
206cdf0e10cSrcweir  *  sucht die erste Position im Array, die groessergleich nValue ist,
207cdf0e10cSrcweir  * dies kann natuerlich auch hinter dem letzten Element sein!
208cdf0e10cSrcweir  *************************************************************************/
209cdf0e10cSrcweir 
GetWrongPos(xub_StrLen nValue) const210cdf0e10cSrcweir MSHORT SwWrongList::GetWrongPos( xub_StrLen nValue ) const
211cdf0e10cSrcweir {
212cdf0e10cSrcweir     MSHORT nOben = Count(), nMitte = 0, nUnten = 0;
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     if( nOben > 0 )
215cdf0e10cSrcweir     {
216cdf0e10cSrcweir         // For smart tag lists, we may not use a binary search. We return the
217cdf0e10cSrcweir         // position of the first smart tag which coveres nValue
218cdf0e10cSrcweir         if ( 0 != maList[0].maType.getLength() || maList[0].mpSubList )
219cdf0e10cSrcweir         {
220cdf0e10cSrcweir             std::vector<SwWrongArea>::const_iterator aIter = maList.begin();
221cdf0e10cSrcweir             while ( aIter != maList.end() )
222cdf0e10cSrcweir             {
223cdf0e10cSrcweir                 const xub_StrLen nSTPos = (*aIter).mnPos;
224cdf0e10cSrcweir                 const xub_StrLen nSTLen = (*aIter).mnLen;
225cdf0e10cSrcweir                 if ( nSTPos <= nValue && nValue < nSTPos + nSTLen )
226cdf0e10cSrcweir                     break;
227cdf0e10cSrcweir                 else if ( nSTPos > nValue )
228cdf0e10cSrcweir                     break;
229cdf0e10cSrcweir 
230cdf0e10cSrcweir                 ++aIter;
231cdf0e10cSrcweir                 ++nUnten;
232cdf0e10cSrcweir             }
233cdf0e10cSrcweir             return nUnten;
234cdf0e10cSrcweir         }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir         --nOben;
237cdf0e10cSrcweir         while( nUnten <= nOben )
238cdf0e10cSrcweir         {
239cdf0e10cSrcweir             nMitte = nUnten + ( nOben - nUnten ) / 2;
240cdf0e10cSrcweir             xub_StrLen nTmp = Pos( nMitte );
241cdf0e10cSrcweir             if( nTmp == nValue )
242cdf0e10cSrcweir             {
243cdf0e10cSrcweir                 nUnten = nMitte;
244cdf0e10cSrcweir                 break;
245cdf0e10cSrcweir             }
246cdf0e10cSrcweir             else if( nTmp < nValue )
247cdf0e10cSrcweir             {
248cdf0e10cSrcweir                 if( nTmp + Len( nMitte ) >= nValue )
249cdf0e10cSrcweir                 {
250cdf0e10cSrcweir                     nUnten = nMitte;
251cdf0e10cSrcweir                     break;
252cdf0e10cSrcweir                 }
253cdf0e10cSrcweir                 nUnten = nMitte + 1;
254cdf0e10cSrcweir             }
255cdf0e10cSrcweir             else if( nMitte == 0 )
256cdf0e10cSrcweir             {
257cdf0e10cSrcweir                 break;
258cdf0e10cSrcweir             }
259cdf0e10cSrcweir             else
260cdf0e10cSrcweir                 nOben = nMitte - 1;
261cdf0e10cSrcweir         }
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir 
264cdf0e10cSrcweir     // nUnten now points to an index i into the wrong list which
265cdf0e10cSrcweir     // 1. nValue is inside [ Area[i].pos, Area[i].pos + Area[i].len ] (inkl!!!)
266cdf0e10cSrcweir     // 2. nValue < Area[i].pos
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     return nUnten;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir /*************************************************************************
272cdf0e10cSrcweir  *                 void SwWrongList::_Invalidate()
273cdf0e10cSrcweir  *************************************************************************/
274cdf0e10cSrcweir 
_Invalidate(xub_StrLen nBegin,xub_StrLen nEnd)275cdf0e10cSrcweir void SwWrongList::_Invalidate( xub_StrLen nBegin, xub_StrLen nEnd )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir     if ( nBegin < GetBeginInv() )
278cdf0e10cSrcweir         nBeginInvalid = nBegin;
279cdf0e10cSrcweir     if ( nEnd > GetEndInv() )
280cdf0e10cSrcweir         nEndInvalid = nEnd;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
SetInvalid(xub_StrLen nBegin,xub_StrLen nEnd)283cdf0e10cSrcweir void SwWrongList::SetInvalid( xub_StrLen nBegin, xub_StrLen nEnd )
284cdf0e10cSrcweir {
285cdf0e10cSrcweir     nBeginInvalid = nBegin;
286cdf0e10cSrcweir     nEndInvalid = nEnd;
287cdf0e10cSrcweir }
288cdf0e10cSrcweir 
289cdf0e10cSrcweir 
290cdf0e10cSrcweir /*************************************************************************
291cdf0e10cSrcweir  *                      SwWrongList::Move( xub_StrLen nPos, long nDiff )
292cdf0e10cSrcweir  *  veraendert alle Positionen ab nPos um den angegebenen Wert,
293cdf0e10cSrcweir  *  wird nach Einfuegen oder Loeschen von Buchstaben benoetigt.
294cdf0e10cSrcweir  *************************************************************************/
295cdf0e10cSrcweir 
Move(xub_StrLen nPos,long nDiff)296cdf0e10cSrcweir void SwWrongList::Move( xub_StrLen nPos, long nDiff )
297cdf0e10cSrcweir {
298cdf0e10cSrcweir     MSHORT i = GetWrongPos( nPos );
299cdf0e10cSrcweir     if( nDiff < 0 )
300cdf0e10cSrcweir     {
301cdf0e10cSrcweir         xub_StrLen nEnd = nPos + xub_StrLen( -nDiff );
302cdf0e10cSrcweir         MSHORT nLst = i;
303cdf0e10cSrcweir         xub_StrLen nWrPos;
304cdf0e10cSrcweir         xub_StrLen nWrLen;
305cdf0e10cSrcweir         sal_Bool bJump = sal_False;
306cdf0e10cSrcweir         while( nLst < Count() && Pos( nLst ) < nEnd )
307cdf0e10cSrcweir             ++nLst;
308cdf0e10cSrcweir         if( nLst > i && ( nWrPos = Pos( nLst - 1 ) ) <= nPos )
309cdf0e10cSrcweir         {
310cdf0e10cSrcweir             nWrLen = Len( nLst - 1 );
311cdf0e10cSrcweir             // calculate new length of word
312cdf0e10cSrcweir             nWrLen = ( nEnd > nWrPos + nWrLen ) ?
313cdf0e10cSrcweir                        nPos - nWrPos :
314cdf0e10cSrcweir                        static_cast<xub_StrLen>(nWrLen + nDiff);
315cdf0e10cSrcweir             if( nWrLen )
316cdf0e10cSrcweir             {
317cdf0e10cSrcweir                 maList[--nLst].mnLen = nWrLen;
318cdf0e10cSrcweir                 bJump = sal_True;
319cdf0e10cSrcweir             }
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir         Remove( i, nLst - i );
322cdf0e10cSrcweir 
323cdf0e10cSrcweir         if ( bJump )
324cdf0e10cSrcweir             ++i;
325cdf0e10cSrcweir         if( STRING_LEN == GetBeginInv() )
326cdf0e10cSrcweir             SetInvalid( nPos ? nPos - 1 : nPos, nPos + 1 );
327cdf0e10cSrcweir         else
328cdf0e10cSrcweir         {
329cdf0e10cSrcweir             ShiftLeft( nBeginInvalid, nPos, nEnd );
330cdf0e10cSrcweir             ShiftLeft( nEndInvalid, nPos, nEnd );
331cdf0e10cSrcweir             _Invalidate( nPos ? nPos - 1 : nPos, nPos + 1 );
332cdf0e10cSrcweir 		}
333cdf0e10cSrcweir 	}
334cdf0e10cSrcweir 	else
335cdf0e10cSrcweir 	{
336cdf0e10cSrcweir 		xub_StrLen nWrPos;
337cdf0e10cSrcweir 		xub_StrLen nEnd = nPos + xub_StrLen( nDiff );
338cdf0e10cSrcweir 		if( STRING_LEN != GetBeginInv() )
339cdf0e10cSrcweir 		{
340cdf0e10cSrcweir 			if( nBeginInvalid > nPos )
341cdf0e10cSrcweir 				nBeginInvalid = nBeginInvalid + xub_StrLen( nDiff );
342cdf0e10cSrcweir 			if( nEndInvalid >= nPos )
343cdf0e10cSrcweir 				nEndInvalid = nEndInvalid + xub_StrLen( nDiff );
344cdf0e10cSrcweir 		}
345cdf0e10cSrcweir 		// Wenn wir mitten in einem falschen Wort stehen, muss vom Wortanfang
346cdf0e10cSrcweir 		// invalidiert werden.
347cdf0e10cSrcweir         if( i < Count() && nPos >= ( nWrPos = Pos( i ) ) )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             Invalidate( nWrPos, nEnd );
350cdf0e10cSrcweir             xub_StrLen nWrLen = Len( i ) + xub_StrLen( nDiff );
351cdf0e10cSrcweir             maList[i++].mnLen = nWrLen;
352cdf0e10cSrcweir             nWrLen = nWrLen + nWrPos;
353cdf0e10cSrcweir             Invalidate( nWrPos, nWrLen );
354cdf0e10cSrcweir         }
355cdf0e10cSrcweir         else
356cdf0e10cSrcweir             Invalidate( nPos, nEnd );
357cdf0e10cSrcweir     }
358cdf0e10cSrcweir     while( i < Count() )
359cdf0e10cSrcweir     {
360cdf0e10cSrcweir         const xub_StrLen nTmp = static_cast<xub_StrLen>(nDiff + maList[i].mnPos);
361cdf0e10cSrcweir         maList[i++].mnPos = nTmp;
362cdf0e10cSrcweir     }
363cdf0e10cSrcweir }
364cdf0e10cSrcweir 
365cdf0e10cSrcweir /*************************************************************************
366cdf0e10cSrcweir  *                      SwWrongList::Fresh
367cdf0e10cSrcweir  *
368cdf0e10cSrcweir  * For a given range [nPos, nPos + nLen[ and an index nIndex, this function
369cdf0e10cSrcweir  * basically counts the number of SwWrongArea entries starting with nIndex
370cdf0e10cSrcweir  * up to nPos + nLen. All these entries are removed.
371cdf0e10cSrcweir  *************************************************************************/
Fresh(xub_StrLen & rStart,xub_StrLen & rEnd,xub_StrLen nPos,xub_StrLen nLen,MSHORT nIndex,xub_StrLen nCursorPos)372cdf0e10cSrcweir sal_Bool SwWrongList::Fresh( xub_StrLen &rStart, xub_StrLen &rEnd, xub_StrLen nPos,
373cdf0e10cSrcweir                              xub_StrLen nLen, MSHORT nIndex, xub_StrLen nCursorPos )
374cdf0e10cSrcweir {
375cdf0e10cSrcweir     // length of word must be greater than 0 and cursor position must be outside the word
376cdf0e10cSrcweir     sal_Bool bRet = nLen && ( nCursorPos > nPos + nLen || nCursorPos < nPos );
377cdf0e10cSrcweir 
378cdf0e10cSrcweir     xub_StrLen nWrPos = 0;
379cdf0e10cSrcweir     xub_StrLen nWrEnd = rEnd;
380cdf0e10cSrcweir     MSHORT nCnt = nIndex;
381cdf0e10cSrcweir     if( nCnt < Count() && ( nWrPos = Pos( nIndex ) ) < nPos )
382cdf0e10cSrcweir     {
383cdf0e10cSrcweir         if( rStart > nWrPos )
384cdf0e10cSrcweir             rStart = nWrPos;
385cdf0e10cSrcweir     }
386cdf0e10cSrcweir 
387cdf0e10cSrcweir     while( nCnt < Count() && ( nWrPos = Pos( nCnt ) ) < nPos )
388cdf0e10cSrcweir         nWrEnd = nWrPos + Len( nCnt++ );
389cdf0e10cSrcweir 
390cdf0e10cSrcweir     if( nCnt < Count() && nWrPos == nPos && Len( nCnt ) == nLen )
391cdf0e10cSrcweir     {
392cdf0e10cSrcweir         ++nCnt;
393cdf0e10cSrcweir         bRet = sal_True;
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir     else
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         if( bRet )
398cdf0e10cSrcweir         {
399cdf0e10cSrcweir             if( rStart > nPos )
400cdf0e10cSrcweir                 rStart = nPos;
401cdf0e10cSrcweir             nWrEnd = nPos + nLen;
402cdf0e10cSrcweir         }
403cdf0e10cSrcweir     }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir     nPos = nPos + nLen;
406cdf0e10cSrcweir 
407cdf0e10cSrcweir     if( nCnt < Count() && ( nWrPos = Pos( nCnt ) ) < nPos )
408cdf0e10cSrcweir     {
409cdf0e10cSrcweir         if( rStart > nWrPos )
410cdf0e10cSrcweir             rStart = nWrPos;
411cdf0e10cSrcweir     }
412cdf0e10cSrcweir 
413cdf0e10cSrcweir     while( nCnt < Count() && ( nWrPos = Pos( nCnt ) ) < nPos )
414cdf0e10cSrcweir         nWrEnd = nWrPos + Len( nCnt++ );
415cdf0e10cSrcweir 
416cdf0e10cSrcweir     if( rEnd < nWrEnd )
417cdf0e10cSrcweir         rEnd = nWrEnd;
418cdf0e10cSrcweir 
419cdf0e10cSrcweir     Remove( nIndex, nCnt - nIndex );
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     return bRet;
422cdf0e10cSrcweir }
423cdf0e10cSrcweir 
Invalidate(xub_StrLen nBegin,xub_StrLen nEnd)424cdf0e10cSrcweir void SwWrongList::Invalidate( xub_StrLen nBegin, xub_StrLen nEnd )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir     if (STRING_LEN == GetBeginInv())
427cdf0e10cSrcweir         SetInvalid( nBegin, nEnd );
428cdf0e10cSrcweir     else
429cdf0e10cSrcweir         _Invalidate( nBegin, nEnd );
430cdf0e10cSrcweir }
431cdf0e10cSrcweir 
InvalidateWrong()432cdf0e10cSrcweir sal_Bool SwWrongList::InvalidateWrong( )
433cdf0e10cSrcweir {
434cdf0e10cSrcweir 	if( Count() )
435cdf0e10cSrcweir 	{
436cdf0e10cSrcweir         xub_StrLen nFirst = Pos( 0 );
437cdf0e10cSrcweir         xub_StrLen nLast = Pos( Count() - 1 ) + Len( Count() - 1 );
438cdf0e10cSrcweir 		Invalidate( nFirst, nLast );
439cdf0e10cSrcweir 		return sal_True;
440cdf0e10cSrcweir 	}
441cdf0e10cSrcweir 	else
442cdf0e10cSrcweir 		return sal_False;
443cdf0e10cSrcweir }
444cdf0e10cSrcweir 
SplitList(xub_StrLen nSplitPos)445cdf0e10cSrcweir SwWrongList* SwWrongList::SplitList( xub_StrLen nSplitPos )
446cdf0e10cSrcweir {
447cdf0e10cSrcweir     SwWrongList *pRet = NULL;
448cdf0e10cSrcweir     MSHORT nLst = 0;
449cdf0e10cSrcweir     xub_StrLen nWrPos;
450cdf0e10cSrcweir     xub_StrLen nWrLen;
451cdf0e10cSrcweir     while( nLst < Count() && Pos( nLst ) < nSplitPos )
452cdf0e10cSrcweir         ++nLst;
453cdf0e10cSrcweir     if( nLst && ( nWrPos = Pos( nLst - 1 ) )
454cdf0e10cSrcweir         + ( nWrLen = Len( nLst - 1 ) ) > nSplitPos )
455cdf0e10cSrcweir     {
456cdf0e10cSrcweir         nWrLen += nWrPos - nSplitPos;
457cdf0e10cSrcweir         maList[--nLst].mnPos = nSplitPos;
458cdf0e10cSrcweir         maList[nLst].mnLen = nWrLen;
459cdf0e10cSrcweir     }
460cdf0e10cSrcweir     if( nLst )
461cdf0e10cSrcweir     {
462cdf0e10cSrcweir         if( WRONGLIST_GRAMMAR == GetWrongListType() )
463cdf0e10cSrcweir             pRet = new SwGrammarMarkUp();
464cdf0e10cSrcweir         else
465cdf0e10cSrcweir             pRet = new SwWrongList( GetWrongListType() );
466cdf0e10cSrcweir         pRet->Insert(0, maList.begin(), ( nLst >= maList.size() ? maList.end() : maList.begin() + nLst ) );
467cdf0e10cSrcweir         pRet->SetInvalid( GetBeginInv(), GetEndInv() );
468cdf0e10cSrcweir         pRet->_Invalidate( nSplitPos ? nSplitPos - 1 : nSplitPos, nSplitPos );
469cdf0e10cSrcweir         Remove( 0, nLst );
470cdf0e10cSrcweir     }
471cdf0e10cSrcweir     if( STRING_LEN == GetBeginInv() )
472cdf0e10cSrcweir         SetInvalid( 0, 1 );
473cdf0e10cSrcweir     else
474cdf0e10cSrcweir     {
475cdf0e10cSrcweir         ShiftLeft( nBeginInvalid, 0, nSplitPos );
476cdf0e10cSrcweir         ShiftLeft( nEndInvalid, 0, nSplitPos );
477cdf0e10cSrcweir         _Invalidate( 0, 1 );
478cdf0e10cSrcweir 	}
479cdf0e10cSrcweir     nLst = 0;
480cdf0e10cSrcweir     while( nLst < Count() )
481cdf0e10cSrcweir 	{
482cdf0e10cSrcweir         nWrPos = maList[nLst].mnPos - nSplitPos;
483cdf0e10cSrcweir         maList[nLst++].mnPos = nWrPos;
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir     return pRet;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir 
JoinList(SwWrongList * pNext,xub_StrLen nInsertPos)488cdf0e10cSrcweir void SwWrongList::JoinList( SwWrongList* pNext, xub_StrLen nInsertPos )
489cdf0e10cSrcweir {
490cdf0e10cSrcweir     if (pNext)
491cdf0e10cSrcweir     {
492cdf0e10cSrcweir         DBG_ASSERT( GetWrongListType() == pNext->GetWrongListType(), "type mismatch with next list" );
493cdf0e10cSrcweir     }
494cdf0e10cSrcweir     if( pNext )
495cdf0e10cSrcweir     {
496cdf0e10cSrcweir         sal_uInt16 nCnt = Count();
497cdf0e10cSrcweir         pNext->Move( 0, nInsertPos );
498cdf0e10cSrcweir         Insert(nCnt, pNext->maList.begin(), pNext->maList.end());
499cdf0e10cSrcweir 
500cdf0e10cSrcweir         Invalidate( pNext->GetBeginInv(), pNext->GetEndInv() );
501cdf0e10cSrcweir         if( nCnt && Count() > nCnt )
502cdf0e10cSrcweir         {
503cdf0e10cSrcweir             xub_StrLen nWrPos = Pos( nCnt );
504cdf0e10cSrcweir             xub_StrLen nWrLen = Len( nCnt );
505cdf0e10cSrcweir             if( !nWrPos )
506cdf0e10cSrcweir             {
507cdf0e10cSrcweir                 nWrPos = nWrPos + nInsertPos;
508cdf0e10cSrcweir                 nWrLen = nWrLen - nInsertPos;
509cdf0e10cSrcweir                 maList[nCnt].mnPos = nWrPos;
510cdf0e10cSrcweir                 maList[nCnt].mnLen = nWrLen;
511cdf0e10cSrcweir             }
512cdf0e10cSrcweir             if( nWrPos == Pos( nCnt - 1 ) + Len( nCnt - 1 ) )
513cdf0e10cSrcweir             {
514cdf0e10cSrcweir                 nWrLen = nWrLen + Len( nCnt - 1 );
515cdf0e10cSrcweir                 maList[nCnt - 1].mnLen = nWrLen;
516cdf0e10cSrcweir                 Remove( nCnt, 1 );
517cdf0e10cSrcweir             }
518cdf0e10cSrcweir         }
519cdf0e10cSrcweir     }
520cdf0e10cSrcweir     Invalidate( nInsertPos ? nInsertPos - 1 : nInsertPos, nInsertPos + 1 );
521cdf0e10cSrcweir }
522cdf0e10cSrcweir 
523cdf0e10cSrcweir 
InsertSubList(xub_StrLen nNewPos,xub_StrLen nNewLen,sal_uInt16 nWhere,SwWrongList * pSubList)524cdf0e10cSrcweir void SwWrongList::InsertSubList( xub_StrLen nNewPos, xub_StrLen nNewLen, sal_uInt16 nWhere, SwWrongList* pSubList )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir     if (pSubList)
527cdf0e10cSrcweir     {
528cdf0e10cSrcweir         DBG_ASSERT( GetWrongListType() == pSubList->GetWrongListType(), "type mismatch with sub list" );
529cdf0e10cSrcweir     }
530cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator i = maList.begin();
531cdf0e10cSrcweir     if ( nWhere >= maList.size() )
532cdf0e10cSrcweir         i = maList.end(); // robust
533cdf0e10cSrcweir     else
534cdf0e10cSrcweir         i += nWhere;
535cdf0e10cSrcweir     maList.insert(i, SwWrongArea( rtl::OUString(), 0, nNewPos, nNewLen, pSubList ) );
536cdf0e10cSrcweir }
537cdf0e10cSrcweir 
538cdf0e10cSrcweir 
539cdf0e10cSrcweir // New functions: Necessary because SwWrongList has been changed to use std::vector
Insert(sal_uInt16 nWhere,std::vector<SwWrongArea>::iterator startPos,std::vector<SwWrongArea>::iterator endPos)540cdf0e10cSrcweir void SwWrongList::Insert(sal_uInt16 nWhere, std::vector<SwWrongArea>::iterator startPos, std::vector<SwWrongArea>::iterator endPos)
541cdf0e10cSrcweir {
542cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator i = maList.begin();
543cdf0e10cSrcweir     if ( nWhere >= maList.size() )
544cdf0e10cSrcweir         i = maList.end(); // robust
545cdf0e10cSrcweir     else
546cdf0e10cSrcweir         i += nWhere;
547cdf0e10cSrcweir     maList.insert(i, startPos, endPos); // insert [startPos, endPos[ before i
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     // ownership of the sublist is passed to maList, therefore we have to set the
550cdf0e10cSrcweir     // pSubList-Pointers to 0
551cdf0e10cSrcweir     while ( startPos != endPos )
552cdf0e10cSrcweir     {
553cdf0e10cSrcweir         (*startPos).mpSubList = 0;
554cdf0e10cSrcweir         ++startPos;
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir }
557cdf0e10cSrcweir 
Remove(sal_uInt16 nIdx,sal_uInt16 nLen)558cdf0e10cSrcweir void SwWrongList::Remove(sal_uInt16 nIdx, sal_uInt16 nLen )
559cdf0e10cSrcweir {
560cdf0e10cSrcweir     if ( nIdx >= maList.size() ) return;
561cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator i1 = maList.begin();
562cdf0e10cSrcweir     i1 += nIdx;
563cdf0e10cSrcweir 
564cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator i2 = i1;
565cdf0e10cSrcweir     if ( nIdx + nLen >= static_cast<sal_uInt16>(maList.size()) )
566cdf0e10cSrcweir         i2 = maList.end(); // robust
567cdf0e10cSrcweir     else
568cdf0e10cSrcweir         i2 += nLen;
569cdf0e10cSrcweir 
570cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator iLoop = i1;
571cdf0e10cSrcweir     while ( iLoop != i2 )
572cdf0e10cSrcweir     {
573cdf0e10cSrcweir         if ( (*iLoop).mpSubList )
574cdf0e10cSrcweir             delete (*iLoop).mpSubList;
575cdf0e10cSrcweir         ++iLoop;
576cdf0e10cSrcweir     }
577cdf0e10cSrcweir 
578cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
579cdf0e10cSrcweir     const int nOldSize = Count();
580cdf0e10cSrcweir     (void) nOldSize;
581cdf0e10cSrcweir #endif
582cdf0e10cSrcweir 
583cdf0e10cSrcweir     maList.erase(i1, i2);
584cdf0e10cSrcweir 
585cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
586cdf0e10cSrcweir     ASSERT( Count() + nLen == nOldSize, "SwWrongList::Remove() trouble" )
587cdf0e10cSrcweir #endif
588cdf0e10cSrcweir }
589cdf0e10cSrcweir 
RemoveEntry(xub_StrLen nBegin,xub_StrLen nEnd)590cdf0e10cSrcweir void SwWrongList::RemoveEntry( xub_StrLen nBegin, xub_StrLen nEnd ) {
591cdf0e10cSrcweir     sal_uInt16 nDelPos = 0;
592cdf0e10cSrcweir     sal_uInt16 nDel = 0;
593cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator aIter = maList.begin();
594cdf0e10cSrcweir     while( aIter != maList.end() && (*aIter).mnPos < nBegin )
595cdf0e10cSrcweir     {
596cdf0e10cSrcweir         ++aIter;
597cdf0e10cSrcweir         ++nDelPos;
598cdf0e10cSrcweir     }
599cdf0e10cSrcweir     if( WRONGLIST_GRAMMAR == GetWrongListType() )
600cdf0e10cSrcweir     {
601cdf0e10cSrcweir         while( aIter != maList.end() && nBegin < nEnd && nEnd > (*aIter).mnPos )
602cdf0e10cSrcweir         {
603cdf0e10cSrcweir             ++aIter;
604cdf0e10cSrcweir             ++nDel;
605cdf0e10cSrcweir         }
606cdf0e10cSrcweir     }
607cdf0e10cSrcweir     else
608cdf0e10cSrcweir     {
609cdf0e10cSrcweir         while( aIter != maList.end() && nBegin == (*aIter).mnPos && nEnd == (*aIter).mnPos +(*aIter).mnLen )
610cdf0e10cSrcweir         {
611cdf0e10cSrcweir             ++aIter;
612cdf0e10cSrcweir             ++nDel;
613cdf0e10cSrcweir         }
614cdf0e10cSrcweir     }
615cdf0e10cSrcweir     if( nDel )
616cdf0e10cSrcweir         Remove( nDelPos, nDel );
617cdf0e10cSrcweir }
618cdf0e10cSrcweir 
LookForEntry(xub_StrLen nBegin,xub_StrLen nEnd)619cdf0e10cSrcweir bool SwWrongList::LookForEntry( xub_StrLen nBegin, xub_StrLen nEnd ) {
620cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator aIter = maList.begin();
621cdf0e10cSrcweir     while( aIter != maList.end() && (*aIter).mnPos < nBegin )
622cdf0e10cSrcweir         ++aIter;
623cdf0e10cSrcweir     if( aIter != maList.end() && nBegin == (*aIter).mnPos && nEnd == (*aIter).mnPos +(*aIter).mnLen )
624cdf0e10cSrcweir         return true;
625cdf0e10cSrcweir     return false;
626cdf0e10cSrcweir }
627cdf0e10cSrcweir 
Insert(const rtl::OUString & rType,com::sun::star::uno::Reference<com::sun::star::container::XStringKeyMap> xPropertyBag,xub_StrLen nNewPos,xub_StrLen nNewLen)628cdf0e10cSrcweir void SwWrongList::Insert( const rtl::OUString& rType,
629cdf0e10cSrcweir                           com::sun::star::uno::Reference< com::sun::star::container::XStringKeyMap > xPropertyBag,
630cdf0e10cSrcweir                           xub_StrLen nNewPos, xub_StrLen nNewLen )
631cdf0e10cSrcweir {
632cdf0e10cSrcweir     std::vector<SwWrongArea>::iterator aIter = maList.begin();
633cdf0e10cSrcweir 
634cdf0e10cSrcweir     while ( aIter != maList.end() )
635cdf0e10cSrcweir     {
636cdf0e10cSrcweir         const xub_StrLen nSTPos = (*aIter).mnPos;
637cdf0e10cSrcweir 
638cdf0e10cSrcweir         if ( nNewPos < nSTPos )
639cdf0e10cSrcweir         {
640cdf0e10cSrcweir             // insert at current position
641cdf0e10cSrcweir             break;
642cdf0e10cSrcweir         }
643cdf0e10cSrcweir         else if ( nNewPos == nSTPos )
644cdf0e10cSrcweir         {
645cdf0e10cSrcweir             while ( aIter != maList.end() && (*aIter).mnPos == nSTPos )
646cdf0e10cSrcweir             {
647cdf0e10cSrcweir                 const xub_StrLen nSTLen = (*aIter).mnLen;
648cdf0e10cSrcweir 
649cdf0e10cSrcweir                 if ( nNewLen < nSTLen )
650cdf0e10cSrcweir                 {
651cdf0e10cSrcweir                     // insert at current position
652cdf0e10cSrcweir                     break;
653cdf0e10cSrcweir                 }
654cdf0e10cSrcweir 
655cdf0e10cSrcweir                 ++aIter;
656cdf0e10cSrcweir             }
657cdf0e10cSrcweir 
658cdf0e10cSrcweir             break;
659cdf0e10cSrcweir         }
660cdf0e10cSrcweir 
661cdf0e10cSrcweir         ++aIter;
662cdf0e10cSrcweir     }
663cdf0e10cSrcweir 
664*46f38707SJürgen Schmidt     maList.insert(aIter, SwWrongArea( rType, meType, xPropertyBag, nNewPos, nNewLen) );
665cdf0e10cSrcweir }
666cdf0e10cSrcweir 
667cdf0e10cSrcweir 
668