xref: /aoo41x/main/sw/source/core/txtnode/ndhints.cxx (revision 69a74367)
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
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
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 
29cdf0e10cSrcweir #include "txatbase.hxx"
30cdf0e10cSrcweir #include "ndhints.hxx"
31cdf0e10cSrcweir #include <txtatr.hxx>
32cdf0e10cSrcweir 
33cdf0e10cSrcweir #ifndef PRODUCT
34cdf0e10cSrcweir #include <pam.hxx>
35cdf0e10cSrcweir #endif
36cdf0e10cSrcweir 
37cdf0e10cSrcweir 
_SV_IMPL_SORTAR_ALG(SwpHtStart,SwTxtAttr *)38cdf0e10cSrcweir _SV_IMPL_SORTAR_ALG( SwpHtStart, SwTxtAttr* )
39cdf0e10cSrcweir _SV_IMPL_SORTAR_ALG( SwpHtEnd, SwTxtAttr* )
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #ifdef NIE
42cdf0e10cSrcweir 
43cdf0e10cSrcweir void DumpHints( const SwpHtStart &rHtStart,
44cdf0e10cSrcweir 				const SwpHtEnd &rHtEnd )
45cdf0e10cSrcweir {
46cdf0e10cSrcweir #ifdef DBG_UTIL
47cdf0e10cSrcweir 	aDbstream << "DumpHints:" << endl;
48cdf0e10cSrcweir 	(aDbstream << "\tStarts:" ).WriteNumber(rHtStart.Count()) << endl;
49cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < rHtStart.Count(); ++i )
50cdf0e10cSrcweir 	{
51cdf0e10cSrcweir 		const SwTxtAttr *pHt = rHtStart[i];
52cdf0e10cSrcweir 		((((aDbstream << '\t').WriteNumber( i )<< " [").WriteNumber( pHt->Which() )
53cdf0e10cSrcweir 			<< ']' << '\t').WriteNumber( long( pHt ) )
54cdf0e10cSrcweir 				  << '\t').WriteNumber( *pHt->GetStart() );
55*69a74367SOliver-Rainer Wittmann 		if( pHt->End() )
56*69a74367SOliver-Rainer Wittmann 			(aDbstream << " -> " ).WriteNumber( *pHt->End() );
57cdf0e10cSrcweir 		aDbstream << endl;
58cdf0e10cSrcweir 	}
59cdf0e10cSrcweir 	(aDbstream << "\tEnds:").WriteNumber( rHtEnd.Count() )<< endl;
60cdf0e10cSrcweir 	for( i = 0; i < rHtEnd.Count(); ++i )
61cdf0e10cSrcweir 	{
62cdf0e10cSrcweir 		const SwTxtAttr *pHt = rHtEnd[i];
63cdf0e10cSrcweir 		(((aDbstream << '\t').WriteNumber( i )<< " [").WriteNumber( pHt->Which() )
64cdf0e10cSrcweir 			<< ']' << '\t' ).WriteNumber( long( pHt ) );
65*69a74367SOliver-Rainer Wittmann 		if( pHt->End() )
66*69a74367SOliver-Rainer Wittmann 			(aDbstream << '\t').WriteNumber( *pHt->End() )<< " <- ";
67cdf0e10cSrcweir 		aDbstream.WriteNumber( *pHt->GetStart() )<< endl;
68cdf0e10cSrcweir 	}
69cdf0e10cSrcweir 	aDbstream << endl;
70cdf0e10cSrcweir #endif
71cdf0e10cSrcweir }
72cdf0e10cSrcweir #else
73cdf0e10cSrcweir inline void DumpHints(const SwpHtStart &, const SwpHtEnd &) { }
74cdf0e10cSrcweir #endif
75cdf0e10cSrcweir 
76cdf0e10cSrcweir /*************************************************************************
77cdf0e10cSrcweir  *                        inline IsEqual()
78cdf0e10cSrcweir  *************************************************************************/
79cdf0e10cSrcweir 
IsEqual(const SwTxtAttr & rHt1,const SwTxtAttr & rHt2)80cdf0e10cSrcweir inline sal_Bool IsEqual( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir 	return (long)(&rHt1) == (long)(&rHt2);
83cdf0e10cSrcweir }
84cdf0e10cSrcweir 
85cdf0e10cSrcweir /*************************************************************************
86cdf0e10cSrcweir  *                      IsLessStart()
87cdf0e10cSrcweir  *************************************************************************/
88cdf0e10cSrcweir 
89cdf0e10cSrcweir // SV_IMPL_OP_PTRARR_SORT( SwpHtStart, SwTxtAttr* )
90cdf0e10cSrcweir // kein SV_IMPL_PTRARR_SORT( name,ArrElement )
91cdf0e10cSrcweir // unser SEEK_PTR_TO_OBJECT_NOTL( name,ArrElement )
92cdf0e10cSrcweir 
93cdf0e10cSrcweir // Sortierreihenfolge: Start, Ende (umgekehrt!), Which-Wert (umgekehrt!),
94cdf0e10cSrcweir // 					   als letztes die Adresse selbst
95cdf0e10cSrcweir 
lcl_IsLessStart(const SwTxtAttr & rHt1,const SwTxtAttr & rHt2)96cdf0e10cSrcweir static sal_Bool lcl_IsLessStart( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
97cdf0e10cSrcweir {
98cdf0e10cSrcweir 	if ( *rHt1.GetStart() == *rHt2.GetStart() )
99cdf0e10cSrcweir 	{
100cdf0e10cSrcweir         const xub_StrLen nHt1 = *rHt1.GetAnyEnd();
101cdf0e10cSrcweir         const xub_StrLen nHt2 = *rHt2.GetAnyEnd();
102cdf0e10cSrcweir 		if ( nHt1 == nHt2 )
103cdf0e10cSrcweir 		{
104cdf0e10cSrcweir             const sal_uInt16 nWhich1 = rHt1.Which();
105cdf0e10cSrcweir             const sal_uInt16 nWhich2 = rHt2.Which();
106cdf0e10cSrcweir             if ( nWhich1 == nWhich2 )
107cdf0e10cSrcweir             {
108cdf0e10cSrcweir                 if ( RES_TXTATR_CHARFMT == nWhich1 )
109cdf0e10cSrcweir                 {
110cdf0e10cSrcweir                     const sal_uInt16 nS1 = static_cast<const SwTxtCharFmt&>(rHt1).GetSortNumber();
111cdf0e10cSrcweir                     const sal_uInt16 nS2 = static_cast<const SwTxtCharFmt&>(rHt2).GetSortNumber();
112cdf0e10cSrcweir                     ASSERT( nS1 != nS2, "AUTOSTYLES: lcl_IsLessStart trouble" )
113cdf0e10cSrcweir                     if ( nS1 != nS2 ) // robust
114cdf0e10cSrcweir                         return nS1 < nS2;
115cdf0e10cSrcweir                 }
116cdf0e10cSrcweir 
117cdf0e10cSrcweir                 return (long)&rHt1 < (long)&rHt2;
118cdf0e10cSrcweir             }
119cdf0e10cSrcweir             // order is important! for requirements see hintids.hxx
120cdf0e10cSrcweir             return ( nWhich1 > nWhich2 );
121cdf0e10cSrcweir         }
122cdf0e10cSrcweir         return ( nHt1 > nHt2 );
123cdf0e10cSrcweir 	}
124cdf0e10cSrcweir 	return ( *rHt1.GetStart() < *rHt2.GetStart() );
125cdf0e10cSrcweir }
126cdf0e10cSrcweir 
127cdf0e10cSrcweir /*************************************************************************
128cdf0e10cSrcweir  *                      inline IsLessEnd()
129cdf0e10cSrcweir  *************************************************************************/
130cdf0e10cSrcweir 
131cdf0e10cSrcweir // Zuerst nach Ende danach nach Ptr
lcl_IsLessEnd(const SwTxtAttr & rHt1,const SwTxtAttr & rHt2)132cdf0e10cSrcweir static sal_Bool lcl_IsLessEnd( const SwTxtAttr &rHt1, const SwTxtAttr &rHt2 )
133cdf0e10cSrcweir {
134cdf0e10cSrcweir     const xub_StrLen nHt1 = *rHt1.GetAnyEnd();
135cdf0e10cSrcweir     const xub_StrLen nHt2 = *rHt2.GetAnyEnd();
136cdf0e10cSrcweir 	if ( nHt1 == nHt2 )
137cdf0e10cSrcweir 	{
138cdf0e10cSrcweir 		if ( *rHt1.GetStart() == *rHt2.GetStart() )
139cdf0e10cSrcweir 		{
140cdf0e10cSrcweir             const sal_uInt16 nWhich1 = rHt1.Which();
141cdf0e10cSrcweir             const sal_uInt16 nWhich2 = rHt2.Which();
142cdf0e10cSrcweir             if ( nWhich1 == nWhich2 )
143cdf0e10cSrcweir             {
144cdf0e10cSrcweir                 if ( RES_TXTATR_CHARFMT == nWhich1 )
145cdf0e10cSrcweir                 {
146cdf0e10cSrcweir                     const sal_uInt16 nS1 = static_cast<const SwTxtCharFmt&>(rHt1).GetSortNumber();
147cdf0e10cSrcweir                     const sal_uInt16 nS2 = static_cast<const SwTxtCharFmt&>(rHt2).GetSortNumber();
148cdf0e10cSrcweir                     ASSERT( nS1 != nS2, "AUTOSTYLES: lcl_IsLessEnd trouble" )
149cdf0e10cSrcweir                     if ( nS1 != nS2 ) // robust
150cdf0e10cSrcweir                         return nS1 > nS2;
151cdf0e10cSrcweir                 }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir                 return (long)&rHt1 > (long)&rHt2;
154cdf0e10cSrcweir             }
155cdf0e10cSrcweir             // order is important! for requirements see hintids.hxx
156cdf0e10cSrcweir             return ( nWhich1 < nWhich2 );
157cdf0e10cSrcweir         }
158cdf0e10cSrcweir 		else
159cdf0e10cSrcweir 			return ( *rHt1.GetStart() > *rHt2.GetStart() );
160cdf0e10cSrcweir 	}
161cdf0e10cSrcweir 	return ( nHt1 < nHt2 );
162cdf0e10cSrcweir }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir /*************************************************************************
165cdf0e10cSrcweir  *                      SwpHtStart::Seek_Entry()
166cdf0e10cSrcweir  *************************************************************************/
167cdf0e10cSrcweir 
Seek_Entry(const SwTxtAttr * pElement,sal_uInt16 * pPos) const168cdf0e10cSrcweir sal_Bool SwpHtStart::Seek_Entry( const SwTxtAttr *pElement, sal_uInt16 *pPos ) const
169cdf0e10cSrcweir {
170cdf0e10cSrcweir 	sal_uInt16 nOben = Count(), nMitte, nUnten = 0;
171cdf0e10cSrcweir 	if( nOben > 0 )
172cdf0e10cSrcweir 	{
173cdf0e10cSrcweir 		nOben--;
174cdf0e10cSrcweir 		while( nUnten <= nOben )
175cdf0e10cSrcweir 		{
176cdf0e10cSrcweir 			nMitte = nUnten + ( nOben - nUnten ) / 2;
177cdf0e10cSrcweir 			const SwTxtAttr *pMitte = (*this)[nMitte];
178cdf0e10cSrcweir 			if( IsEqual( *pMitte, *pElement ) )
179cdf0e10cSrcweir 			{
180cdf0e10cSrcweir 				*pPos = nMitte;
181cdf0e10cSrcweir 				return sal_True;
182cdf0e10cSrcweir 			}
183cdf0e10cSrcweir 			else
184cdf0e10cSrcweir 				if( lcl_IsLessStart( *pMitte, *pElement ) )
185cdf0e10cSrcweir 					nUnten = nMitte + 1;
186cdf0e10cSrcweir 				else
187cdf0e10cSrcweir 					if( nMitte == 0 )
188cdf0e10cSrcweir 					{
189cdf0e10cSrcweir 						*pPos = nUnten;
190cdf0e10cSrcweir 						return sal_False;
191cdf0e10cSrcweir 					}
192cdf0e10cSrcweir 					else
193cdf0e10cSrcweir 						nOben = nMitte - 1;
194cdf0e10cSrcweir 		}
195cdf0e10cSrcweir 	}
196cdf0e10cSrcweir 	*pPos = nUnten;
197cdf0e10cSrcweir 	return sal_False;
198cdf0e10cSrcweir }
199cdf0e10cSrcweir 
200cdf0e10cSrcweir /*************************************************************************
201cdf0e10cSrcweir  *                      SwpHtEnd::Seek_Entry()
202cdf0e10cSrcweir  *************************************************************************/
203cdf0e10cSrcweir 
Seek_Entry(const SwTxtAttr * pElement,sal_uInt16 * pPos) const204cdf0e10cSrcweir sal_Bool SwpHtEnd::Seek_Entry( const SwTxtAttr *pElement, sal_uInt16 *pPos ) const
205cdf0e10cSrcweir {
206cdf0e10cSrcweir 	sal_uInt16 nOben = Count(), nMitte, nUnten = 0;
207cdf0e10cSrcweir 	if( nOben > 0 )
208cdf0e10cSrcweir 	{
209cdf0e10cSrcweir 		nOben--;
210cdf0e10cSrcweir 		while( nUnten <= nOben )
211cdf0e10cSrcweir 		{
212cdf0e10cSrcweir 			nMitte = nUnten + ( nOben - nUnten ) / 2;
213cdf0e10cSrcweir 			const SwTxtAttr *pMitte = (*this)[nMitte];
214cdf0e10cSrcweir 			if( IsEqual( *pMitte, *pElement ) )
215cdf0e10cSrcweir 			{
216cdf0e10cSrcweir 				*pPos = nMitte;
217cdf0e10cSrcweir 				return sal_True;
218cdf0e10cSrcweir 			}
219cdf0e10cSrcweir 			else
220cdf0e10cSrcweir 				if( lcl_IsLessEnd( *pMitte, *pElement ) )
221cdf0e10cSrcweir 					nUnten = nMitte + 1;
222cdf0e10cSrcweir 				else
223cdf0e10cSrcweir 					if( nMitte == 0 )
224cdf0e10cSrcweir 					{
225cdf0e10cSrcweir 						*pPos = nUnten;
226cdf0e10cSrcweir 						return sal_False;
227cdf0e10cSrcweir 					}
228cdf0e10cSrcweir 					else
229cdf0e10cSrcweir 						nOben = nMitte - 1;
230cdf0e10cSrcweir 		}
231cdf0e10cSrcweir 	}
232cdf0e10cSrcweir 	*pPos = nUnten;
233cdf0e10cSrcweir 	return sal_False;
234cdf0e10cSrcweir }
235cdf0e10cSrcweir 
236cdf0e10cSrcweir /*************************************************************************
237cdf0e10cSrcweir  *                      class SwpHintsArr
238cdf0e10cSrcweir  *************************************************************************/
239cdf0e10cSrcweir 
Insert(const SwTxtAttr * pHt)240cdf0e10cSrcweir void SwpHintsArray::Insert( const SwTxtAttr *pHt )
241cdf0e10cSrcweir {
242cdf0e10cSrcweir     Resort();
243cdf0e10cSrcweir #ifdef DBG_UTIL
244cdf0e10cSrcweir     sal_uInt16 nPos;
245cdf0e10cSrcweir     ASSERT(!m_HintStarts.Seek_Entry( pHt, &nPos ),
246cdf0e10cSrcweir             "Insert: hint already in HtStart");
247cdf0e10cSrcweir     ASSERT(!m_HintEnds.Seek_Entry( pHt, &nPos ),
248cdf0e10cSrcweir             "Insert: hint already in HtEnd");
249cdf0e10cSrcweir #endif
250cdf0e10cSrcweir     m_HintStarts.Insert( pHt );
251cdf0e10cSrcweir     m_HintEnds.Insert( pHt );
252cdf0e10cSrcweir #ifdef DBG_UTIL
253cdf0e10cSrcweir #ifdef NIE
254cdf0e10cSrcweir     (aDbstream << "Insert: " ).WriteNumber( long( pHt ) ) << endl;
255cdf0e10cSrcweir     DumpHints( m_HintStarts, m_HintEnds );
256cdf0e10cSrcweir #endif
257cdf0e10cSrcweir #endif
258cdf0e10cSrcweir }
259cdf0e10cSrcweir 
DeleteAtPos(const sal_uInt16 nPos)260cdf0e10cSrcweir void SwpHintsArray::DeleteAtPos( const sal_uInt16 nPos )
261cdf0e10cSrcweir {
262cdf0e10cSrcweir     // optimization: nPos is the position in the Starts array
263cdf0e10cSrcweir     const SwTxtAttr *pHt = m_HintStarts[ nPos ];
264cdf0e10cSrcweir     m_HintStarts.Remove( nPos );
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     Resort();
267cdf0e10cSrcweir 
268cdf0e10cSrcweir     sal_uInt16 nEndPos;
269cdf0e10cSrcweir     m_HintEnds.Seek_Entry( pHt, &nEndPos );
270cdf0e10cSrcweir     m_HintEnds.Remove( nEndPos );
271cdf0e10cSrcweir #ifdef DBG_UTIL
272cdf0e10cSrcweir #ifdef NIE
273cdf0e10cSrcweir     (aDbstream << "DeleteAtPos: " ).WriteNumber( long( pHt ) ) << endl;
274cdf0e10cSrcweir     DumpHints( m_HintStarts, m_HintEnds );
275cdf0e10cSrcweir #endif
276cdf0e10cSrcweir #endif
277cdf0e10cSrcweir }
278cdf0e10cSrcweir 
279cdf0e10cSrcweir #ifdef DBG_UTIL
280cdf0e10cSrcweir 
281cdf0e10cSrcweir /*************************************************************************
282cdf0e10cSrcweir  *                      SwpHintsArray::Check()
283cdf0e10cSrcweir  *************************************************************************/
284cdf0e10cSrcweir 
285cdf0e10cSrcweir 
286cdf0e10cSrcweir #define CHECK_ERR(cond, text) \
287cdf0e10cSrcweir         if(!(cond)) \
288cdf0e10cSrcweir         { \
289cdf0e10cSrcweir             ASSERT(!this, text); \
290cdf0e10cSrcweir             DumpHints(m_HintStarts, m_HintEnds); \
291cdf0e10cSrcweir             return !(const_cast<SwpHintsArray*>(this))->Resort(); \
292cdf0e10cSrcweir         }
293cdf0e10cSrcweir 
Check() const294cdf0e10cSrcweir bool SwpHintsArray::Check() const
295cdf0e10cSrcweir {
296cdf0e10cSrcweir 	// 1) gleiche Anzahl in beiden Arrays
297cdf0e10cSrcweir     CHECK_ERR( m_HintStarts.Count() == m_HintEnds.Count(),
298cdf0e10cSrcweir         "HintsCheck: wrong sizes" );
299cdf0e10cSrcweir 	xub_StrLen nLastStart = 0;
300cdf0e10cSrcweir 	xub_StrLen nLastEnd   = 0;
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 	const SwTxtAttr *pLastStart = 0;
303cdf0e10cSrcweir 	const SwTxtAttr *pLastEnd = 0;
304cdf0e10cSrcweir 
305cdf0e10cSrcweir 	for( sal_uInt16 i = 0; i < Count(); ++i )
306cdf0e10cSrcweir 	{
307cdf0e10cSrcweir 		// --- Start-Kontrolle ---
308cdf0e10cSrcweir 
309cdf0e10cSrcweir 		// 2a) gueltiger Pointer? vgl. DELETEFF
310cdf0e10cSrcweir         const SwTxtAttr *pHt = m_HintStarts[i];
311cdf0e10cSrcweir 		CHECK_ERR( 0xFF != *(unsigned char*)pHt, "HintsCheck: start ptr was deleted" );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir 		// 3a) Stimmt die Start-Sortierung?
314cdf0e10cSrcweir 		xub_StrLen nIdx = *pHt->GetStart();
315cdf0e10cSrcweir 		CHECK_ERR( nIdx >= nLastStart, "HintsCheck: starts are unsorted" );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 		// 4a) IsLessStart-Konsistenz
318cdf0e10cSrcweir 		if( pLastStart )
319cdf0e10cSrcweir 			CHECK_ERR( lcl_IsLessStart( *pLastStart, *pHt ), "HintsCheck: IsLastStart" );
320cdf0e10cSrcweir 
321cdf0e10cSrcweir 		nLastStart = nIdx;
322cdf0e10cSrcweir 		pLastStart = pHt;
323cdf0e10cSrcweir 
324cdf0e10cSrcweir 		// --- End-Kontrolle ---
325cdf0e10cSrcweir 
326cdf0e10cSrcweir 		// 2b) gueltiger Pointer? vgl. DELETEFF
327cdf0e10cSrcweir         const SwTxtAttr *pHtEnd = m_HintEnds[i];
328cdf0e10cSrcweir 		CHECK_ERR( 0xFF != *(unsigned char*)pHtEnd, "HintsCheck: end ptr was deleted" );
329cdf0e10cSrcweir 
330cdf0e10cSrcweir 		// 3b) Stimmt die End-Sortierung?
331cdf0e10cSrcweir 		nIdx = *pHtEnd->GetAnyEnd();
332cdf0e10cSrcweir 		CHECK_ERR( nIdx >= nLastEnd, "HintsCheck: ends are unsorted" );
333cdf0e10cSrcweir 		nLastEnd = nIdx;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 		// 4b) IsLessEnd-Konsistenz
336cdf0e10cSrcweir 		if( pLastEnd )
337cdf0e10cSrcweir 			CHECK_ERR( lcl_IsLessEnd( *pLastEnd, *pHtEnd ), "HintsCheck: IsLastEnd" );
338cdf0e10cSrcweir 
339cdf0e10cSrcweir 		nLastEnd = nIdx;
340cdf0e10cSrcweir 		pLastEnd = pHtEnd;
341cdf0e10cSrcweir 
342cdf0e10cSrcweir 		// --- Ueberkreuzungen ---
343cdf0e10cSrcweir 
344cdf0e10cSrcweir 		// 5) gleiche Pointer in beiden Arrays
345cdf0e10cSrcweir         if( !m_HintStarts.Seek_Entry( pHt, &nIdx ) )
346cdf0e10cSrcweir             nIdx = STRING_LEN;
347cdf0e10cSrcweir 
348cdf0e10cSrcweir         CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetStartOf" );
349cdf0e10cSrcweir 
350cdf0e10cSrcweir 		// 6) gleiche Pointer in beiden Arrays
351cdf0e10cSrcweir         if( !m_HintEnds.Seek_Entry( pHt, &nIdx ) )
352cdf0e10cSrcweir             nIdx = STRING_LEN;
353cdf0e10cSrcweir 
354cdf0e10cSrcweir         CHECK_ERR( STRING_LEN != nIdx, "HintsCheck: no GetEndOf" );
355cdf0e10cSrcweir 
356cdf0e10cSrcweir         // 7a) character attributes in array?
357cdf0e10cSrcweir         sal_uInt16 nWhich = pHt->Which();
358cdf0e10cSrcweir         CHECK_ERR( !isCHRATR(nWhich),
359cdf0e10cSrcweir                    "HintsCheck: Character attribute in start array" );
360cdf0e10cSrcweir 
361cdf0e10cSrcweir         // 7b) character attributes in array?
362cdf0e10cSrcweir         nWhich = pHtEnd->Which();
363cdf0e10cSrcweir         CHECK_ERR( !isCHRATR(nWhich),
364cdf0e10cSrcweir                    "HintsCheck: Character attribute in end array" );
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         // 8) style portion check
367cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 1
368cdf0e10cSrcweir         const SwTxtAttr* pHtThis = m_HintStarts[i];
369cdf0e10cSrcweir         const SwTxtAttr* pHtLast = i > 0 ? m_HintStarts[i-1] : 0;
370cdf0e10cSrcweir         CHECK_ERR( 0 == i ||
371cdf0e10cSrcweir                     ( RES_TXTATR_CHARFMT != pHtLast->Which() && RES_TXTATR_AUTOFMT != pHtLast->Which() ) ||
372cdf0e10cSrcweir                     ( RES_TXTATR_CHARFMT != pHtThis->Which() && RES_TXTATR_AUTOFMT != pHtThis->Which() ) ||
373*69a74367SOliver-Rainer Wittmann                     ( *pHtThis->GetStart() >= *pHtLast->End() ) ||
374cdf0e10cSrcweir                     (   (   (   (*pHtThis->GetStart() == *pHtLast->GetStart())
375*69a74367SOliver-Rainer Wittmann                             &&  (*pHtThis->End()   == *pHtLast->End())
376cdf0e10cSrcweir                             ) // same range
377*69a74367SOliver-Rainer Wittmann                         ||  (*pHtThis->GetStart() == *pHtThis->End())
378cdf0e10cSrcweir                         )
379cdf0e10cSrcweir                     &&  (   (pHtThis->Which() != RES_TXTATR_AUTOFMT)
380cdf0e10cSrcweir                         ||  (pHtLast->Which() != RES_TXTATR_AUTOFMT)
381cdf0e10cSrcweir                         ) // never two AUTOFMT on same range
382cdf0e10cSrcweir                     ),
383cdf0e10cSrcweir                    "HintsCheck: Portion inconsistency. "
384cdf0e10cSrcweir                    "This can be temporarily ok during undo operations" );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir         // 9) nesting portion check
387cdf0e10cSrcweir         if (pHtThis->IsNesting())
388cdf0e10cSrcweir         {
389cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < Count(); ++j )
390cdf0e10cSrcweir             {
391cdf0e10cSrcweir                 SwTxtAttr const * const pOther( m_HintStarts[j] );
392cdf0e10cSrcweir                 if ( pOther->IsNesting() &&  (i != j) )
393cdf0e10cSrcweir                 {
394cdf0e10cSrcweir                     SwComparePosition cmp = ComparePosition(
395*69a74367SOliver-Rainer Wittmann                         *pHtThis->GetStart(), *pHtThis->End(),
396*69a74367SOliver-Rainer Wittmann                         *pOther->GetStart(), *pOther->End());
397cdf0e10cSrcweir                     CHECK_ERR( (POS_OVERLAP_BEFORE != cmp) &&
398cdf0e10cSrcweir                                (POS_OVERLAP_BEHIND != cmp),
399cdf0e10cSrcweir                         "HintsCheck: overlapping nesting hints!!!" );
400cdf0e10cSrcweir                 }
401cdf0e10cSrcweir             }
402cdf0e10cSrcweir         }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir         // 10) dummy char check (unfortunately cannot check SwTxtNode::m_Text)
405cdf0e10cSrcweir         if (pHtThis->HasDummyChar())
406cdf0e10cSrcweir         {
407cdf0e10cSrcweir             for ( sal_uInt16 j = 0; j < i; ++j )
408cdf0e10cSrcweir             {
409cdf0e10cSrcweir                 SwTxtAttr const * const pOther( m_HintStarts[j] );
410cdf0e10cSrcweir                 if (pOther->HasDummyChar())
411cdf0e10cSrcweir                 {
412cdf0e10cSrcweir                     CHECK_ERR( (*pOther->GetStart() != *pHtThis->GetStart()),
413cdf0e10cSrcweir                         "HintsCheck: multiple hints claim same CH_TXTATR!");
414cdf0e10cSrcweir                 }
415cdf0e10cSrcweir             }
416cdf0e10cSrcweir         }
417cdf0e10cSrcweir #endif
418cdf0e10cSrcweir     }
419cdf0e10cSrcweir     return true;
420cdf0e10cSrcweir }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir #endif      /* PRODUCT */
423cdf0e10cSrcweir 
424cdf0e10cSrcweir /*************************************************************************
425cdf0e10cSrcweir  *                          SwpHintsArray::Resort()
426cdf0e10cSrcweir  *************************************************************************/
427cdf0e10cSrcweir 
428cdf0e10cSrcweir // Resort() wird vor jedem Insert und Delete gerufen.
429cdf0e10cSrcweir // Wenn Textmasse geloescht wird, so werden die Indizes in
430cdf0e10cSrcweir // ndtxt.cxx angepasst. Leider erfolgt noch keine Neusortierung
431cdf0e10cSrcweir // auf gleichen Positionen.
432cdf0e10cSrcweir 
Resort()433cdf0e10cSrcweir bool SwpHintsArray::Resort()
434cdf0e10cSrcweir {
435cdf0e10cSrcweir     bool bResort = false;
436cdf0e10cSrcweir 	const SwTxtAttr *pLast = 0;
437cdf0e10cSrcweir 	sal_uInt16 i;
438cdf0e10cSrcweir 
439cdf0e10cSrcweir     for ( i = 0; i < m_HintStarts.Count(); ++i )
440cdf0e10cSrcweir     {
441cdf0e10cSrcweir         const SwTxtAttr *pHt = m_HintStarts[i];
442cdf0e10cSrcweir 		if( pLast && !lcl_IsLessStart( *pLast, *pHt ) )
443cdf0e10cSrcweir 		{
444cdf0e10cSrcweir #ifdef NIE
445cdf0e10cSrcweir #ifdef DBG_UTIL
446cdf0e10cSrcweir //            ASSERT( bResort, "!Resort/Start: correcting hints-array" );
447cdf0e10cSrcweir 			aDbstream << "Resort: Starts" << endl;
448cdf0e10cSrcweir             DumpHints( m_HintStarts, m_HintEnds );
449cdf0e10cSrcweir #endif
450cdf0e10cSrcweir #endif
451cdf0e10cSrcweir             m_HintStarts.Remove( i );
452cdf0e10cSrcweir             m_HintStarts.Insert( pHt );
453cdf0e10cSrcweir             pHt = m_HintStarts[i];
454cdf0e10cSrcweir 			if ( pHt != pLast )
455cdf0e10cSrcweir 				--i;
456cdf0e10cSrcweir             bResort = true;
457cdf0e10cSrcweir         }
458cdf0e10cSrcweir 		pLast = pHt;
459cdf0e10cSrcweir 	}
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 	pLast = 0;
462cdf0e10cSrcweir     for ( i = 0; i < m_HintEnds.Count(); ++i )
463cdf0e10cSrcweir     {
464cdf0e10cSrcweir         const SwTxtAttr *pHt = m_HintEnds[i];
465cdf0e10cSrcweir 		if( pLast && !lcl_IsLessEnd( *pLast, *pHt ) )
466cdf0e10cSrcweir 		{
467cdf0e10cSrcweir #ifdef NIE
468cdf0e10cSrcweir #ifdef DBG_UTIL
469cdf0e10cSrcweir 			aDbstream << "Resort: Ends" << endl;
470cdf0e10cSrcweir             DumpHints( m_HintStarts, m_HintEnds );
471cdf0e10cSrcweir #endif
472cdf0e10cSrcweir #endif
473cdf0e10cSrcweir             m_HintEnds.Remove( i );
474cdf0e10cSrcweir             m_HintEnds.Insert( pHt );
475cdf0e10cSrcweir             pHt = m_HintEnds[i]; // normalerweise == pLast
476cdf0e10cSrcweir 			// Wenn die Unordnung etwas groesser ist (24200),
477cdf0e10cSrcweir 			// muessen wir Position i erneut vergleichen.
478cdf0e10cSrcweir 			if ( pLast != pHt )
479cdf0e10cSrcweir 				--i;
480cdf0e10cSrcweir             bResort = true;
481cdf0e10cSrcweir         }
482cdf0e10cSrcweir 		pLast = pHt;
483cdf0e10cSrcweir 	}
484cdf0e10cSrcweir #ifdef DBG_UTIL
485cdf0e10cSrcweir #ifdef NIE
486cdf0e10cSrcweir 	aDbstream << "Resorted:" << endl;
487cdf0e10cSrcweir     DumpHints( m_HintStarts, m_HintEnds );
488cdf0e10cSrcweir #endif
489cdf0e10cSrcweir #endif
490cdf0e10cSrcweir 	return bResort;
491cdf0e10cSrcweir }
492cdf0e10cSrcweir 
493cdf0e10cSrcweir 
494