bump product version to 4.1.6.2
[LibreOffice.git] / vcl / source / edit / textdata.cxx
blob10353c721116abd28cbd053a2bc4fae751c916cb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <vcl/textdata.hxx>
22 #include <textdat2.hxx>
24 #include <tools/debug.hxx>
27 TextSelection::TextSelection()
31 TextSelection::TextSelection( const TextPaM& rPaM ) :
32 maStartPaM( rPaM ), maEndPaM( rPaM )
36 TextSelection::TextSelection( const TextPaM& rStart, const TextPaM& rEnd ) :
37 maStartPaM( rStart ), maEndPaM( rEnd )
41 void TextSelection::Justify()
43 if ( maEndPaM < maStartPaM )
45 TextPaM aTemp( maStartPaM );
46 maStartPaM = maEndPaM;
47 maEndPaM = aTemp;
52 TETextPortionList::TETextPortionList()
56 TETextPortionList::~TETextPortionList()
58 Reset();
61 void TETextPortionList::Reset()
63 for ( iterator it = begin(); it != end(); ++it )
64 delete *it;
65 clear();
68 void TETextPortionList::DeleteFromPortion( sal_uInt16 nDelFrom )
70 DBG_ASSERT( ( nDelFrom < size() ) || ( (nDelFrom == 0) && (size() == 0) ), "DeleteFromPortion: Out of range" );
71 for ( iterator it = begin() + nDelFrom; it != end(); ++it )
72 delete *it;
73 erase( begin() + nDelFrom, end() );
76 sal_uInt16 TETextPortionList::FindPortion( sal_uInt16 nCharPos, sal_uInt16& nPortionStart, sal_Bool bPreferStartingPortion )
78 // find left portion at nCharPos at portion border
79 sal_uInt16 nTmpPos = 0;
80 for ( sal_uInt16 nPortion = 0; nPortion < size(); nPortion++ )
82 TETextPortion* pPortion = operator[]( nPortion );
83 nTmpPos = nTmpPos + pPortion->GetLen();
84 if ( nTmpPos >= nCharPos )
86 // take this one if we don't prefer the starting portion, or if it's the last one
87 if ( ( nTmpPos != nCharPos ) || !bPreferStartingPortion || ( nPortion == size() - 1 ) )
89 nPortionStart = nTmpPos - pPortion->GetLen();
90 return nPortion;
94 OSL_FAIL( "FindPortion: Nicht gefunden!" );
95 return ( size() - 1 );
99 TEParaPortion::TEParaPortion( TextNode* pN )
101 mpNode = pN;
102 mnInvalidPosStart = mnInvalidDiff = 0;
103 mbInvalid = sal_True;
104 mbSimple = sal_False;
107 TEParaPortion::~TEParaPortion()
111 void TEParaPortion::MarkInvalid( sal_uInt16 nStart, short nDiff )
113 if ( mbInvalid == sal_False )
115 mnInvalidPosStart = ( nDiff >= 0 ) ? nStart : ( nStart + nDiff );
116 mnInvalidDiff = nDiff;
118 else
120 // simple consecutive typing
121 if ( ( nDiff > 0 ) && ( mnInvalidDiff > 0 ) &&
122 ( ( mnInvalidPosStart+mnInvalidDiff ) == nStart ) )
124 mnInvalidDiff = mnInvalidDiff + nDiff;
126 // simple consecutive deleting
127 else if ( ( nDiff < 0 ) && ( mnInvalidDiff < 0 ) && ( mnInvalidPosStart == nStart ) )
129 mnInvalidPosStart = mnInvalidPosStart + nDiff;
130 mnInvalidDiff = mnInvalidDiff + nDiff;
132 else
134 DBG_ASSERT( ( nDiff >= 0 ) || ( (nStart+nDiff) >= 0 ), "MarkInvalid: Diff out of Range" );
135 mnInvalidPosStart = std::min( mnInvalidPosStart, (sal_uInt16) ( (nDiff < 0) ? nStart+nDiff : nDiff ) );
136 mnInvalidDiff = 0;
137 mbSimple = sal_False;
141 maWritingDirectionInfos.clear();
143 mbInvalid = sal_True;
146 void TEParaPortion::MarkSelectionInvalid( sal_uInt16 nStart, sal_uInt16 /*nEnd*/ )
148 if ( mbInvalid == sal_False )
150 mnInvalidPosStart = nStart;
151 // nInvalidPosEnd = nEnd;
153 else
155 mnInvalidPosStart = std::min( mnInvalidPosStart, nStart );
156 // nInvalidPosEnd = pNode->Len();
159 maWritingDirectionInfos.clear();
161 mnInvalidDiff = 0;
162 mbInvalid = sal_True;
163 mbSimple = sal_False;
166 sal_uInt16 TEParaPortion::GetLineNumber( sal_uInt16 nChar, sal_Bool bInclEnd )
168 for ( sal_uInt16 nLine = 0; nLine < maLines.size(); nLine++ )
170 TextLine* pLine = maLines[ nLine ];
171 if ( ( bInclEnd && ( pLine->GetEnd() >= nChar ) ) ||
172 ( pLine->GetEnd() > nChar ) )
174 return nLine;
178 // Then it should be at the end of the last line
179 OSL_ENSURE(nChar == maLines[maLines.size() - 1]->GetEnd(), "wrong Index");
180 OSL_ENSURE(!bInclEnd, "Line not found: FindLine");
181 return ( maLines.size() - 1 );
185 void TEParaPortion::CorrectValuesBehindLastFormattedLine( sal_uInt16 nLastFormattedLine )
187 sal_uInt16 nLines = maLines.size();
188 DBG_ASSERT( nLines, "CorrectPortionNumbersFromLine: Leere Portion?" );
189 if ( nLastFormattedLine < ( nLines - 1 ) )
191 const TextLine* pLastFormatted = maLines[ nLastFormattedLine ];
192 const TextLine* pUnformatted = maLines[ nLastFormattedLine+1 ];
193 short nPortionDiff = pUnformatted->GetStartPortion() - pLastFormatted->GetEndPortion();
194 short nTextDiff = pUnformatted->GetStart() - pLastFormatted->GetEnd();
195 nTextDiff++; // LastFormatted->GetEnd() was inclusive => subtracted one too much!
197 // The first unformated one has to start exactly one portion past the last
198 // formated one.
199 // If a portion got split in the changed row, nLastEnd could be > nNextStart!
200 short nPDiff = sal::static_int_cast< short >(-( nPortionDiff-1 ));
201 short nTDiff = sal::static_int_cast< short >(-( nTextDiff-1 ));
202 if ( nPDiff || nTDiff )
204 for ( sal_uInt16 nL = nLastFormattedLine+1; nL < nLines; nL++ )
206 TextLine* pLine = maLines[ nL ];
208 pLine->GetStartPortion() = pLine->GetStartPortion() + nPDiff;
209 pLine->GetEndPortion() = pLine->GetEndPortion() + nPDiff;
211 pLine->GetStart() = pLine->GetStart() + nTDiff;
212 pLine->GetEnd() = pLine->GetEnd() + nTDiff;
214 pLine->SetValid();
220 TEParaPortions::TEParaPortions()
224 TEParaPortions::~TEParaPortions()
226 Reset();
229 void TEParaPortions::Reset()
231 TEParaPortions::iterator aIter( begin() );
232 while ( aIter != end() )
233 delete *aIter++;
234 clear();
237 IdleFormatter::IdleFormatter()
239 mpView = 0;
240 mnRestarts = 0;
243 IdleFormatter::~IdleFormatter()
245 mpView = 0;
248 void IdleFormatter::DoIdleFormat( TextView* pV, sal_uInt16 nMaxRestarts )
250 mpView = pV;
252 if ( IsActive() )
253 mnRestarts++;
255 if ( mnRestarts > nMaxRestarts )
257 mnRestarts = 0;
258 ((Link&)GetTimeoutHdl()).Call( this );
260 else
262 Start();
266 void IdleFormatter::ForceTimeout()
268 if ( IsActive() )
270 Stop();
271 mnRestarts = 0;
272 ((Link&)GetTimeoutHdl()).Call( this );
276 TYPEINIT1( TextHint, SfxSimpleHint );
278 TextHint::TextHint( sal_uLong Id ) : SfxSimpleHint( Id )
280 mnValue = 0;
283 TextHint::TextHint( sal_uLong Id, sal_uLong nValue ) : SfxSimpleHint( Id )
285 mnValue = nValue;
288 TEIMEInfos::TEIMEInfos( const TextPaM& rPos, const String& rOldTextAfterStartPos )
289 : aOldTextAfterStartPos( rOldTextAfterStartPos )
291 aPos = rPos;
292 nLen = 0;
293 bCursor = sal_True;
294 pAttribs = NULL;
295 bWasCursorOverwrite = sal_False;
298 TEIMEInfos::~TEIMEInfos()
300 delete[] pAttribs;
303 void TEIMEInfos::CopyAttribs( const sal_uInt16* pA, sal_uInt16 nL )
305 nLen = nL;
306 delete[] pAttribs;
307 pAttribs = new sal_uInt16[ nL ];
308 memcpy( pAttribs, pA, nL*sizeof(sal_uInt16) );
311 void TEIMEInfos::DestroyAttribs()
313 delete[] pAttribs;
314 pAttribs = NULL;
315 nLen = 0;
319 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */