Update ooo320-m1
[ooovba.git] / sw / source / core / text / frminf.cxx
blobd31091207517a7dfe743e5a00808b848ae24eaa7
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: frminf.cxx,v $
10 * $Revision: 1.10 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #include <pam.hxx> // GetSpaces
36 #include <txtcfg.hxx>
37 #include <frminf.hxx> // SwTxtFrminfo
38 #include <itrtxt.hxx> // SwTxtMargin
40 /*************************************************************************
41 * SwTxtMargin::GetTxtStart()
42 *************************************************************************/
44 xub_StrLen SwTxtMargin::GetTxtStart() const
46 const XubString &rTxt = GetInfo().GetTxt();
47 const xub_StrLen nTmpPos = nStart;
48 const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
49 xub_StrLen i;
51 for( i = nTmpPos; i < nEnd; ++i )
53 const xub_Unicode aChar = rTxt.GetChar( i );
54 if( CH_TAB != aChar && ' ' != aChar )
55 return i;
57 return i;
60 /*************************************************************************
61 * SwTxtMargin::GetTxtEnd()
62 *************************************************************************/
64 xub_StrLen SwTxtMargin::GetTxtEnd() const
66 const XubString &rTxt = GetInfo().GetTxt();
67 const xub_StrLen nTmpPos = nStart;
68 const xub_StrLen nEnd = nTmpPos + pCurr->GetLen();
69 long i;
70 for( i = nEnd - 1; i >= nTmpPos; --i )
72 xub_Unicode aChar = rTxt.GetChar( static_cast<xub_StrLen>(i) );
73 if( CH_TAB != aChar && CH_BREAK != aChar && ' ' != aChar )
74 return static_cast<xub_StrLen>(i + 1);
76 return static_cast<xub_StrLen>(i + 1);
79 /*************************************************************************
80 * SwTxtFrmInfo::IsOneLine()
81 *************************************************************************/
83 // Passt der Absatz in eine Zeile?
84 sal_Bool SwTxtFrmInfo::IsOneLine() const
86 const SwLineLayout *pLay = pFrm->GetPara();
87 if( !pLay )
88 return sal_False;
89 else
91 // 6575: bei Follows natuerlich sal_False
92 if( pFrm->GetFollow() )
93 return sal_False;
94 pLay = pLay->GetNext();
95 while( pLay )
97 if( pLay->GetLen() )
98 return sal_False;
99 pLay = pLay->GetNext();
101 return sal_True;
105 /*************************************************************************
106 * SwTxtFrmInfo::IsFilled()
107 *************************************************************************/
109 // Ist die Zeile zu X% gefuellt?
110 sal_Bool SwTxtFrmInfo::IsFilled( const sal_uInt8 nPercent ) const
112 const SwLineLayout *pLay = pFrm->GetPara();
113 if( !pLay )
114 return sal_False;
115 else
117 long nWidth = pFrm->Prt().Width();
118 nWidth *= nPercent;
119 nWidth /= 100;
120 return KSHORT(nWidth) <= pLay->Width();
124 /*************************************************************************
125 * SwTxtFrmInfo::GetLineStart()
126 *************************************************************************/
128 // Wo beginnt der Text (ohne whitespaces)? ( Dokument global )
129 SwTwips SwTxtFrmInfo::GetLineStart( const SwTxtCursor &rLine ) const
131 xub_StrLen nTxtStart = rLine.GetTxtStart();
132 SwTwips nStart;
133 if( rLine.GetStart() == nTxtStart )
134 nStart = rLine.GetLineStart();
135 else
137 SwRect aRect;
138 if( ((SwTxtCursor&)rLine).GetCharRect( &aRect, nTxtStart ) )
139 nStart = aRect.Left();
140 else
141 nStart = rLine.GetLineStart();
143 return nStart;
147 /*************************************************************************
148 * SwTxtFrmInfo::GetLineStart()
149 *************************************************************************/
151 // Wo beginnt der Text (ohne whitespaces)? (rel. im Frame)
152 SwTwips SwTxtFrmInfo::GetLineStart() const
154 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
155 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
156 return GetLineStart( aLine ) - pFrm->Frm().Left() - pFrm->Prt().Left();
159 // errechne die Position des Zeichens und gebe die Mittelposition zurueck
160 SwTwips SwTxtFrmInfo::GetCharPos( xub_StrLen nChar, sal_Bool bCenter ) const
162 SWRECTFN( pFrm )
163 SwFrmSwapper aSwapper( pFrm, sal_True );
165 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
166 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
168 SwTwips nStt, nNext;
169 SwRect aRect;
170 if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar ) )
172 if ( bVert )
173 pFrm->SwitchHorizontalToVertical( aRect );
175 nStt = (aRect.*fnRect->fnGetLeft)();
177 else
178 nStt = aLine.GetLineStart();
180 if( !bCenter )
181 return nStt - (pFrm->Frm().*fnRect->fnGetLeft)();
183 if( ((SwTxtCursor&)aLine).GetCharRect( &aRect, nChar+1 ) )
185 if ( bVert )
186 pFrm->SwitchHorizontalToVertical( aRect );
188 nNext = (aRect.*fnRect->fnGetLeft)();
190 else
191 nNext = aLine.GetLineStart();
193 return (( nNext + nStt ) / 2 ) - (pFrm->Frm().*fnRect->fnGetLeft)();
196 /*************************************************************************
197 * SwTxtFrmInfo::GetSpaces()
198 *************************************************************************/
200 SwPaM *AddPam( SwPaM *pPam, const SwTxtFrm* pTxtFrm,
201 const xub_StrLen nPos, const xub_StrLen nLen )
203 if( nLen )
205 // Es koennte auch der erste sein.
206 if( pPam->HasMark() )
208 // liegt die neue Position genau hinter der aktuellen, dann
209 // erweiter den Pam einfach
210 if( nPos == pPam->GetPoint()->nContent.GetIndex() )
212 pPam->GetPoint()->nContent += nLen;
213 return pPam;
215 pPam = new SwPaM( *pPam );
218 SwIndex &rContent = pPam->GetPoint()->nContent;
219 rContent.Assign( (SwTxtNode*)pTxtFrm->GetTxtNode(), nPos );
220 pPam->SetMark();
221 rContent += nLen;
223 return pPam;
226 // Sammelt die whitespaces am Zeilenbeginn und -ende im Pam
227 void SwTxtFrmInfo::GetSpaces( SwPaM &rPam, sal_Bool bWithLineBreak ) const
229 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
230 SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
231 SwPaM *pPam = &rPam;
232 sal_Bool bFirstLine = sal_True;
233 do {
235 if( aLine.GetCurr()->GetLen() )
237 xub_StrLen nPos = aLine.GetTxtStart();
238 // Bug 49649: von der ersten Line die Blanks/Tabs NICHT
239 // mit selektieren
240 if( !bFirstLine && nPos > aLine.GetStart() )
241 pPam = AddPam( pPam, pFrm, aLine.GetStart(),
242 nPos - aLine.GetStart() );
244 // Bug 49649: von der letzten Line die Blanks/Tabs NICHT
245 // mit selektieren
246 if( aLine.GetNext() )
248 nPos = aLine.GetTxtEnd();
250 if( nPos < aLine.GetEnd() )
252 MSHORT nOff = !bWithLineBreak && CH_BREAK ==
253 aLine.GetInfo().GetChar( aLine.GetEnd() - 1 )
254 ? 1 : 0;
255 pPam = AddPam( pPam, pFrm, nPos, aLine.GetEnd() - nPos - nOff );
259 bFirstLine = sal_False;
261 while( aLine.Next() );
264 /*************************************************************************
265 * SwTxtFrmInfo::IsBullet()
266 *************************************************************************/
268 // Ist an der Textposition ein Bullet/Symbol etc?
269 // Fonts: CharSet, SYMBOL und DONTKNOW
270 sal_Bool SwTxtFrmInfo::IsBullet( xub_StrLen nTxtStart ) const
272 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
273 SwTxtMargin aLine( (SwTxtFrm*)pFrm, &aInf );
274 aInf.SetIdx( nTxtStart );
275 return aLine.IsSymbol( nTxtStart );
278 /*************************************************************************
279 * SwTxtFrmInfo::GetFirstIndent()
280 *************************************************************************/
282 // Ermittelt Erstzeileneinzug
283 // Voraussetzung fuer pos. oder neg. EZE ist, dass alle
284 // Zeilen ausser der ersten Zeile den selben linken Rand haben.
285 // Wir wollen nicht so knauserig sein und arbeiten mit einer Toleranz
286 // von TOLERANCE Twips.
288 #define TOLERANCE 20
290 SwTwips SwTxtFrmInfo::GetFirstIndent() const
292 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
293 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
294 const SwTwips nFirst = GetLineStart( aLine );
295 if( !aLine.Next() )
296 return 0;
298 SwTwips nLeft = GetLineStart( aLine );
299 while( aLine.Next() )
301 if( aLine.GetCurr()->GetLen() )
303 const SwTwips nCurrLeft = GetLineStart( aLine );
304 if( nLeft + TOLERANCE < nCurrLeft ||
305 nLeft - TOLERANCE > nCurrLeft )
306 return 0;
310 // Vorerst wird nur +1, -1 und 0 returnt.
311 if( nLeft == nFirst )
312 return 0;
313 else
314 if( nLeft > nFirst )
315 return -1;
316 else
317 return +1;
320 /*************************************************************************
321 * SwTxtFrmInfo::GetBigIndent()
322 *************************************************************************/
324 KSHORT SwTxtFrmInfo::GetBigIndent( xub_StrLen& rFndPos,
325 const SwTxtFrm *pNextFrm ) const
327 SwTxtSizeInfo aInf( (SwTxtFrm*)pFrm );
328 SwTxtCursor aLine( (SwTxtFrm*)pFrm, &aInf );
329 SwTwips nNextIndent = 0;
331 if( pNextFrm )
333 // ich bin einzeilig
334 SwTxtSizeInfo aNxtInf( (SwTxtFrm*)pNextFrm );
335 SwTxtCursor aNxtLine( (SwTxtFrm*)pNextFrm, &aNxtInf );
336 nNextIndent = GetLineStart( aNxtLine );
338 else
340 // ich bin mehrzeilig
341 if( aLine.Next() )
343 nNextIndent = GetLineStart( aLine );
344 aLine.Prev();
348 if( nNextIndent <= GetLineStart( aLine ) )
349 return 0;
351 const Point aPoint( nNextIndent, aLine.Y() );
352 rFndPos = aLine.GetCrsrOfst( 0, aPoint, sal_False );
353 if( 1 >= rFndPos )
354 return 0;
356 // steht vor einem "nicht Space"
357 const XubString& rTxt = aInf.GetTxt();
358 xub_Unicode aChar = rTxt.GetChar( rFndPos );
359 if( CH_TAB == aChar || CH_BREAK == aChar || ' ' == aChar ||
360 (( CH_TXTATR_BREAKWORD == aChar || CH_TXTATR_INWORD == aChar ) &&
361 aInf.HasHint( rFndPos ) ) )
362 return 0;
364 // und hinter einem "Space"
365 aChar = rTxt.GetChar( rFndPos - 1 );
366 if( CH_TAB != aChar && CH_BREAK != aChar &&
367 ( ( CH_TXTATR_BREAKWORD != aChar && CH_TXTATR_INWORD != aChar ) ||
368 !aInf.HasHint( rFndPos - 1 ) ) &&
369 // mehr als 2 Blanks !!
370 ( ' ' != aChar || ' ' != rTxt.GetChar( rFndPos - 2 ) ) )
371 return 0;
373 SwRect aRect;
374 return aLine.GetCharRect( &aRect, rFndPos )
375 ? KSHORT( aRect.Left() - pFrm->Frm().Left() - pFrm->Prt().Left())
376 : 0;