1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
20 #include <sal/config.h>
21 #include <sal/log.hxx>
22 #include <osl/diagnose.h>
26 #include <vcl/textdata.hxx>
27 #include "textdat2.hxx"
30 TextSelection::TextSelection()
34 TextSelection::TextSelection( const TextPaM
& rPaM
) :
35 maStartPaM( rPaM
), maEndPaM( rPaM
)
39 TextSelection::TextSelection( const TextPaM
& rStart
, const TextPaM
& rEnd
) :
40 maStartPaM( rStart
), maEndPaM( rEnd
)
44 void TextSelection::Justify()
46 if ( maEndPaM
< maStartPaM
)
48 TextPaM
aTemp( maStartPaM
);
49 maStartPaM
= maEndPaM
;
54 TETextPortionList::TETextPortionList()
58 TETextPortionList::~TETextPortionList()
63 TETextPortion
* TETextPortionList::operator[]( std::size_t nPos
)
65 return maPortions
[ nPos
].get();
68 std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
TETextPortionList::begin()
70 return maPortions
.begin();
73 std::vector
<std::unique_ptr
<TETextPortion
>>::const_iterator
TETextPortionList::begin() const
75 return maPortions
.begin();
78 std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
TETextPortionList::end()
80 return maPortions
.end();
83 std::vector
<std::unique_ptr
<TETextPortion
>>::const_iterator
TETextPortionList::end() const
85 return maPortions
.end();
88 bool TETextPortionList::empty() const
90 return maPortions
.empty();
93 std::size_t TETextPortionList::size() const
95 return maPortions
.size();
98 std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
TETextPortionList::erase( const std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
& aIter
)
100 return maPortions
.erase( aIter
);
103 std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
TETextPortionList::insert( const std::vector
<std::unique_ptr
<TETextPortion
>>::iterator
& aIter
,
104 std::unique_ptr
<TETextPortion
> pTP
)
106 return maPortions
.insert( aIter
, std::move(pTP
) );
109 void TETextPortionList::push_back( std::unique_ptr
<TETextPortion
> pTP
)
111 maPortions
.push_back( std::move(pTP
) );
114 void TETextPortionList::Reset()
119 void TETextPortionList::DeleteFromPortion( std::size_t nDelFrom
)
121 SAL_WARN_IF( ( nDelFrom
>= maPortions
.size() ) && ( (nDelFrom
!= 0) || (!maPortions
.empty()) ), "vcl", "DeleteFromPortion: Out of range" );
122 maPortions
.erase( maPortions
.begin() + nDelFrom
, maPortions
.end() );
125 std::size_t TETextPortionList::FindPortion( sal_Int32 nCharPos
, sal_Int32
& nPortionStart
, bool bPreferStartingPortion
)
127 // find left portion at nCharPos at portion border
128 sal_Int32 nTmpPos
= 0;
129 for ( std::size_t nPortion
= 0; nPortion
< maPortions
.size(); nPortion
++ )
131 TETextPortion
* pPortion
= maPortions
[ nPortion
].get();
132 nTmpPos
+= pPortion
->GetLen();
133 if ( nTmpPos
>= nCharPos
)
135 // take this one if we don't prefer the starting portion, or if it's the last one
136 if ( ( nTmpPos
!= nCharPos
) || !bPreferStartingPortion
|| ( nPortion
== maPortions
.size() - 1 ) )
138 nPortionStart
= nTmpPos
- pPortion
->GetLen();
143 OSL_FAIL( "FindPortion: Not found!" );
144 return ( maPortions
.size() - 1 );
147 TEParaPortion::TEParaPortion( TextNode
* pN
)
149 , mnInvalidPosStart
{0}
156 TEParaPortion::~TEParaPortion()
160 void TEParaPortion::MarkInvalid( sal_Int32 nStart
, sal_Int32 nDiff
)
164 mnInvalidPosStart
= ( nDiff
>= 0 ) ? nStart
: ( nStart
+ nDiff
);
165 mnInvalidDiff
= nDiff
;
169 // simple consecutive typing
170 if ( ( nDiff
> 0 ) && ( mnInvalidDiff
> 0 ) &&
171 ( ( mnInvalidPosStart
+mnInvalidDiff
) == nStart
) )
173 mnInvalidDiff
= mnInvalidDiff
+ nDiff
;
175 // simple consecutive deleting
176 else if ( ( nDiff
< 0 ) && ( mnInvalidDiff
< 0 ) && ( mnInvalidPosStart
== nStart
) )
178 mnInvalidPosStart
= mnInvalidPosStart
+ nDiff
;
179 mnInvalidDiff
= mnInvalidDiff
+ nDiff
;
183 SAL_WARN_IF( ( nDiff
< 0 ) && ( (nStart
+nDiff
) < 0 ), "vcl", "MarkInvalid: Diff out of Range" );
184 mnInvalidPosStart
= std::min( mnInvalidPosStart
, nDiff
< 0 ? nStart
+nDiff
: nDiff
);
190 maWritingDirectionInfos
.clear();
195 void TEParaPortion::MarkSelectionInvalid( sal_Int32 nStart
)
199 mnInvalidPosStart
= nStart
;
203 mnInvalidPosStart
= std::min( mnInvalidPosStart
, nStart
);
206 maWritingDirectionInfos
.clear();
213 std::vector
<TextLine
>::size_type
TEParaPortion::GetLineNumber( sal_Int32 nChar
, bool bInclEnd
)
215 for ( std::vector
<TextLine
>::size_type nLine
= 0; nLine
< maLines
.size(); nLine
++ )
217 TextLine
& rLine
= maLines
[ nLine
];
218 if ( ( bInclEnd
&& ( rLine
.GetEnd() >= nChar
) ) ||
219 ( rLine
.GetEnd() > nChar
) )
225 // Then it should be at the end of the last line
226 OSL_ENSURE(nChar
== maLines
.back().GetEnd(), "wrong Index");
227 OSL_ENSURE(!bInclEnd
, "Line not found: FindLine");
228 return ( maLines
.size() - 1 );
231 void TEParaPortion::CorrectValuesBehindLastFormattedLine( sal_uInt16 nLastFormattedLine
)
233 sal_uInt16 nLines
= maLines
.size();
234 SAL_WARN_IF( !nLines
, "vcl", "CorrectPortionNumbersFromLine: Empty portion?" );
235 if ( nLastFormattedLine
< ( nLines
- 1 ) )
237 const TextLine
& rLastFormatted
= maLines
[ nLastFormattedLine
];
238 const TextLine
& rUnformatted
= maLines
[ nLastFormattedLine
+1 ];
239 std::ptrdiff_t nPortionDiff
= rUnformatted
.GetStartPortion() - rLastFormatted
.GetEndPortion();
240 sal_Int32 nTextDiff
= rUnformatted
.GetStart() - rLastFormatted
.GetEnd();
241 nTextDiff
++; // LastFormatted.GetEnd() was inclusive => subtracted one too much!
243 // The first unformatted one has to start exactly one portion past the last
245 // If a portion got split in the changed row, nLastEnd could be > nNextStart!
246 std::ptrdiff_t nPDiff
= -( nPortionDiff
-1 );
247 const sal_Int32 nTDiff
= -( nTextDiff
-1 );
248 if ( nPDiff
|| nTDiff
)
250 for ( sal_uInt16 nL
= nLastFormattedLine
+1; nL
< nLines
; nL
++ )
252 TextLine
& rLine
= maLines
[ nL
];
254 rLine
.SetStartPortion(rLine
.GetStartPortion() + nPDiff
);
255 rLine
.SetEndPortion(rLine
.GetEndPortion() + nPDiff
);
257 rLine
.SetStart(rLine
.GetStart() + nTDiff
);
258 rLine
.SetEnd(rLine
.GetEnd() + nTDiff
);
266 TEParaPortions::~TEParaPortions()
270 IdleFormatter::IdleFormatter()
274 SetPriority(TaskPriority::HIGH_IDLE
);
277 IdleFormatter::~IdleFormatter()
282 void IdleFormatter::DoIdleFormat( TextView
* pV
, sal_uInt16 nMaxRestarts
)
289 if ( mnRestarts
> nMaxRestarts
)
300 void IdleFormatter::ForceTimeout()
310 TextHint::TextHint( SfxHintId Id
) : SfxHint( Id
), mnValue(0)
314 TextHint::TextHint( SfxHintId Id
, sal_uLong nValue
) : SfxHint( Id
), mnValue(nValue
)
318 TEIMEInfos::TEIMEInfos( const TextPaM
& rPos
, const OUString
& rOldTextAfterStartPos
)
319 : aOldTextAfterStartPos(rOldTextAfterStartPos
)
322 , bWasCursorOverwrite(false)
326 TEIMEInfos::~TEIMEInfos()
330 void TEIMEInfos::CopyAttribs(const ExtTextInputAttr
* pA
, sal_Int32 nL
)
333 pAttribs
.reset( new ExtTextInputAttr
[ nL
] );
334 memcpy( pAttribs
.get(), pA
, nL
*sizeof(ExtTextInputAttr
) );
337 void TEIMEInfos::DestroyAttribs()
343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */