LibreOffice Module vcl (master) 1
textdoc.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <memory>
21#include "textdoc.hxx"
22#include <osl/diagnose.h>
23#include <sal/log.hxx>
24#include <rtl/ustrbuf.hxx>
25#include <utility>
26
27// compare function called by QuickSort
28static bool CompareStart( const std::unique_ptr<TextCharAttrib>& pFirst, const std::unique_ptr<TextCharAttrib>& pSecond )
29{
30 return pFirst->GetStart() < pSecond->GetStart();
31}
32
33TextCharAttrib::TextCharAttrib( const TextAttrib& rAttr, sal_Int32 nStart, sal_Int32 nEnd )
34 : mpAttr(rAttr.Clone())
35 , mnStart(nStart)
36 , mnEnd(nEnd)
37{
38}
39
41 : mpAttr(rTextCharAttrib.mpAttr->Clone())
42 , mnStart(rTextCharAttrib.mnStart)
43 , mnEnd(rTextCharAttrib.mnEnd)
44{
45}
46
48 : mbHasEmptyAttribs(false)
49{
50}
51
53{
54 // PTRARR_DEL
55}
56
58{
59 maAttribs.clear();
60}
61
62void TextCharAttribList::InsertAttrib( std::unique_ptr<TextCharAttrib> pAttrib )
63{
64 if ( pAttrib->IsEmpty() )
65 mbHasEmptyAttribs = true;
66
67 const sal_Int32 nStart = pAttrib->GetStart(); // maybe better for Comp.Opt.
68 bool bInserted = false;
69 auto it = std::find_if(maAttribs.begin(), maAttribs.end(),
70 [nStart](std::unique_ptr<TextCharAttrib>& rAttrib) { return rAttrib->GetStart() > nStart; });
71 if (it != maAttribs.end())
72 {
73 maAttribs.insert( it, std::move(pAttrib) );
74 bInserted = true;
75 }
76 if ( !bInserted )
77 maAttribs.push_back( std::move(pAttrib) );
78}
79
81{
82 std::sort( maAttribs.begin(), maAttribs.end(), CompareStart );
83}
84
85TextCharAttrib* TextCharAttribList::FindAttrib( sal_uInt16 nWhich, sal_Int32 nPos )
86{
87 for (std::vector<std::unique_ptr<TextCharAttrib> >::reverse_iterator it = maAttribs.rbegin(); it != maAttribs.rend(); ++it)
88 {
89 if ( (*it)->GetEnd() < nPos )
90 return nullptr;
91
92 if ( ( (*it)->Which() == nWhich ) && (*it)->IsIn(nPos) )
93 return it->get();
94 }
95 return nullptr;
96}
97
99{
100 for (std::vector<std::unique_ptr<TextCharAttrib> >::reverse_iterator it = maAttribs.rbegin(); it != maAttribs.rend(); ++it)
101 {
102 if ( (*it)->GetEnd() < nBound )
103 return false;
104
105 if ( ( (*it)->GetStart() == nBound ) || ( (*it)->GetEnd() == nBound ) )
106 return true;
107 }
108 return false;
109}
110
111TextCharAttrib* TextCharAttribList::FindEmptyAttrib( sal_uInt16 nWhich, sal_Int32 nPos )
112{
113 if ( !mbHasEmptyAttribs )
114 return nullptr;
115
116 for (auto const& attrib : maAttribs)
117 {
118 if ( attrib->GetStart() > nPos )
119 return nullptr;
120
121 if ( ( attrib->GetStart() == nPos ) && ( attrib->GetEnd() == nPos ) && ( attrib->Which() == nWhich ) )
122 return attrib.get();
123 }
124 return nullptr;
125}
126
128{
129 maAttribs.erase(
130 std::remove_if( maAttribs.begin(), maAttribs.end(),
131 [] (const std::unique_ptr<TextCharAttrib>& rAttrib) { return rAttrib->IsEmpty(); } ),
132 maAttribs.end() );
133 mbHasEmptyAttribs = false;
134}
135
136TextNode::TextNode( OUString aText ) :
137 maText(std::move( aText ))
138{
139}
140
141void TextNode::ExpandAttribs( sal_Int32 nIndex, sal_Int32 nNew )
142{
143 if ( !nNew )
144 return;
145
146 bool bResort = false;
147 sal_uInt16 nAttribs = maCharAttribs.Count();
148 for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
149 {
150 TextCharAttrib& rAttrib = maCharAttribs.GetAttrib( nAttr );
151 if ( rAttrib.GetEnd() >= nIndex )
152 {
153 // move all attributes that are behind the cursor
154 if ( rAttrib.GetStart() > nIndex )
155 {
156 rAttrib.MoveForward( nNew );
157 }
158 // 0: expand empty attribute, if at cursor
159 else if ( rAttrib.IsEmpty() )
160 {
161 // Do not check the index; empty one may only be here.
162 // If checking later anyway, special case:
163 // Start == 0; AbsLen == 1, nNew = 1 => Expand due to new paragraph!
164 // Start <= nIndex, End >= nIndex => Start=End=nIndex!
165 rAttrib.Expand( nNew );
166 }
167 // 1: attribute starts before and reaches up to index
168 else if ( rAttrib.GetEnd() == nIndex ) // start must be before
169 {
170 // Only expand if no feature and not in Exclude list!
171 // Otherwise e.g. an UL would go until the new ULDB, thus expand both.
172 if ( !maCharAttribs.FindEmptyAttrib( rAttrib.Which(), nIndex ) )
173 {
174 rAttrib.Expand( nNew );
175 }
176 else
177 bResort = true;
178 }
179 // 2: attribute starts before and reaches past the index
180 else if ( ( rAttrib.GetStart() < nIndex ) && ( rAttrib.GetEnd() > nIndex ) )
181 {
182 rAttrib.Expand( nNew );
183 }
184 // 3: attribute starts at Index
185 else if ( rAttrib.GetStart() == nIndex )
186 {
187 if ( nIndex == 0 )
188 {
189 rAttrib.Expand( nNew );
190 }
191 else
192 rAttrib.MoveForward( nNew );
193 }
194 }
195
196 SAL_WARN_IF( rAttrib.GetStart() > rAttrib.GetEnd(), "vcl", "Expand: attribute twisted!" );
197 SAL_WARN_IF( ( rAttrib.GetEnd() > maText.getLength() ), "vcl", "Expand: attribute greater than paragraph!" );
198 SAL_WARN_IF( rAttrib.IsEmpty(), "vcl", "Empty attribute after ExpandAttribs?" );
199 }
200
201 if ( bResort )
203}
204
205void TextNode::CollapseAttribs( sal_Int32 nIndex, sal_Int32 nDeleted )
206{
207 if ( !nDeleted )
208 return;
209
210 bool bResort = false;
211 const sal_Int32 nEndChanges = nIndex+nDeleted;
212
213 for ( sal_uInt16 nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
214 {
215 TextCharAttrib& rAttrib = maCharAttribs.GetAttrib( nAttr );
216 bool bDelAttr = false;
217 if ( rAttrib.GetEnd() >= nIndex )
218 {
219 // move all attributes that are behind the cursor
220 if ( rAttrib.GetStart() >= nEndChanges )
221 {
222 rAttrib.MoveBackward( nDeleted );
223 }
224 // 1. delete inner attributes
225 else if ( ( rAttrib.GetStart() >= nIndex ) && ( rAttrib.GetEnd() <= nEndChanges ) )
226 {
227 // special case: attribute covers the region exactly
228 // => keep as an empty attribute
229 if ( ( rAttrib.GetStart() == nIndex ) && ( rAttrib.GetEnd() == nEndChanges ) )
230 rAttrib.SetEnd(nIndex); // empty
231 else
232 bDelAttr = true;
233 }
234 // 2. attribute starts before, ends inside or after
235 else if ( ( rAttrib.GetStart() <= nIndex ) && ( rAttrib.GetEnd() > nIndex ) )
236 {
237 if ( rAttrib.GetEnd() <= nEndChanges ) // ends inside
238 rAttrib.SetEnd(nIndex);
239 else
240 rAttrib.Collaps( nDeleted ); // ends after
241 }
242 // 3. attribute starts inside, ends after
243 else if ( ( rAttrib.GetStart() >= nIndex ) && ( rAttrib.GetEnd() > nEndChanges ) )
244 {
245 // features are not allowed to expand!
246 rAttrib.SetStart(nEndChanges);
247 rAttrib.MoveBackward( nDeleted );
248 }
249 }
250
251 SAL_WARN_IF( rAttrib.GetStart() > rAttrib.GetEnd(), "vcl", "Collaps: attribute twisted!" );
252 SAL_WARN_IF( ( rAttrib.GetEnd() > maText.getLength()) && !bDelAttr, "vcl", "Collaps: attribute greater than paragraph!" );
253 if ( bDelAttr /* || rAttrib.IsEmpty() */ )
254 {
255 bResort = true;
257 nAttr--;
258 }
259 else if ( rAttrib.IsEmpty() )
261 }
262
263 if ( bResort )
265}
266
267void TextNode::InsertText( sal_Int32 nPos, std::u16string_view rText )
268{
269 maText = maText.replaceAt( nPos, 0, rText );
270 ExpandAttribs( nPos, rText.size() );
271}
272
273void TextNode::InsertText( sal_Int32 nPos, sal_Unicode c )
274{
275 maText = maText.replaceAt( nPos, 0, rtl::OUStringChar(c) );
276 ExpandAttribs( nPos, 1 );
277}
278
279void TextNode::RemoveText( sal_Int32 nPos, sal_Int32 nChars )
280{
281 maText = maText.replaceAt( nPos, nChars, u"" );
282 CollapseAttribs( nPos, nChars );
283}
284
285std::unique_ptr<TextNode> TextNode::Split( sal_Int32 nPos )
286{
287 OUString aNewText;
288 if ( nPos < maText.getLength() )
289 {
290 aNewText = maText.copy( nPos );
291 maText = maText.copy(0, nPos);
292 }
293 std::unique_ptr<TextNode> pNew(new TextNode( aNewText ));
294
295 for ( sal_uInt16 nAttr = 0; nAttr < maCharAttribs.Count(); nAttr++ )
296 {
297 TextCharAttrib& rAttrib = maCharAttribs.GetAttrib( nAttr );
298 if ( rAttrib.GetEnd() < nPos )
299 {
300 // no change
301 ;
302 }
303 else if ( rAttrib.GetEnd() == nPos )
304 {
305 // must be copied as an empty attribute
306 // !FindAttrib only sensible if traversing backwards through the list!
307 if ( !pNew->maCharAttribs.FindAttrib( rAttrib.Which(), 0 ) )
308 {
309 std::unique_ptr<TextCharAttrib> pNewAttrib(new TextCharAttrib( rAttrib ));
310 pNewAttrib->SetStart(0);
311 pNewAttrib->SetEnd(0);
312 pNew->maCharAttribs.InsertAttrib( std::move(pNewAttrib) );
313 }
314 }
315 else if ( rAttrib.IsInside( nPos ) || ( !nPos && !rAttrib.GetStart() ) )
316 {
317 // If cutting at the very beginning, the attribute has to be
318 // copied and changed
319 std::unique_ptr<TextCharAttrib> pNewAttrib(new TextCharAttrib( rAttrib ));
320 pNewAttrib->SetStart(0);
321 pNewAttrib->SetEnd(rAttrib.GetEnd()-nPos);
322 pNew->maCharAttribs.InsertAttrib( std::move(pNewAttrib) );
323 // trim
324 rAttrib.SetEnd(nPos);
325 }
326 else
327 {
328 SAL_WARN_IF( rAttrib.GetStart() < nPos, "vcl", "Start < nPos!" );
329 SAL_WARN_IF( rAttrib.GetEnd() < nPos, "vcl", "End < nPos!" );
330 // move all into the new node (this)
331 pNew->maCharAttribs.InsertAttrib(maCharAttribs.RemoveAttrib(nAttr));
332 rAttrib.SetStart( rAttrib.GetStart() - nPos );
333 rAttrib.SetEnd( rAttrib.GetEnd() - nPos );
334 nAttr--;
335 }
336 }
337 return pNew;
338}
339
340void TextNode::Append( const TextNode& rNode )
341{
342 sal_Int32 nOldLen = maText.getLength();
343
344 maText += rNode.GetText();
345
346 const sal_uInt16 nAttribs = rNode.GetCharAttribs().Count();
347 for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
348 {
349 const TextCharAttrib& rAttrib = rNode.GetCharAttrib( nAttr );
350 bool bMelted = false;
351 if ( rAttrib.GetStart() == 0 )
352 {
353 // potentially merge attributes
354 sal_uInt16 nTmpAttribs = maCharAttribs.Count();
355 for ( sal_uInt16 nTmpAttr = 0; nTmpAttr < nTmpAttribs; nTmpAttr++ )
356 {
357 TextCharAttrib& rTmpAttrib = maCharAttribs.GetAttrib( nTmpAttr );
358
359 if ( rTmpAttrib.GetEnd() == nOldLen )
360 {
361 if ( ( rTmpAttrib.Which() == rAttrib.Which() ) &&
362 ( rTmpAttrib.GetAttr() == rAttrib.GetAttr() ) )
363 {
364 rTmpAttrib.SetEnd( rTmpAttrib.GetEnd() + rAttrib.GetLen() );
365 bMelted = true;
366 break; // there can be only one of this type at this position
367 }
368 }
369 }
370 }
371
372 if ( !bMelted )
373 {
374 std::unique_ptr<TextCharAttrib> pNewAttrib(new TextCharAttrib( rAttrib ));
375 pNewAttrib->SetStart( pNewAttrib->GetStart() + nOldLen );
376 pNewAttrib->SetEnd( pNewAttrib->GetEnd() + nOldLen );
377 maCharAttribs.InsertAttrib( std::move(pNewAttrib) );
378 }
379 }
380}
381
383 : mnLeftMargin(0)
384{
385};
386
388{
390}
391
393{
395}
396
398{
399 maTextNodes.clear();
400}
401
402OUString TextDoc::GetText( const sal_Unicode* pSep ) const
403{
404 sal_uInt32 nNodes = static_cast<sal_uInt32>(maTextNodes.size());
405
406 OUStringBuffer aASCIIText;
407 const sal_uInt32 nLastNode = nNodes-1;
408 for ( sal_uInt32 nNode = 0; nNode < nNodes; ++nNode )
409 {
410 TextNode* pNode = maTextNodes[ nNode ].get();
411 aASCIIText.append(pNode->GetText());
412 if ( pSep && ( nNode != nLastNode ) )
413 aASCIIText.append(pSep);
414 }
415
416 return aASCIIText.makeStringAndClear();
417}
418
419OUString TextDoc::GetText( sal_uInt32 nPara ) const
420{
421 TextNode* pNode = ( nPara < maTextNodes.size() ) ? maTextNodes[ nPara ].get() : nullptr;
422 if ( pNode )
423 return pNode->GetText();
424
425 return OUString();
426}
427
428sal_Int32 TextDoc::GetTextLen( const sal_Unicode* pSep, const TextSelection* pSel ) const
429{
430 sal_Int32 nLen = 0;
431 sal_uInt32 nNodes = static_cast<sal_uInt32>(maTextNodes.size());
432 if ( nNodes )
433 {
434 sal_uInt32 nStartNode = 0;
435 sal_uInt32 nEndNode = nNodes-1;
436 if ( pSel )
437 {
438 nStartNode = pSel->GetStart().GetPara();
439 nEndNode = pSel->GetEnd().GetPara();
440 }
441
442 for ( sal_uInt32 nNode = nStartNode; nNode <= nEndNode; ++nNode )
443 {
444 TextNode* pNode = maTextNodes[ nNode ].get();
445
446 sal_Int32 nS = 0;
447 sal_Int32 nE = pNode->GetText().getLength();
448 if ( pSel && ( nNode == pSel->GetStart().GetPara() ) )
449 nS = pSel->GetStart().GetIndex();
450 if ( pSel && ( nNode == pSel->GetEnd().GetPara() ) )
451 nE = pSel->GetEnd().GetIndex();
452
453 nLen += ( nE - nS );
454 }
455
456 if ( pSep )
457 nLen += (nEndNode-nStartNode) * rtl_ustr_getLength(pSep);
458 }
459
460 return nLen;
461}
462
464{
465 SAL_WARN_IF( c == 0x0A, "vcl", "TextDoc::InsertText: Line separator in paragraph not allowed!" );
466 SAL_WARN_IF( c == 0x0D, "vcl", "TextDoc::InsertText: Line separator in paragraph not allowed!" );
467
468 TextNode* pNode = maTextNodes[ rPaM.GetPara() ].get();
469 pNode->InsertText( rPaM.GetIndex(), c );
470
471 TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+1 );
472 return aPaM;
473}
474
475TextPaM TextDoc::InsertText( const TextPaM& rPaM, std::u16string_view rStr )
476{
477 SAL_WARN_IF( rStr.find( 0x0A ) != std::u16string_view::npos, "vcl", "TextDoc::InsertText: Line separator in paragraph not allowed!" );
478 SAL_WARN_IF( rStr.find( 0x0D ) != std::u16string_view::npos, "vcl", "TextDoc::InsertText: Line separator in paragraph not allowed!" );
479
480 TextNode* pNode = maTextNodes[ rPaM.GetPara() ].get();
481 pNode->InsertText( rPaM.GetIndex(), rStr );
482
483 TextPaM aPaM( rPaM.GetPara(), rPaM.GetIndex()+rStr.size() );
484 return aPaM;
485}
486
488{
489 TextNode* pNode = maTextNodes[ rPaM.GetPara() ].get();
490 std::unique_ptr<TextNode> pNew = pNode->Split( rPaM.GetIndex() );
491
492 SAL_WARN_IF( maTextNodes.size()>=SAL_MAX_UINT32, "vcl", "InsertParaBreak: more than 4Gi paragraphs!" );
493 maTextNodes.insert( maTextNodes.begin() + rPaM.GetPara() + 1, std::move(pNew) );
494
495 TextPaM aPaM( rPaM.GetPara()+1, 0 );
496 return aPaM;
497}
498
500{
501 sal_Int32 nPrevLen = pLeft->GetText().getLength();
502 pLeft->Append( *pRight );
503
504 // the paragraph on the right vanishes
505 maTextNodes.erase( std::find_if( maTextNodes.begin(), maTextNodes.end(),
506 [&] (std::unique_ptr<TextNode> const & p) { return p.get() == pRight; } ) );
507
508 sal_Int32 nLeft = ::std::find_if( maTextNodes.begin(), maTextNodes.end(),
509 [&] (std::unique_ptr<TextNode> const & p) { return p.get() == pLeft; } )
510 - maTextNodes.begin();
511 TextPaM aPaM( nLeft, nPrevLen );
512 return aPaM;
513}
514
515void TextDoc::RemoveChars( const TextPaM& rPaM, sal_Int32 nChars )
516{
517 TextNode* pNode = maTextNodes[ rPaM.GetPara() ].get();
518 pNode->RemoveText( rPaM.GetIndex(), nChars );
519}
520
521bool TextDoc::IsValidPaM( const TextPaM& rPaM )
522{
523 if ( rPaM.GetPara() >= maTextNodes.size() )
524 {
525 OSL_FAIL( "PaM: Para out of range" );
526 return false;
527 }
528 TextNode * pNode = maTextNodes[ rPaM.GetPara() ].get();
529 if ( rPaM.GetIndex() > pNode->GetText().getLength() )
530 {
531 OSL_FAIL( "PaM: Index out of range" );
532 return false;
533 }
534 return true;
535}
536
537/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Text maText
size_t mnEnd
TextCharAttrib * FindAttrib(sal_uInt16 nWhich, sal_Int32 nPos)
Definition: textdoc.cxx:85
std::vector< std::unique_ptr< TextCharAttrib > > maAttribs
Definition: textdoc.hxx:34
void InsertAttrib(std::unique_ptr< TextCharAttrib > pAttrib)
Definition: textdoc.cxx:62
bool HasBoundingAttrib(sal_Int32 nBound)
Definition: textdoc.cxx:98
const TextCharAttrib & GetAttrib(sal_uInt16 n) const
Definition: textdoc.hxx:44
void ResortAttribs()
Definition: textdoc.cxx:80
bool & HasEmptyAttribs()
Definition: textdoc.hxx:58
TextCharAttrib * FindEmptyAttrib(sal_uInt16 nWhich, sal_Int32 nPos)
Definition: textdoc.cxx:111
std::unique_ptr< TextCharAttrib > RemoveAttrib(sal_uInt16 n)
Definition: textdoc.hxx:46
void DeleteEmptyAttribs()
Definition: textdoc.cxx:127
bool mbHasEmptyAttribs
Definition: textdoc.hxx:35
sal_uInt16 Count() const
Definition: textdoc.hxx:42
bool IsEmpty() const
Definition: txtattr.hxx:182
void Expand(sal_Int32 nDiff)
Definition: txtattr.hxx:160
void MoveBackward(sal_Int32 nDiff)
Definition: txtattr.hxx:153
void Collaps(sal_Int32 nDiff)
Definition: txtattr.hxx:166
void SetStart(sal_Int32 n)
Definition: txtattr.hxx:121
const TextAttrib & GetAttr() const
Definition: txtattr.hxx:116
TextCharAttrib(const TextAttrib &rAttr, sal_Int32 nStart, sal_Int32 nEnd)
Definition: textdoc.cxx:33
sal_uInt16 Which() const
Definition: txtattr.hxx:118
sal_Int32 GetLen() const
Definition: txtattr.hxx:140
void MoveForward(sal_Int32 nDiff)
Definition: txtattr.hxx:146
sal_Int32 GetStart() const
Definition: txtattr.hxx:120
bool IsInside(sal_Int32 nIndex) const
Definition: txtattr.hxx:177
sal_Int32 GetEnd() const
Definition: txtattr.hxx:123
void SetEnd(sal_Int32 n)
Definition: txtattr.hxx:124
TextPaM InsertText(const TextPaM &rPaM, sal_Unicode c)
Definition: textdoc.cxx:463
OUString GetText(const sal_Unicode *pSep) const
Definition: textdoc.cxx:402
bool IsValidPaM(const TextPaM &rPaM)
Definition: textdoc.cxx:521
void Clear()
Definition: textdoc.cxx:392
TextPaM ConnectParagraphs(TextNode *pLeft, const TextNode *pRight)
Definition: textdoc.cxx:499
void RemoveChars(const TextPaM &rPaM, sal_Int32 nChars)
Definition: textdoc.cxx:515
std::vector< std::unique_ptr< TextNode > > maTextNodes
Definition: textdoc.hxx:95
~TextDoc()
Definition: textdoc.cxx:387
void DestroyTextNodes()
Definition: textdoc.cxx:397
TextPaM InsertParaBreak(const TextPaM &rPaM)
Definition: textdoc.cxx:487
TextDoc()
Definition: textdoc.cxx:382
sal_Int32 GetTextLen(const sal_Unicode *pSep, const TextSelection *pSel=nullptr) const
Definition: textdoc.cxx:428
void CollapseAttribs(sal_Int32 nIndex, sal_Int32 nDelChars)
Definition: textdoc.cxx:205
void ExpandAttribs(sal_Int32 nIndex, sal_Int32 nNewChars)
Definition: textdoc.cxx:141
const TextCharAttribList & GetCharAttribs() const
Definition: textdoc.hxx:82
void Append(const TextNode &rNode)
Definition: textdoc.cxx:340
std::unique_ptr< TextNode > Split(sal_Int32 nPos)
Definition: textdoc.cxx:285
void RemoveText(sal_Int32 nPos, sal_Int32 nChars)
Definition: textdoc.cxx:279
TextCharAttribList maCharAttribs
Definition: textdoc.hxx:68
OUString maText
Definition: textdoc.hxx:67
const TextCharAttrib & GetCharAttrib(sal_uInt16 nPos) const
Definition: textdoc.hxx:81
void InsertText(sal_Int32 nPos, std::u16string_view rText)
Definition: textdoc.cxx:267
const OUString & GetText() const
Definition: textdoc.hxx:79
TextNode(OUString aText)
Definition: textdoc.cxx:136
sal_uInt32 GetPara() const
Definition: textdata.hxx:45
sal_Int32 GetIndex() const
Definition: textdata.hxx:48
const TextPaM & GetStart() const
Definition: textdata.hxx:90
const TextPaM & GetEnd() const
Definition: textdata.hxx:93
float u
sal_Int32 nIndex
void * p
sal_uInt16 nPos
#define SAL_WARN_IF(condition, area, stream)
css::uno::Reference< css::animations::XAnimationNode > Clone(const css::uno::Reference< css::animations::XAnimationNode > &xSourceNode, const SdPage *pSource=nullptr, const SdPage *pTarget=nullptr)
css::uno::Reference< css::linguistic2::XProofreadingIterator > get(css::uno::Reference< css::uno::XComponentContext > const &context)
static bool CompareStart(const std::unique_ptr< TextCharAttrib > &pFirst, const std::unique_ptr< TextCharAttrib > &pSecond)
Definition: textdoc.cxx:28
sal_uInt16 sal_Unicode
#define SAL_MAX_UINT32
sal_Int32 mnStart