LibreOffice Module editeng (master) 1
outliner.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 <comphelper/string.hxx>
21#include <svl/eitem.hxx>
22#include <svl/intitem.hxx>
23#include <editeng/editeng.hxx>
24#include <editeng/editview.hxx>
25#include <editeng/editdata.hxx>
26#include <editeng/lrspitem.hxx>
27
28#include <math.h>
29#include <svl/style.hxx>
30#include <editeng/outliner.hxx>
31#include "paralist.hxx"
32#include <editeng/outlobj.hxx>
33#include <outleeng.hxx>
34#include "outlundo.hxx"
35#include <editeng/eeitem.hxx>
36#include <editeng/editstat.hxx>
38#include <editeng/editobj.hxx>
39#include <svl/itemset.hxx>
40#include <vcl/metric.hxx>
41#include <editeng/numitem.hxx>
43#include <vcl/GraphicObject.hxx>
44#include <editeng/svxfont.hxx>
45#include <editeng/brushitem.hxx>
46#include <svl/itempool.hxx>
47#include <libxml/xmlwriter.h>
48#include <sal/log.hxx>
49#include <o3tl/safeint.hxx>
50#include <o3tl/string_view.hxx>
51#include <o3tl/temporary.hxx>
52#include <osl/diagnose.h>
53
54#include <memory>
55using std::advance;
56
57
58// Outliner
59
60
61void Outliner::ImplCheckDepth( sal_Int16& rnDepth ) const
62{
63 if( rnDepth < gnMinDepth )
64 rnDepth = gnMinDepth;
65 else if( rnDepth > nMaxDepth )
66 rnDepth = nMaxDepth;
67}
68
69Paragraph* Outliner::Insert(const OUString& rText, sal_Int32 nAbsPos, sal_Int16 nDepth)
70{
71 DBG_ASSERT(pParaList->GetParagraphCount(),"Insert:No Paras");
72
73 Paragraph* pPara;
74
75 ImplCheckDepth( nDepth );
76
77 sal_Int32 nParagraphCount = pParaList->GetParagraphCount();
78 if( nAbsPos > nParagraphCount )
79 nAbsPos = nParagraphCount;
80
82 {
83 pPara = pParaList->GetParagraph( 0 );
84 if( pPara->GetDepth() != nDepth )
85 {
87 ParaFlag nPrevFlags = pPara->nFlags;
88 pPara->SetDepth( nDepth );
89 DepthChangedHdl(pPara, nPrevFlags);
90 }
92 SetText( rText, pPara );
93 }
94 else
95 {
96 bool bUpdate = pEditEngine->SetUpdateLayout( false );
98 pPara = new Paragraph( nDepth );
99 pParaList->Insert( std::unique_ptr<Paragraph>(pPara), nAbsPos );
100 pEditEngine->InsertParagraph( nAbsPos, OUString() );
101 DBG_ASSERT(pPara==pParaList->GetParagraph(nAbsPos),"Insert:Failed");
102 ImplInitDepth( nAbsPos, nDepth, false );
104 pPara->nFlags |= ParaFlag::HOLDDEPTH;
105 SetText( rText, pPara );
107 pEditEngine->SetUpdateLayout( bUpdate );
108 }
109 bFirstParaIsEmpty = false;
110 DBG_ASSERT(pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(),"SetText failed");
111 return pPara;
112}
113
114
115void Outliner::ParagraphInserted( sal_Int32 nPara )
116{
117
118 if ( nBlockInsCallback )
119 return;
120
121 if( bPasting || pEditEngine->IsInUndo() )
122 {
123 Paragraph* pPara = new Paragraph( -1 );
124 pParaList->Insert( std::unique_ptr<Paragraph>(pPara), nPara );
125 if( pEditEngine->IsInUndo() )
126 {
127 pPara->bVisible = true;
128 const SfxInt16Item& rLevel = pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
129 pPara->SetDepth( rLevel.GetValue() );
130 }
131 }
132 else
133 {
134 sal_Int16 nDepth = -1;
135 Paragraph* pParaBefore = pParaList->GetParagraph( nPara-1 );
136 if ( pParaBefore )
137 nDepth = pParaBefore->GetDepth();
138
139 Paragraph* pPara = new Paragraph( nDepth );
140 pParaList->Insert( std::unique_ptr<Paragraph>(pPara), nPara );
141
142 if( !pEditEngine->IsInUndo() )
143 {
144 ImplCalcBulletText( nPara, true, false );
146 }
147 }
148}
149
150void Outliner::ParagraphDeleted( sal_Int32 nPara )
151{
152
153 if ( nBlockInsCallback || ( nPara == EE_PARA_ALL ) )
154 return;
155
156 Paragraph* pPara = pParaList->GetParagraph( nPara );
157 if (!pPara)
158 return;
159
160 sal_Int16 nDepth = pPara->GetDepth();
161
162 if( !pEditEngine->IsInUndo() )
163 {
164 aParaRemovingHdl.Call( { this, pPara } );
165 }
166
167 pParaList->Remove( nPara );
168
169 if( pEditEngine->IsInUndo() || bPasting )
170 return;
171
172 pPara = pParaList->GetParagraph( nPara );
173 if ( pPara && ( pPara->GetDepth() > nDepth ) )
174 {
175 ImplCalcBulletText( nPara, true, false );
176 // Search for next on the this level ...
177 while ( pPara && pPara->GetDepth() > nDepth )
178 pPara = pParaList->GetParagraph( ++nPara );
179 }
180
181 if ( pPara && ( pPara->GetDepth() == nDepth ) )
182 ImplCalcBulletText( nPara, true, false );
183}
184
186{
187 nOutlinerMode = nMode;
188
189 Clear();
190
191 EEControlBits nCtrl = pEditEngine->GetControlWord();
193
194 SetMaxDepth( 9 );
195
196 switch ( GetOutlinerMode() )
197 {
200 break;
201
204 break;
207 break;
208
209 default: OSL_FAIL( "Outliner::Init - Invalid Mode!" );
210 }
211
212 pEditEngine->SetControlWord( nCtrl );
213
214 const bool bWasUndoEnabled(IsUndoEnabled());
215 EnableUndo(false);
216 ImplInitDepth( 0, -1, false );
218 EnableUndo(bWasUndoEnabled);
219}
220
221void Outliner::SetMaxDepth( sal_Int16 nDepth )
222{
223 if( nMaxDepth != nDepth )
224 {
225 nMaxDepth = std::min( nDepth, sal_Int16(SVX_MAX_NUM-1) );
226 }
227}
228
229sal_Int16 Outliner::GetDepth( sal_Int32 nPara ) const
230{
231 Paragraph* pPara = pParaList->GetParagraph( nPara );
232 DBG_ASSERT( pPara, "Outliner::GetDepth - Paragraph not found!" );
233 return pPara ? pPara->GetDepth() : -1;
234}
235
236void Outliner::SetDepth( Paragraph* pPara, sal_Int16 nNewDepth )
237{
238
239 ImplCheckDepth( nNewDepth );
240
241 if ( nNewDepth == pPara->GetDepth() )
242 return;
243
245 ParaFlag nPrevFlags = pPara->nFlags;
246
247 sal_Int32 nPara = GetAbsPos( pPara );
248 ImplInitDepth( nPara, nNewDepth, true );
249 ImplCalcBulletText( nPara, false, false );
250
253
254 DepthChangedHdl(pPara, nPrevFlags);
255}
256
257sal_Int16 Outliner::GetNumberingStartValue( sal_Int32 nPara ) const
258{
259 Paragraph* pPara = pParaList->GetParagraph( nPara );
260 DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
261 return pPara ? pPara->GetNumberingStartValue() : -1;
262}
263
264void Outliner::SetNumberingStartValue( sal_Int32 nPara, sal_Int16 nNumberingStartValue )
265{
266 Paragraph* pPara = pParaList->GetParagraph( nPara );
267 DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
268 if( pPara && pPara->GetNumberingStartValue() != nNumberingStartValue )
269 {
270 if( IsUndoEnabled() && !IsInUndo() )
271 InsertUndo( std::make_unique<OutlinerUndoChangeParaNumberingRestart>( this, nPara,
272 pPara->GetNumberingStartValue(), nNumberingStartValue,
274
275 pPara->SetNumberingStartValue( nNumberingStartValue );
276 ImplCheckParagraphs( nPara, pParaList->GetParagraphCount() );
277 pEditEngine->SetModified();
278 }
279}
280
281bool Outliner::IsParaIsNumberingRestart( sal_Int32 nPara ) const
282{
283 Paragraph* pPara = pParaList->GetParagraph( nPara );
284 DBG_ASSERT( pPara, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
285 return pPara && pPara->IsParaIsNumberingRestart();
286}
287
288void Outliner::SetParaIsNumberingRestart( sal_Int32 nPara, bool bParaIsNumberingRestart )
289{
290 Paragraph* pPara = pParaList->GetParagraph( nPara );
291 DBG_ASSERT( pPara, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
292 if( pPara && (pPara->IsParaIsNumberingRestart() != bParaIsNumberingRestart) )
293 {
294 if( IsUndoEnabled() && !IsInUndo() )
295 InsertUndo( std::make_unique<OutlinerUndoChangeParaNumberingRestart>( this, nPara,
297 pPara->IsParaIsNumberingRestart(), bParaIsNumberingRestart ) );
298
299 pPara->SetParaIsNumberingRestart( bParaIsNumberingRestart );
300 ImplCheckParagraphs( nPara, pParaList->GetParagraphCount() );
301 pEditEngine->SetModified();
302 }
303}
304
306 const sal_Int32 nParaStart,
307 const sal_Int32 nParaEnd ) const
308{
309 if ( nParaStart > nParaEnd
310 || nParaEnd >= pParaList->GetParagraphCount() )
311 {
312 SAL_WARN("editeng", "<Outliner::GetBulletsNumberingStatus> - unexpected parameter values" );
313 return 2;
314 }
315
316 sal_Int32 nBulletsCount = 0;
317 sal_Int32 nNumberingCount = 0;
318 for (sal_Int32 nPara = nParaStart; nPara <= nParaEnd; ++nPara)
319 {
320 if ( !pParaList->GetParagraph(nPara) )
321 {
322 break;
323 }
324 const SvxNumberFormat* pFmt = GetNumberFormat(nPara);
325 if (!pFmt)
326 {
327 // At least, exists one paragraph that has no Bullets/Numbering.
328 break;
329 }
330 else if ((pFmt->GetNumberingType() == SVX_NUM_BITMAP) || (pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL))
331 {
332 // Having Bullets in this paragraph.
333 nBulletsCount++;
334 }
335 else
336 {
337 // Having Numbering in this paragraph.
338 nNumberingCount++;
339 }
340 }
341
342 const sal_Int32 nParaCount = nParaEnd - nParaStart + 1;
343 if ( nBulletsCount == nParaCount )
344 {
345 return 0;
346 }
347 else if ( nNumberingCount == nParaCount )
348 {
349 return 1;
350 }
351 return 2;
352}
353
355{
356 return pParaList->GetParagraphCount() > 0
357 ? GetBulletsNumberingStatus( 0, pParaList->GetParagraphCount()-1 )
358 : 2;
359}
360
361std::optional<OutlinerParaObject> Outliner::CreateParaObject( sal_Int32 nStartPara, sal_Int32 nCount ) const
362{
363 if ( static_cast<sal_uInt64>(nStartPara) + nCount >
364 o3tl::make_unsigned(pParaList->GetParagraphCount()) )
365 nCount = pParaList->GetParagraphCount() - nStartPara;
366
367 // When a new OutlinerParaObject is created because a paragraph is just being deleted,
368 // it can happen that the ParaList is not updated yet...
369 if ( ( nStartPara + nCount ) > pEditEngine->GetParagraphCount() )
370 nCount = pEditEngine->GetParagraphCount() - nStartPara;
371
372 if (nCount <= 0)
373 return std::nullopt;
374
375 std::unique_ptr<EditTextObject> xText = pEditEngine->CreateTextObject( nStartPara, nCount );
376 const bool bIsEditDoc(OutlinerMode::TextObject == GetOutlinerMode());
377 ParagraphDataVector aParagraphDataVector(nCount);
378 const sal_Int32 nLastPara(nStartPara + nCount - 1);
379
380 for(sal_Int32 nPara(nStartPara); nPara <= nLastPara; nPara++)
381 {
382 aParagraphDataVector[nPara-nStartPara] = *GetParagraph(nPara);
383 }
384
385 xText->ClearPortionInfo(); // tdf#147166 the PortionInfo is unwanted here
386 OutlinerParaObject aPObj(std::move(xText), std::move(aParagraphDataVector), bIsEditDoc);
388
389 return aPObj;
390}
391
393{
395}
396
397void Outliner::SetText( const OUString& rText, Paragraph* pPara )
398{
399 DBG_ASSERT(pPara,"SetText:No Para");
400
401 const sal_Int32 nPara = pParaList->GetAbsPos( pPara );
402
403 if (pEditEngine->GetText( nPara ) == rText)
404 {
405 // short-circuit logic to improve performance
406 bFirstParaIsEmpty = false;
407 return;
408 }
409
410 const bool bUpdate = pEditEngine->SetUpdateLayout( false );
412
413 if (rText.isEmpty())
414 {
415 pEditEngine->SetText( nPara, rText );
416 ImplInitDepth( nPara, pPara->GetDepth(), false );
417 }
418 else
419 {
420 const OUString aText(convertLineEnd(rText, LINEEND_LF));
421
422 sal_Int32 nPos = 0;
423 sal_Int32 nInsPos = nPara+1;
424 sal_Int32 nIdx {0};
425 // Loop over all tokens, but ignore the last one if empty
426 // (i.e. if strings ends with the delimiter, detected by
427 // checking nIdx against string length). This check also
428 // handle empty strings.
429 while( nIdx>=0 && nIdx<aText.getLength() )
430 {
431 std::u16string_view aStr = o3tl::getToken(aText, 0, '\x0A', nIdx );
432
433 sal_Int16 nCurDepth;
434 if( nPos )
435 {
436 pPara = new Paragraph( -1 );
437 nCurDepth = -1;
438 }
439 else
440 nCurDepth = pPara->GetDepth();
441
442 // In the outliner mode, filter the tabs and set the indentation
443 // about a LRSpaceItem. In EditEngine mode intend over old tabs
446 {
447 // Extract Tabs
448 size_t nTabs = 0;
449 while ( ( nTabs < aStr.size() ) && ( aStr[nTabs] == '\t' ) )
450 nTabs++;
451 if ( nTabs )
452 aStr = aStr.substr(nTabs);
453
454 // Keep depth? (see Outliner::Insert)
455 if( !(pPara->nFlags & ParaFlag::HOLDDEPTH) )
456 {
457 nCurDepth = nTabs-1; //TODO: sal_Int32 -> sal_Int16!
458 ImplCheckDepth( nCurDepth );
459 pPara->SetDepth( nCurDepth );
460 }
461 }
462 if( nPos ) // not with the first paragraph
463 {
464 pParaList->Insert( std::unique_ptr<Paragraph>(pPara), nInsPos );
465 pEditEngine->InsertParagraph( nInsPos, OUString(aStr) );
467 }
468 else
469 {
470 nInsPos--;
471 pEditEngine->SetText( nInsPos, OUString(aStr) );
472 }
473 ImplInitDepth( nInsPos, nCurDepth, false );
474 nInsPos++;
475 nPos++;
476 }
477 }
478
479 DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"SetText failed!");
480 bFirstParaIsEmpty = false;
482 // Restore the update mode.
483 pEditEngine->SetUpdateLayout(bUpdate, /*bRestoring=*/true);
484}
485
486// pView == 0 -> Ignore tabs
487
488bool Outliner::ImpConvertEdtToOut( sal_Int32 nPara )
489{
490
491 bool bConverted = false;
492 sal_Int32 nTabs = 0;
493 ESelection aDelSel;
494
495 OUString aName;
496
497 OUString aStr( pEditEngine->GetText( nPara ) );
498 const sal_Unicode* pPtr = aStr.getStr();
499
500 sal_Int32 nHeadingNumberStart = 0;
501 sal_Int32 nNumberingNumberStart = 0;
502 SfxStyleSheet* pStyle= pEditEngine->GetStyleSheet( nPara );
503 if( pStyle )
504 {
505 OUString aHeading_US( "heading" );
506 OUString aNumber_US( "Numbering" );
507 aName = pStyle->GetName();
508 sal_Int32 nSearch;
509 if ( ( nSearch = aName.indexOf( aHeading_US ) ) != -1 )
510 nHeadingNumberStart = nSearch + aHeading_US.getLength();
511 else if ( ( nSearch = aName.indexOf( aNumber_US ) ) != -1 )
512 nNumberingNumberStart = nSearch + aNumber_US.getLength();
513 }
514
515 if ( nHeadingNumberStart || nNumberingNumberStart )
516 {
517 // PowerPoint import ?
518 if( nHeadingNumberStart && ( aStr.getLength() >= 2 ) &&
519 ( pPtr[0] != '\t' ) && ( pPtr[1] == '\t' ) )
520 {
521 // Extract Bullet and Tab
522 aDelSel = ESelection( nPara, 0, nPara, 2 );
523 }
524
525 sal_Int32 nPos = nHeadingNumberStart ? nHeadingNumberStart : nNumberingNumberStart;
526 std::u16string_view aLevel = comphelper::string::stripStart(aName.subView(nPos), ' ');
527 nTabs = o3tl::toInt32(aLevel);
528 if( nTabs )
529 nTabs--; // Level 0 = "heading 1"
530 bConverted = true;
531 }
532 else
533 {
534 // filter leading tabs
535 while( *pPtr == '\t' )
536 {
537 pPtr++;
538 nTabs++;
539 }
540 // Remove tabs from the text
541 if( nTabs )
542 aDelSel = ESelection( nPara, 0, nPara, nTabs );
543 }
544
545 if ( aDelSel.HasRange() )
546 {
547 pEditEngine->QuickDelete( aDelSel );
548 }
549
550 const SfxInt16Item& rLevel = pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
551 sal_Int16 nOutlLevel = rLevel.GetValue();
552
553 ImplCheckDepth( nOutlLevel );
554 ImplInitDepth( nPara, nOutlLevel, false );
555
556 return bConverted;
557}
558
560{
561 bool bUpdate = pEditEngine->SetUpdateLayout( false );
562
563 bool bUndo = pEditEngine->IsUndoEnabled();
564 EnableUndo( false );
565
566 Init( rPObj.GetOutlinerMode() );
567
569 pEditEngine->SetText(rPObj.GetTextObject());
570
571 bFirstParaIsEmpty = false;
572
573 pParaList->Clear();
574 for( sal_Int32 nCurPara = 0; nCurPara < rPObj.Count(); nCurPara++ )
575 {
576 std::unique_ptr<Paragraph> pPara(new Paragraph( rPObj.GetParagraphData(nCurPara)));
577 ImplCheckDepth( pPara->nDepth );
578
579 pParaList->Append(std::move(pPara));
580 ImplCheckNumBulletItem( nCurPara );
581 }
582
583 ImplCheckParagraphs( 0, pParaList->GetParagraphCount() );
584
585 EnableUndo( bUndo );
587 pEditEngine->SetUpdateLayout( bUpdate );
588
589 DBG_ASSERT( pParaList->GetParagraphCount()==rPObj.Count(),"SetText failed");
590 DBG_ASSERT( pEditEngine->GetParagraphCount()==rPObj.Count(),"SetText failed");
591}
592
593void Outliner::AddText( const OutlinerParaObject& rPObj, bool bAppend )
594{
595 bool bUpdate = pEditEngine->SetUpdateLayout( false );
596
598 sal_Int32 nPara;
600 {
601 pParaList->Clear();
602 pEditEngine->SetText(rPObj.GetTextObject());
603 nPara = 0;
604 bAppend = false;
605 }
606 else
607 {
608 nPara = pParaList->GetParagraphCount();
609 pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject(), bAppend );
610 }
611 bFirstParaIsEmpty = false;
612
613 for( sal_Int32 n = 0; n < rPObj.Count(); n++ )
614 {
615 if ( n == 0 && bAppend )
616 {
617 // This first "paragraph" was just appended to an existing (incomplete) paragraph.
618 // Since no new paragraph will be added, the assumed increase-by-1 also won't happen.
619 --nPara;
620 continue;
621 }
622
623 Paragraph* pPara = new Paragraph( rPObj.GetParagraphData(n) );
624 pParaList->Append(std::unique_ptr<Paragraph>(pPara));
625 sal_Int32 nP = nPara+n;
626 DBG_ASSERT(pParaList->GetAbsPos(pPara)==nP,"AddText:Out of sync");
627 ImplInitDepth( nP, pPara->GetDepth(), false );
628 }
629 DBG_ASSERT( pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(), "SetText: OutOfSync" );
630
631 ImplCheckParagraphs( nPara, pParaList->GetParagraphCount() );
632
634 pEditEngine->SetUpdateLayout( bUpdate );
635}
636
637OUString Outliner::CalcFieldValue( const SvxFieldItem& rField, sal_Int32 nPara, sal_Int32 nPos, std::optional<Color>& rpTxtColor, std::optional<Color>& rpFldColor, std::optional<FontLineStyle>& rpFldLineStyle )
638{
639 if ( !aCalcFieldValueHdl.IsSet() )
640 return OUString( ' ' );
641
642 EditFieldInfo aFldInfo( this, rField, nPara, nPos );
643 // The FldColor is preset with COL_LIGHTGRAY.
644 if ( rpFldColor )
645 aFldInfo.SetFieldColor( *rpFldColor );
646
647 aCalcFieldValueHdl.Call( &aFldInfo );
648 if ( aFldInfo.GetTextColor() )
649 {
650 rpTxtColor = *aFldInfo.GetTextColor();
651 }
652
653 if ( aFldInfo.GetFontLineStyle() )
654 {
655 rpFldLineStyle = *aFldInfo.GetFontLineStyle();
656 }
657
658 if (aFldInfo.GetFieldColor())
659 rpFldColor = *aFldInfo.GetFieldColor();
660 else
661 rpFldColor.reset();
662
663 return aFldInfo.GetRepresentation();
664}
665
666void Outliner::SetStyleSheet( sal_Int32 nPara, SfxStyleSheet* pStyle )
667{
668 Paragraph* pPara = pParaList->GetParagraph( nPara );
669 if (pPara)
670 {
671 pEditEngine->SetStyleSheet( nPara, pStyle );
672 ImplCheckNumBulletItem( nPara );
673 }
674}
675
676void Outliner::ImplCheckNumBulletItem( sal_Int32 nPara )
677{
678 Paragraph* pPara = pParaList->GetParagraph( nPara );
679 if (pPara)
680 pPara->aBulSize.setWidth( -1 );
681}
682
684{
685
686 DBG_ASSERT( ( GetOutlinerMode() == OutlinerMode::OutlineObject ) || ( GetOutlinerMode() == OutlinerMode::OutlineView ), "SetLevelDependentStyleSheet: Wrong Mode!" );
687
688 SfxStyleSheet* pStyle = GetStyleSheet( nPara );
689
690 if ( !pStyle )
691 return;
692
693 sal_Int16 nDepth = GetDepth( nPara );
694 if( nDepth < 0 )
695 nDepth = 0;
696
697 OUString aNewStyleSheetName( pStyle->GetName() );
698 aNewStyleSheetName = aNewStyleSheetName.subView( 0, aNewStyleSheetName.getLength()-1 ) +
699 OUString::number( nDepth+1 );
700 SfxStyleSheet* pNewStyle = static_cast<SfxStyleSheet*>(GetStyleSheetPool()->Find( aNewStyleSheetName, pStyle->GetFamily() ));
701 DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" );
702 if ( pNewStyle && ( pNewStyle != GetStyleSheet( nPara ) ) )
703 {
704 SfxItemSet aOldAttrs( GetParaAttribs( nPara ) );
705 SetStyleSheet( nPara, pNewStyle );
706 if ( aOldAttrs.GetItemState( EE_PARA_NUMBULLET ) == SfxItemState::SET )
707 {
708 SfxItemSet aAttrs( GetParaAttribs( nPara ) );
709 aAttrs.Put( aOldAttrs.Get( EE_PARA_NUMBULLET ) );
710 SetParaAttribs( nPara, aAttrs );
711 }
712 }
713}
714
715void Outliner::ImplInitDepth( sal_Int32 nPara, sal_Int16 nDepth, bool bCreateUndo )
716{
717
718 DBG_ASSERT( ( nDepth >= gnMinDepth ) && ( nDepth <= nMaxDepth ), "ImplInitDepth - Depth is invalid!" );
719
720 Paragraph* pPara = pParaList->GetParagraph( nPara );
721 if (!pPara)
722 return;
723 sal_Int16 nOldDepth = pPara->GetDepth();
724 pPara->SetDepth( nDepth );
725
726 // For IsInUndo attributes and style do not have to be set, there
727 // the old values are restored by the EditEngine.
728 if( IsInUndo() )
729 return;
730
731 bool bUpdate = pEditEngine->SetUpdateLayout( false );
732
733 bool bUndo = bCreateUndo && IsUndoEnabled();
734
735 SfxItemSet aAttrs( pEditEngine->GetParaAttribs( nPara ) );
736 aAttrs.Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nDepth ) );
737 pEditEngine->SetParaAttribs( nPara, aAttrs );
738 ImplCheckNumBulletItem( nPara );
739 ImplCalcBulletText( nPara, false, false );
740
741 if ( bUndo )
742 {
743 InsertUndo( std::make_unique<OutlinerUndoChangeDepth>( this, nPara, nOldDepth, nDepth ) );
744 }
745
746 pEditEngine->SetUpdateLayout( bUpdate );
747}
748
749void Outliner::SetParaAttribs( sal_Int32 nPara, const SfxItemSet& rSet )
750{
751
752 pEditEngine->SetParaAttribs( nPara, rSet );
753}
754
755void Outliner::SetCharAttribs(sal_Int32 nPara, const SfxItemSet& rSet)
756{
757 pEditEngine->SetCharAttribs(nPara, rSet);
758}
759
760bool Outliner::Expand( Paragraph const * pPara )
761{
762 if ( !pParaList->HasHiddenChildren( pPara ) )
763 return false;
764
765 std::unique_ptr<OLUndoExpand> pUndo;
766 bool bUndo = IsUndoEnabled() && !IsInUndo();
767 if( bUndo )
768 {
770 pUndo.reset( new OLUndoExpand( this, OLUNDO_EXPAND ) );
771 pUndo->nCount = pParaList->GetAbsPos( pPara );
772 }
773 pParaList->Expand( pPara );
774 InvalidateBullet(pParaList->GetAbsPos(pPara));
775 if( bUndo )
776 {
777 InsertUndo( std::move(pUndo) );
779 }
780 return true;
781}
782
783bool Outliner::Collapse( Paragraph const * pPara )
784{
785 if ( !pParaList->HasVisibleChildren( pPara ) ) // collapsed
786 return false;
787
788 std::unique_ptr<OLUndoExpand> pUndo;
789 bool bUndo = false;
790
791 if( !IsInUndo() && IsUndoEnabled() )
792 bUndo = true;
793 if( bUndo )
794 {
796 pUndo.reset( new OLUndoExpand( this, OLUNDO_COLLAPSE ) );
797 pUndo->nCount = pParaList->GetAbsPos( pPara );
798 }
799
800 pParaList->Collapse( pPara );
801 InvalidateBullet(pParaList->GetAbsPos(pPara));
802 if( bUndo )
803 {
804 InsertUndo( std::move(pUndo) );
806 }
807 return true;
808}
809
811{
812 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
813 DBG_ASSERT( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ), "ImpCalcBulletFont: Missing or BitmapBullet!" );
814
815 vcl::Font aStdFont;
816 if ( !pEditEngine->IsFlatMode() )
817 {
818 ESelection aSel( nPara, 0, nPara, 0 );
819 aStdFont = EditEngine::CreateFontFromItemSet( pEditEngine->GetAttribs( aSel ), pEditEngine->GetScriptType( aSel ) );
820 }
821 else
822 {
823 aStdFont = pEditEngine->GetStandardFont( nPara );
824 }
825
826 vcl::Font aBulletFont;
827 std::optional<vcl::Font> pSourceFont;
828 if ( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
829 {
830 pSourceFont = pFmt->GetBulletFont();
831 }
832
833 if (pSourceFont)
834 {
835 aBulletFont = *pSourceFont;
836 }
837 else
838 {
839 aBulletFont = aStdFont;
840 aBulletFont.SetUnderline( LINESTYLE_NONE );
841 aBulletFont.SetOverline( LINESTYLE_NONE );
842 aBulletFont.SetStrikeout( STRIKEOUT_NONE );
843 aBulletFont.SetEmphasisMark( FontEmphasisMark::NONE );
844 aBulletFont.SetRelief( FontRelief::NONE );
845 }
846
847 // Use original scale...
848 double nStretchY = 100.0;
849 getGlobalScale(o3tl::temporary(double()), nStretchY, o3tl::temporary(double()), o3tl::temporary(double()));
850
851 double fScale = pFmt->GetBulletRelSize() * nStretchY / 100.0;
852 double fScaledLineHeight = aStdFont.GetFontSize().Height();
853 fScaledLineHeight *= fScale * 10;
854 fScaledLineHeight /= 1000.0;
855
856 aBulletFont.SetAlignment( ALIGN_BOTTOM );
857 aBulletFont.SetFontSize(Size(0, basegfx::fround(fScaledLineHeight)));
858 bool bVertical = IsVertical();
859 aBulletFont.SetVertical( bVertical );
860 aBulletFont.SetOrientation( Degree10(bVertical ? (IsTopToBottom() ? 2700 : 900) : 0) );
861
862 Color aColor( COL_AUTO );
863 if( !pEditEngine->IsFlatMode() && !( pEditEngine->GetControlWord() & EEControlBits::NOCOLORS ) )
864 {
865 aColor = pFmt->GetBulletColor();
866 }
867
868 if ( ( aColor == COL_AUTO ) || ( IsForceAutoColor() ) )
869 aColor = pEditEngine->GetAutoColor();
870
871 aBulletFont.SetColor( aColor );
872 return aBulletFont;
873}
874
875void Outliner::PaintBullet(sal_Int32 nPara, const Point& rStartPos, const Point& rOrigin,
876 Degree10 nOrientation, OutputDevice& rOutDev)
877{
878
879 bool bDrawBullet = false;
880 if (pEditEngine)
881 {
882 const SfxBoolItem& rBulletState = pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
883 bDrawBullet = rBulletState.GetValue();
884 }
885
886 if (!(bDrawBullet && ImplHasNumberFormat(nPara)))
887 return;
888
889 bool bVertical = IsVertical();
890 bool bTopToBottom = IsTopToBottom();
891
892 bool bRightToLeftPara = pEditEngine->IsRightToLeft( nPara );
893
894 tools::Rectangle aBulletArea( ImpCalcBulletArea( nPara, true, false ) );
895
896 double nStretchX = 100.0;
898 nStretchX, o3tl::temporary(double()));
899
900 tools::Long nStretchBulletX = basegfx::fround(double(aBulletArea.Left()) * nStretchX / 100.0);
901 tools::Long nStretchBulletWidth = basegfx::fround(double(aBulletArea.GetWidth()) * nStretchX / 100.0);
902 aBulletArea = tools::Rectangle(Point(nStretchBulletX, aBulletArea.Top()),
903 Size(nStretchBulletWidth, aBulletArea.GetHeight()) );
904
905 Paragraph* pPara = pParaList->GetParagraph( nPara );
906 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
907 if ( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) )
908 {
909 if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
910 {
911 vcl::Font aBulletFont( ImpCalcBulletFont( nPara ) );
912 // Use baseline
913 bool bSymbol = pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
914 aBulletFont.SetAlignment( bSymbol ? ALIGN_BOTTOM : ALIGN_BASELINE );
915 vcl::Font aOldFont = rOutDev.GetFont();
916 rOutDev.SetFont( aBulletFont );
917
918 ParagraphInfos aParaInfos = pEditEngine->GetParagraphInfos( nPara );
919 Point aTextPos;
920 if ( !bVertical )
921 {
922// aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
923 aTextPos.setY( rStartPos.Y() + ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent ) );
924 if ( !bRightToLeftPara )
925 aTextPos.setX( rStartPos.X() + aBulletArea.Left() );
926 else
927 aTextPos.setX( rStartPos.X() + GetPaperSize().Width() - aBulletArea.Right() );
928 }
929 else
930 {
931 if (bTopToBottom)
932 {
933// aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
934 aTextPos.setX( rStartPos.X() - (bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent) );
935 aTextPos.setY( rStartPos.Y() + aBulletArea.Left() );
936 }
937 else
938 {
939 aTextPos.setX( rStartPos.X() + (bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent) );
940 aTextPos.setY( rStartPos.Y() + aBulletArea.Left() );
941 }
942 }
943
944 if ( nOrientation )
945 {
946 // Both TopLeft and bottom left is not quite correct,
947 // since in EditEngine baseline ...
948 rOrigin.RotateAround(aTextPos, nOrientation);
949
950 vcl::Font aRotatedFont( aBulletFont );
951 aRotatedFont.SetOrientation( nOrientation );
952 rOutDev.SetFont( aRotatedFont );
953 }
954
955 // VCL will take care of brackets and so on...
956 vcl::text::ComplexTextLayoutFlags nLayoutMode = rOutDev.GetLayoutMode();
958 if ( bRightToLeftPara )
960 rOutDev.SetLayoutMode( nLayoutMode );
961
963 {
964 const vcl::Font& aSvxFont(rOutDev.GetFont());
966 rOutDev.GetTextArray( pPara->GetText(), &aBuf );
967
968 if(bSymbol)
969 {
970 // aTextPos is Bottom, go to Baseline
971 FontMetric aMetric(rOutDev.GetFontMetric());
972 aTextPos.AdjustY( -(aMetric.GetDescent()) );
973 }
974
975 assert(aBuf.get_factor() == 1);
976 DrawingText(aTextPos, pPara->GetText(), 0, pPara->GetText().getLength(), aBuf.get_subunit_array(), {},
977 aSvxFont, nPara, bRightToLeftPara ? 1 : 0, nullptr, nullptr, false, false, true, nullptr, Color(), Color());
978 }
979 else
980 {
981 rOutDev.DrawText( aTextPos, pPara->GetText() );
982 }
983
984 rOutDev.SetFont( aOldFont );
985 }
986 else
987 {
988 if ( pFmt->GetBrush()->GetGraphicObject() )
989 {
990 Point aBulletPos;
991 if ( !bVertical )
992 {
993 aBulletPos.setY( rStartPos.Y() + aBulletArea.Top() );
994 if ( !bRightToLeftPara )
995 aBulletPos.setX( rStartPos.X() + aBulletArea.Left() );
996 else
997 aBulletPos.setX( rStartPos.X() + GetPaperSize().Width() - aBulletArea.Right() );
998 }
999 else
1000 {
1001 if (bTopToBottom)
1002 {
1003 aBulletPos.setX( rStartPos.X() - aBulletArea.Bottom() );
1004 aBulletPos.setY( rStartPos.Y() + aBulletArea.Left() );
1005 }
1006 else
1007 {
1008 aBulletPos.setX( rStartPos.X() + aBulletArea.Top() );
1009 aBulletPos.setY( rStartPos.Y() - aBulletArea.Right() );
1010 }
1011 }
1012
1014 {
1015 if(aDrawBulletHdl.IsSet())
1016 {
1017 // call something analog to aDrawPortionHdl (if set) and feed it something
1018 // analog to DrawPortionInfo...
1019 // created aDrawBulletHdl, Set/GetDrawBulletHdl.
1020 // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
1021 DrawBulletInfo aDrawBulletInfo(
1022 *pFmt->GetBrush()->GetGraphicObject(),
1023 aBulletPos,
1024 pPara->aBulSize);
1025
1026 aDrawBulletHdl.Call(&aDrawBulletInfo);
1027 }
1028 }
1029 else
1030 {
1031 pFmt->GetBrush()->GetGraphicObject()->Draw(rOutDev, aBulletPos, pPara->aBulSize);
1032 }
1033 }
1034 }
1035 }
1036
1037 // In case of collapsed subparagraphs paint a line before the text.
1038 if( !pParaList->HasChildren(pPara) || pParaList->HasVisibleChildren(pPara) ||
1039 bStrippingPortions || nOrientation )
1040 return;
1041
1042 tools::Long nWidth = rOutDev.PixelToLogic( Size( 10, 0 ) ).Width();
1043
1044 Point aStartPos, aEndPos;
1045 if ( !bVertical )
1046 {
1047 aStartPos.setY( rStartPos.Y() + aBulletArea.Bottom() );
1048 if ( !bRightToLeftPara )
1049 aStartPos.setX( rStartPos.X() + aBulletArea.Right() );
1050 else
1051 aStartPos.setX( rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left() );
1052 aEndPos = aStartPos;
1053 aEndPos.AdjustX(nWidth );
1054 }
1055 else
1056 {
1057 aStartPos.setX( rStartPos.X() - aBulletArea.Bottom() );
1058 aStartPos.setY( rStartPos.Y() + aBulletArea.Right() );
1059 aEndPos = aStartPos;
1060 aEndPos.AdjustY(nWidth );
1061 }
1062
1063 const Color& rOldLineColor = rOutDev.GetLineColor();
1064 rOutDev.SetLineColor( COL_BLACK );
1065 rOutDev.DrawLine( aStartPos, aEndPos );
1066 rOutDev.SetLineColor( rOldLineColor );
1067}
1068
1069void Outliner::InvalidateBullet(sal_Int32 nPara)
1070{
1071 tools::Long nLineHeight = static_cast<tools::Long>(pEditEngine->GetLineHeight(nPara ));
1072 for (OutlinerView* pView : aViewList)
1073 {
1074 Point aPos( pView->pEditView->GetWindowPosTopLeft(nPara ) );
1075 tools::Rectangle aRect( pView->GetOutputArea() );
1076 aRect.SetRight( aPos.X() );
1077 aRect.SetTop( aPos.Y() );
1078 aRect.SetBottom( aPos.Y() );
1079 aRect.AdjustBottom(nLineHeight );
1080
1081 pView->pEditView->InvalidateWindow(aRect);
1082 }
1083}
1084
1085ErrCode Outliner::Read( SvStream& rInput, const OUString& rBaseURL, EETextFormat eFormat, SvKeyValueIterator* pHTTPHeaderAttrs )
1086{
1087
1088 bool bOldUndo = pEditEngine->IsUndoEnabled();
1089 EnableUndo( false );
1090
1091 bool bUpdate = pEditEngine->SetUpdateLayout( false );
1092
1093 Clear();
1094
1096 ErrCode nRet = pEditEngine->Read( rInput, rBaseURL, eFormat, pHTTPHeaderAttrs );
1097
1098 bFirstParaIsEmpty = false;
1099
1100 sal_Int32 nParas = pEditEngine->GetParagraphCount();
1101 pParaList->Clear();
1102 for ( sal_Int32 n = 0; n < nParas; n++ )
1103 {
1104 std::unique_ptr<Paragraph> pPara(new Paragraph( 0 ));
1105 pParaList->Append(std::move(pPara));
1106 }
1107
1108 ImpFilterIndents( 0, nParas-1 );
1109
1111 pEditEngine->SetUpdateLayout( bUpdate );
1112 EnableUndo( bOldUndo );
1113
1114 return nRet;
1115}
1116
1117
1118void Outliner::ImpFilterIndents( sal_Int32 nFirstPara, sal_Int32 nLastPara )
1119{
1120 bool bUpdate = pEditEngine->SetUpdateLayout( false );
1121
1122 Paragraph* pLastConverted = nullptr;
1123 for( sal_Int32 nPara = nFirstPara; nPara <= nLastPara; nPara++ )
1124 {
1125 Paragraph* pPara = pParaList->GetParagraph( nPara );
1126 if (pPara)
1127 {
1128 if( ImpConvertEdtToOut( nPara ) )
1129 {
1130 pLastConverted = pPara;
1131 }
1132 else if ( pLastConverted )
1133 {
1134 // Arrange normal paragraphs below the heading ...
1135 pPara->SetDepth( pLastConverted->GetDepth() );
1136 }
1137
1138 ImplInitDepth( nPara, pPara->GetDepth(), false );
1139 }
1140 }
1141
1142 pEditEngine->SetUpdateLayout( bUpdate );
1143}
1144
1146{
1147 return pEditEngine->GetUndoManager();
1148}
1149
1151{
1152 return pEditEngine->SetUndoManager(pNew);
1153}
1154
1155void Outliner::ImpTextPasted( sal_Int32 nStartPara, sal_Int32 nCount )
1156{
1157 bool bUpdate = pEditEngine->SetUpdateLayout( false );
1158
1159 const sal_Int32 nStart = nStartPara;
1160
1161 Paragraph* pPara = pParaList->GetParagraph( nStartPara );
1162
1163 while( nCount && pPara )
1164 {
1166 {
1168 ParaFlag nPrevFlags = pPara->nFlags;
1169
1170 ImpConvertEdtToOut( nStartPara );
1171
1172 if( nStartPara == nStart )
1173 {
1174 // the existing paragraph has changed depth or flags
1175 if( (pPara->GetDepth() != nDepthChangedHdlPrevDepth) || (pPara->nFlags != nPrevFlags) )
1176 DepthChangedHdl(pPara, nPrevFlags);
1177 }
1178 }
1179 else // EditEngine mode
1180 {
1181 sal_Int16 nDepth = -1;
1182 const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( nStartPara );
1183 if ( rAttrs.GetItemState( EE_PARA_OUTLLEVEL ) == SfxItemState::SET )
1184 {
1185 const SfxInt16Item& rLevel = rAttrs.Get( EE_PARA_OUTLLEVEL );
1186 nDepth = rLevel.GetValue();
1187 }
1188 if ( nDepth != GetDepth( nStartPara ) )
1189 ImplInitDepth( nStartPara, nDepth, false );
1190 }
1191
1192 nCount--;
1193 nStartPara++;
1194 pPara = pParaList->GetParagraph( nStartPara );
1195 }
1196
1197 pEditEngine->SetUpdateLayout( bUpdate );
1198
1199 DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"ImpTextPasted failed");
1200}
1201
1203{
1204 if( !aIndentingPagesHdl.IsSet() )
1205 return true;
1206 return aIndentingPagesHdl.Call( pView );
1207}
1208
1210{
1211 // The selected pages must already be set in advance through
1212 // ImpCalcSelectedPages
1213
1214 // If the first paragraph is on level 0 it can not indented in any case,
1215 // possible there might be indentations in the following on the 0 level.
1216 if ( ( mnFirstSelPage == 0 ) && ( GetOutlinerMode() != OutlinerMode::TextObject ) )
1217 {
1218 if ( nDepthChangedHdlPrevDepth == 1 ) // is the only page
1219 return false;
1220 else
1221 (void)pCurView->ImpCalcSelectedPages( false ); // without the first
1222 }
1223 return IndentingPagesHdl( pCurView );
1224}
1225
1226
1228{
1229 // The selected pages must already be set in advance through
1230 // ImpCalcSelectedPages
1231 return RemovingPagesHdl( pCurView );
1232}
1233
1235 : mnFirstSelPage(0)
1236 , nDepthChangedHdlPrevDepth(0)
1237 , nMaxDepth(9)
1238 , bFirstParaIsEmpty(true)
1239 , nBlockInsCallback(0)
1240 , bStrippingPortions(false)
1241 , bPasting(false)
1242{
1243
1244 pParaList.reset( new ParagraphList );
1245 pParaList->SetVisibleStateChangedHdl( LINK( this, Outliner, ParaVisibleStateChangedHdl ) );
1246 std::unique_ptr<Paragraph> pPara(new Paragraph( 0 ));
1247 pParaList->Append(std::move(pPara));
1248
1249 pEditEngine.reset( new OutlinerEditEng( this, pPool ) );
1250 pEditEngine->SetBeginMovingParagraphsHdl( LINK( this, Outliner, BeginMovingParagraphsHdl ) );
1251 pEditEngine->SetEndMovingParagraphsHdl( LINK( this, Outliner, EndMovingParagraphsHdl ) );
1252 pEditEngine->SetBeginPasteOrDropHdl( LINK( this, Outliner, BeginPasteOrDropHdl ) );
1253 pEditEngine->SetEndPasteOrDropHdl( LINK( this, Outliner, EndPasteOrDropHdl ) );
1254
1255 Init( nMode );
1256}
1257
1259{
1260 pParaList->Clear();
1261 pParaList.reset();
1262 pEditEngine.reset();
1263}
1264
1265size_t Outliner::InsertView( OutlinerView* pView, size_t nIndex )
1266{
1267 size_t ActualIndex;
1268
1269 if ( nIndex >= aViewList.size() )
1270 {
1271 aViewList.push_back( pView );
1272 ActualIndex = aViewList.size() - 1;
1273 }
1274 else
1275 {
1276 ViewList::iterator it = aViewList.begin();
1277 advance( it, nIndex );
1278 ActualIndex = nIndex;
1279 }
1280 pEditEngine->InsertView( pView->pEditView.get(), nIndex );
1281 return ActualIndex;
1282}
1283
1285{
1286 ViewList::iterator it = std::find(aViewList.begin(), aViewList.end(), pView);
1287 if (it != aViewList.end())
1288 {
1289 pView->pEditView->HideCursor(); // HACK
1290 pEditEngine->RemoveView( pView->pEditView.get() );
1291 aViewList.erase( it );
1292 }
1293}
1294
1295void Outliner::RemoveView( size_t nIndex )
1296{
1297 EditView* pEditView = pEditEngine->GetView( nIndex );
1298 pEditView->HideCursor(); // HACK
1299
1300 pEditEngine->RemoveView( nIndex );
1301
1302 {
1303 ViewList::iterator it = aViewList.begin();
1304 advance( it, nIndex );
1305 aViewList.erase( it );
1306 }
1307}
1308
1309
1310OutlinerView* Outliner::GetView( size_t nIndex ) const
1311{
1312 return ( nIndex >= aViewList.size() ) ? nullptr : aViewList[ nIndex ];
1313}
1314
1316{
1317 return aViewList.size();
1318}
1319
1321{
1322 if( !IsInUndo() )
1323 aParaInsertedHdl.Call( { this, pPara } );
1324}
1325
1326
1328{
1329 if( !IsInUndo() )
1330 aDepthChangedHdl.Call( { this, pPara, nPrevFlags } );
1331}
1332
1333
1334sal_Int32 Outliner::GetAbsPos( Paragraph const * pPara ) const
1335{
1336 DBG_ASSERT(pPara,"GetAbsPos:No Para");
1337 return pParaList->GetAbsPos( pPara );
1338}
1339
1341{
1342 return pParaList->GetParagraphCount();
1343}
1344
1345Paragraph* Outliner::GetParagraph( sal_Int32 nAbsPos ) const
1346{
1347 return pParaList->GetParagraph( nAbsPos );
1348}
1349
1350bool Outliner::HasChildren( Paragraph const * pParagraph ) const
1351{
1352 return pParaList->HasChildren( pParagraph );
1353}
1354
1355bool Outliner::ImplHasNumberFormat( sal_Int32 nPara ) const
1356{
1357 return GetNumberFormat(nPara) != nullptr;
1358}
1359
1360const SvxNumberFormat* Outliner::GetNumberFormat( sal_Int32 nPara ) const
1361{
1362 const SvxNumberFormat* pFmt = nullptr;
1363
1364 Paragraph* pPara = pParaList->GetParagraph( nPara );
1365 if (!pPara)
1366 return nullptr;
1367
1368 sal_Int16 nDepth = pPara->GetDepth();
1369
1370 if( nDepth >= 0 )
1371 {
1372 const SvxNumBulletItem& rNumBullet = pEditEngine->GetParaAttrib( nPara, EE_PARA_NUMBULLET );
1373 if ( rNumBullet.GetNumRule().GetLevelCount() > nDepth )
1374 pFmt = rNumBullet.GetNumRule().Get( nDepth );
1375 }
1376
1377 return pFmt;
1378}
1379
1381{
1382 Paragraph* pPara = pParaList->GetParagraph( nPara );
1383 if (!pPara)
1384 return Size();
1385
1386 if( pPara->aBulSize.Width() == -1 )
1387 {
1388 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1389 DBG_ASSERT( pFmt, "ImplGetBulletSize - no Bullet!" );
1390
1391 if ( pFmt->GetNumberingType() == SVX_NUM_NUMBER_NONE )
1392 {
1393 pPara->aBulSize = Size( 0, 0 );
1394 }
1395 else if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1396 {
1397 OUString aBulletText = ImplGetBulletText( nPara );
1398 OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1399 vcl::Font aBulletFont( ImpCalcBulletFont( nPara ) );
1400 vcl::Font aRefFont( pRefDev->GetFont());
1401 pRefDev->SetFont( aBulletFont );
1402 pPara->aBulSize.setWidth( pRefDev->GetTextWidth( aBulletText ) );
1403 pPara->aBulSize.setHeight( pRefDev->GetTextHeight() );
1404 pRefDev->SetFont( aRefFont );
1405 }
1406 else
1407 {
1409 MapMode(MapUnit::Map100thMM),
1410 pEditEngine->GetRefDevice()->GetMapMode());
1411 }
1412 }
1413
1414 return pPara->aBulSize;
1415}
1416
1417void Outliner::ImplCheckParagraphs( sal_Int32 nStart, sal_Int32 nEnd )
1418{
1419
1420 for ( sal_Int32 n = nStart; n < nEnd; n++ )
1421 {
1422 Paragraph* pPara = pParaList->GetParagraph( n );
1423 if (pPara)
1424 {
1425 pPara->Invalidate();
1426 ImplCalcBulletText( n, false, false );
1427 }
1428 }
1429}
1430
1432{
1433 pEditEngine->SetRefDevice( pRefDev );
1434 for ( sal_Int32 n = pParaList->GetParagraphCount(); n; )
1435 {
1436 Paragraph* pPara = pParaList->GetParagraph( --n );
1437 pPara->Invalidate();
1438 }
1439}
1440
1441void Outliner::ParaAttribsChanged( sal_Int32 nPara )
1442{
1443 // The Outliner does not have an undo of its own, when paragraphs are
1444 // separated/merged. When ParagraphInserted the attribute EE_PARA_OUTLLEVEL
1445 // may not be set, this is however needed when the depth of the paragraph
1446 // is to be determined.
1447 if (!pEditEngine->IsInUndo())
1448 return;
1449 if (pParaList->GetParagraphCount() != pEditEngine->GetParagraphCount())
1450 return;
1451 Paragraph* pPara = pParaList->GetParagraph(nPara);
1452 if (!pPara)
1453 return;
1454 // tdf#100734: force update of bullet
1455 pPara->Invalidate();
1456 const SfxInt16Item& rLevel = pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1457 if (pPara->GetDepth() == rLevel.GetValue())
1458 return;
1459 pPara->SetDepth(rLevel.GetValue());
1460 ImplCalcBulletText(nPara, true, true);
1461}
1462
1464{
1465
1466 // The EditEngine calls StyleSheetChanged also for derived styles.
1467 // Here all the paragraphs, which had the said template, used to be
1468 // hunted by an ImpRecalcParaAttribs, why?
1469 // => only the Bullet-representation can really change...
1470 sal_Int32 nParas = pParaList->GetParagraphCount();
1471 for( sal_Int32 nPara = 0; nPara < nParas; nPara++ )
1472 {
1473 if ( pEditEngine->GetStyleSheet( nPara ) == pStyle )
1474 {
1475 ImplCheckNumBulletItem( nPara );
1476 ImplCalcBulletText( nPara, false, false );
1477 // EditEngine formats changed paragraphs before calling this method,
1478 // so they are not reformatted now and use wrong bullet indent
1479 pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
1480 }
1481 }
1482}
1483
1484tools::Rectangle Outliner::ImpCalcBulletArea( sal_Int32 nPara, bool bAdjust, bool bReturnPaperPos )
1485{
1486 // Bullet area within the paragraph ...
1487 tools::Rectangle aBulletArea;
1488
1489 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1490 if ( pFmt )
1491 {
1492 Point aTopLeft;
1493 Size aBulletSize( ImplGetBulletSize( nPara ) );
1494
1495 bool bOutlineMode = bool( pEditEngine->GetControlWord() & EEControlBits::OUTLINER );
1496
1497 // the ODF attribute text:space-before which holds the spacing to add to the left of the label
1498 const auto nSpaceBefore = pFmt->GetAbsLSpace() + pFmt->GetFirstLineOffset();
1499
1500 const SvxLRSpaceItem& rLR = pEditEngine->GetParaAttrib( nPara, bOutlineMode ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
1501 aTopLeft.setX( rLR.GetTextLeft() + rLR.GetTextFirstLineOffset() + nSpaceBefore );
1502
1503 tools::Long nBulletWidth = std::max( static_cast<tools::Long>(-rLR.GetTextFirstLineOffset()), static_cast<tools::Long>((-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance()) );
1504 if ( nBulletWidth < aBulletSize.Width() ) // The Bullet creates its space
1505 nBulletWidth = aBulletSize.Width();
1506
1507 if ( bAdjust && !bOutlineMode )
1508 {
1509 // Adjust when centered or align right
1510 const SvxAdjustItem& rItem = pEditEngine->GetParaAttrib( nPara, EE_PARA_JUST );
1511 if ( ( !pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SvxAdjust::Left ) ) ||
1512 ( pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SvxAdjust::Right ) ) )
1513 {
1514 aTopLeft.setX( pEditEngine->GetFirstLineStartX( nPara ) - nBulletWidth );
1515 }
1516 }
1517
1518 // Vertical:
1519 ParagraphInfos aInfos = pEditEngine->GetParagraphInfos( nPara );
1520 if ( aInfos.bValid )
1521 {
1522 aTopLeft.setY( /* aInfos.nFirstLineOffset + */ // nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
1523 aInfos.nFirstLineHeight - aInfos.nFirstLineTextHeight
1524 + aInfos.nFirstLineTextHeight / 2
1525 - aBulletSize.Height() / 2 );
1526 // may prefer to print out on the baseline ...
1527 if( ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) )
1528 {
1529 vcl::Font aBulletFont( ImpCalcBulletFont( nPara ) );
1530 if ( aBulletFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL )
1531 {
1532 OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1533 vcl::Font aOldFont = pRefDev->GetFont();
1534 pRefDev->SetFont( aBulletFont );
1535 FontMetric aMetric( pRefDev->GetFontMetric() );
1536 // Leading on the first line ...
1537 aTopLeft.setY( /* aInfos.nFirstLineOffset + */ aInfos.nFirstLineMaxAscent );
1538 aTopLeft.AdjustY( -(aMetric.GetAscent()) );
1539 pRefDev->SetFont( aOldFont );
1540 }
1541 }
1542 }
1543
1544 // Horizontal:
1545 if( pFmt->GetNumAdjust() == SvxAdjust::Right )
1546 {
1547 aTopLeft.AdjustX(nBulletWidth - aBulletSize.Width() );
1548 }
1549 else if( pFmt->GetNumAdjust() == SvxAdjust::Center )
1550 {
1551 aTopLeft.AdjustX(( nBulletWidth - aBulletSize.Width() ) / 2 );
1552 }
1553
1554 if ( aTopLeft.X() < 0 ) // then push
1555 aTopLeft.setX( 0 );
1556
1557 aBulletArea = tools::Rectangle( aTopLeft, aBulletSize );
1558 }
1559 if ( bReturnPaperPos )
1560 {
1561 Size aBulletSize( aBulletArea.GetSize() );
1562 Point aBulletDocPos( aBulletArea.TopLeft() );
1563 aBulletDocPos.AdjustY(pEditEngine->GetDocPosTopLeft( nPara ).Y() );
1564 Point aBulletPos( aBulletDocPos );
1565
1566 if ( IsVertical() )
1567 {
1568 aBulletPos.setY( aBulletDocPos.X() );
1569 aBulletPos.setX( GetPaperSize().Width() - aBulletDocPos.Y() );
1570 // Rotate:
1571 aBulletPos.AdjustX( -(aBulletSize.Height()) );
1572 Size aSz( aBulletSize );
1573 aBulletSize.setWidth( aSz.Height() );
1574 aBulletSize.setHeight( aSz.Width() );
1575 }
1576 else if ( pEditEngine->IsRightToLeft( nPara ) )
1577 {
1578 aBulletPos.setX( GetPaperSize().Width() - aBulletDocPos.X() - aBulletSize.Width() );
1579 }
1580
1581 aBulletArea = tools::Rectangle( aBulletPos, aBulletSize );
1582 }
1583 return aBulletArea;
1584}
1585
1587{
1588 EBulletInfo aInfo;
1589
1590 aInfo.nParagraph = nPara;
1591 aInfo.bVisible = ImplHasNumberFormat( nPara );
1592
1593 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1594 aInfo.nType = pFmt ? pFmt->GetNumberingType() : 0;
1595
1596 if( pFmt )
1597 {
1598 if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1599 {
1600 aInfo.aText = ImplGetBulletText( nPara );
1601
1602 if( pFmt->GetBulletFont() )
1603 aInfo.aFont = *pFmt->GetBulletFont();
1604 }
1605 }
1606
1607 if ( aInfo.bVisible )
1608 {
1609 aInfo.aBounds = ImpCalcBulletArea( nPara, true, true );
1610 }
1611
1612 return aInfo;
1613}
1614
1615OUString Outliner::GetText( Paragraph const * pParagraph, sal_Int32 nCount ) const
1616{
1617
1618 OUStringBuffer aText(128);
1619 sal_Int32 nStartPara = pParaList->GetAbsPos( pParagraph );
1620 for ( sal_Int32 n = 0; n < nCount; n++ )
1621 {
1622 aText.append(pEditEngine->GetText( nStartPara + n ));
1623 if ( (n+1) < nCount )
1624 aText.append("\n");
1625 }
1626 return aText.makeStringAndClear();
1627}
1628
1629void Outliner::Remove( Paragraph const * pPara, sal_Int32 nParaCount )
1630{
1631
1632 sal_Int32 nPos = pParaList->GetAbsPos( pPara );
1633 if( !nPos && ( nParaCount >= pParaList->GetParagraphCount() ) )
1634 {
1635 Clear();
1636 }
1637 else
1638 {
1639 for( sal_Int32 n = 0; n < nParaCount; n++ )
1640 pEditEngine->RemoveParagraph( nPos );
1641 }
1642}
1643
1645{
1646 bStrippingPortions = true;
1647 pEditEngine->StripPortions();
1648 bStrippingPortions = false;
1649}
1650
1651void Outliner::DrawingText( const Point& rStartPos, const OUString& rText, sal_Int32 nTextStart,
1652 sal_Int32 nTextLen, o3tl::span<const sal_Int32> pDXArray,
1653 o3tl::span<const sal_Bool> pKashidaArray, const SvxFont& rFont,
1654 sal_Int32 nPara, sal_uInt8 nRightToLeft,
1655 const EEngineData::WrongSpellVector* pWrongSpellVector,
1656 const SvxFieldData* pFieldData,
1657 bool bEndOfLine,
1658 bool bEndOfParagraph,
1659 bool bEndOfBullet,
1660 const css::lang::Locale* pLocale,
1661 const Color& rOverlineColor,
1662 const Color& rTextLineColor)
1663{
1665 {
1666 DrawPortionInfo aInfo( rStartPos, rText, nTextStart, nTextLen, rFont, nPara, pDXArray, pKashidaArray, pWrongSpellVector,
1667 pFieldData, pLocale, rOverlineColor, rTextLineColor, nRightToLeft, false, 0, bEndOfLine, bEndOfParagraph, bEndOfBullet);
1668
1669 aDrawPortionHdl.Call( &aInfo );
1670 }
1671}
1672
1673void Outliner::DrawingTab( const Point& rStartPos, tools::Long nWidth, const OUString& rChar, const SvxFont& rFont,
1674 sal_Int32 nPara, sal_uInt8 nRightToLeft, bool bEndOfLine, bool bEndOfParagraph,
1675 const Color& rOverlineColor, const Color& rTextLineColor)
1676{
1678 {
1679 DrawPortionInfo aInfo( rStartPos, rChar, 0, rChar.getLength(), rFont, nPara, {}, {}, nullptr,
1680 nullptr, nullptr, rOverlineColor, rTextLineColor, nRightToLeft, true, nWidth, bEndOfLine, bEndOfParagraph, false);
1681
1682 aDrawPortionHdl.Call( &aInfo );
1683 }
1684}
1685
1687{
1688 return !aRemovingPagesHdl.IsSet() || aRemovingPagesHdl.Call( pView );
1689}
1690
1691bool Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView, sal_Int32 _nFirstPage, sal_Int32 nPages )
1692{
1693
1695 mnFirstSelPage = _nFirstPage;
1696 return RemovingPagesHdl( pCurView );
1697}
1698
1699SfxItemSet const & Outliner::GetParaAttribs( sal_Int32 nPara ) const
1700{
1701 return pEditEngine->GetParaAttribs( nPara );
1702}
1703
1704IMPL_LINK( Outliner, ParaVisibleStateChangedHdl, Paragraph&, rPara, void )
1705{
1706 sal_Int32 nPara = pParaList->GetAbsPos( &rPara );
1707 pEditEngine->ShowParagraph( nPara, rPara.IsVisible() );
1708}
1709
1710IMPL_LINK_NOARG(Outliner, BeginMovingParagraphsHdl, MoveParagraphsInfo&, void)
1711{
1712 if( !IsInUndo() )
1713 aBeginMovingHdl.Call( this );
1714}
1715
1716IMPL_LINK( Outliner, BeginPasteOrDropHdl, PasteOrDropInfos&, rInfos, void )
1717{
1718 UndoActionStart( EDITUNDO_DRAGANDDROP );
1719 maBeginPasteOrDropHdl.Call(&rInfos);
1720}
1721
1722IMPL_LINK( Outliner, EndPasteOrDropHdl, PasteOrDropInfos&, rInfos, void )
1723{
1724 bPasting = false;
1725 ImpTextPasted( rInfos.nStartPara, rInfos.nEndPara - rInfos.nStartPara + 1 );
1726 maEndPasteOrDropHdl.Call( &rInfos );
1727 UndoActionEnd();
1728}
1729
1730IMPL_LINK( Outliner, EndMovingParagraphsHdl, MoveParagraphsInfo&, rInfos, void )
1731{
1732 pParaList->MoveParagraphs( rInfos.nStartPara, rInfos.nDestPara, rInfos.nEndPara - rInfos.nStartPara + 1 );
1733 sal_Int32 nChangesStart = std::min( rInfos.nStartPara, rInfos.nDestPara );
1734 sal_Int32 nParas = pParaList->GetParagraphCount();
1735 for ( sal_Int32 n = nChangesStart; n < nParas; n++ )
1736 ImplCalcBulletText( n, false, false );
1737
1738 if( !IsInUndo() )
1739 aEndMovingHdl.Call( this );
1740}
1741
1742static bool isSameNumbering( const SvxNumberFormat& rN1, const SvxNumberFormat& rN2 )
1743{
1744 if( rN1.GetNumberingType() != rN2.GetNumberingType() )
1745 return false;
1746
1747 if( rN1.GetNumStr(1) != rN2.GetNumStr(1) )
1748 return false;
1749
1750 if( (rN1.GetPrefix() != rN2.GetPrefix()) || (rN1.GetSuffix() != rN2.GetSuffix()) )
1751 return false;
1752
1753 return true;
1754}
1755
1756sal_uInt16 Outliner::ImplGetNumbering( sal_Int32 nPara, const SvxNumberFormat* pParaFmt )
1757{
1758 sal_uInt16 nNumber = pParaFmt->GetStart() - 1;
1759
1760 Paragraph* pPara = pParaList->GetParagraph( nPara );
1761 const sal_Int16 nParaDepth = pPara->GetDepth();
1762
1763 do
1764 {
1765 pPara = pParaList->GetParagraph( nPara );
1766 const sal_Int16 nDepth = pPara->GetDepth();
1767
1768 // ignore paragraphs that are below our paragraph or have no numbering
1769 if( (nDepth > nParaDepth) || (nDepth == -1) )
1770 continue;
1771
1772 // stop on paragraphs that are above our paragraph
1773 if( nDepth < nParaDepth )
1774 break;
1775
1776 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1777
1778 if( pFmt == nullptr )
1779 continue; // ignore paragraphs without bullets
1780
1781 // check if numbering less than or equal to pParaFmt
1782 if( !isSameNumbering( *pFmt, *pParaFmt ) || ( pFmt->GetStart() < pParaFmt->GetStart() ) )
1783 break;
1784
1785 if ( pFmt->GetStart() > pParaFmt->GetStart() )
1786 {
1787 nNumber += pFmt->GetStart() - pParaFmt->GetStart();
1788 pParaFmt = pFmt;
1789 }
1790
1791 const SfxBoolItem& rBulletState = pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
1792
1793 if( rBulletState.GetValue() )
1794 nNumber += 1;
1795
1796 // same depth, same number format, check for restart
1797 const sal_Int16 nNumberingStartValue = pPara->GetNumberingStartValue();
1798 if( (nNumberingStartValue != -1) || pPara->IsParaIsNumberingRestart() )
1799 {
1800 if( nNumberingStartValue != -1 )
1801 nNumber += nNumberingStartValue - 1;
1802 break;
1803 }
1804 }
1805 while( nPara-- );
1806
1807 return nNumber;
1808}
1809
1810void Outliner::ImplCalcBulletText( sal_Int32 nPara, bool bRecalcLevel, bool bRecalcChildren )
1811{
1812
1813 Paragraph* pPara = pParaList->GetParagraph( nPara );
1814
1815 while ( pPara )
1816 {
1817 OUString aBulletText;
1818 const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1819 if( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) )
1820 {
1821 aBulletText += pFmt->GetPrefix();
1822 if( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
1823 {
1824 sal_UCS4 cChar = pFmt->GetBulletChar();
1825 aBulletText += OUString(&cChar, 1);
1826 }
1827 else if( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE )
1828 {
1829 aBulletText += pFmt->GetNumStr( ImplGetNumbering( nPara, pFmt ) );
1830 }
1831 aBulletText += pFmt->GetSuffix();
1832 }
1833
1834 if (pPara->GetText() != aBulletText)
1835 pPara->SetText( aBulletText );
1836
1837 if ( bRecalcLevel )
1838 {
1839 sal_Int16 nDepth = pPara->GetDepth();
1840 pPara = pParaList->GetParagraph( ++nPara );
1841 if ( !bRecalcChildren )
1842 {
1843 while ( pPara && ( pPara->GetDepth() > nDepth ) )
1844 pPara = pParaList->GetParagraph( ++nPara );
1845 }
1846
1847 if ( pPara && ( pPara->GetDepth() < nDepth ) )
1848 pPara = nullptr;
1849 }
1850 else
1851 {
1852 pPara = nullptr;
1853 }
1854 }
1855}
1856
1858{
1859
1860 if( !bFirstParaIsEmpty )
1861 {
1863 pEditEngine->Clear();
1864 pParaList->Clear();
1865 pParaList->Append( std::unique_ptr<Paragraph>(new Paragraph( gnMinDepth )));
1866 bFirstParaIsEmpty = true;
1868 }
1869 else
1870 {
1871 Paragraph* pPara = pParaList->GetParagraph( 0 );
1872 if(pPara)
1873 pPara->SetDepth( gnMinDepth );
1874 }
1875}
1876
1877void Outliner::SetFlatMode( bool bFlat )
1878{
1879
1880 if( bFlat != pEditEngine->IsFlatMode() )
1881 {
1882 for ( sal_Int32 nPara = pParaList->GetParagraphCount(); nPara; )
1883 pParaList->GetParagraph( --nPara )->aBulSize.setWidth( -1 );
1884
1885 pEditEngine->SetFlatMode( bFlat );
1886 }
1887}
1888
1889OUString Outliner::ImplGetBulletText( sal_Int32 nPara )
1890{
1891 OUString aRes;
1892 Paragraph* pPara = pParaList->GetParagraph( nPara );
1893 if (pPara)
1894 {
1895 ImplCalcBulletText( nPara, false, false );
1896 aRes = pPara->GetText();
1897 }
1898 return aRes;
1899}
1900
1901// this is needed for StarOffice Api
1903{
1904 SfxItemSet aOldAttrs( pEditEngine->GetParaAttribs( nPara ) );
1906 pEditEngine->SetParaAttribs( nPara, aOldAttrs );
1907}
1908
1910{
1911 if ( b )
1912 {
1914 }
1915 else
1916 {
1917 DBG_ASSERT( nBlockInsCallback, "ImplBlockInsertionCallbacks ?!" );
1919 if ( !nBlockInsCallback )
1920 {
1921 // Call blocked notify events...
1922 while(!pEditEngine->aNotifyCache.empty())
1923 {
1924 EENotify aNotify(pEditEngine->aNotifyCache.front());
1925 // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
1926 pEditEngine->aNotifyCache.erase(pEditEngine->aNotifyCache.begin());
1927 pEditEngine->aOutlinerNotifyHdl.Call( aNotify );
1928 }
1929 }
1930 }
1931}
1932
1933IMPL_LINK( Outliner, EditEngineNotifyHdl, EENotify&, rNotify, void )
1934{
1935 if ( !nBlockInsCallback )
1936 pEditEngine->aOutlinerNotifyHdl.Call( rNotify );
1937 else
1938 pEditEngine->aNotifyCache.push_back(rNotify);
1939}
1940
1943{
1944 pEditEngine->SetBeginDropHdl( rLink );
1945}
1946
1949{
1950 pEditEngine->SetEndDropHdl( rLink );
1951}
1952
1955{
1956 maBeginPasteOrDropHdl = rLink;
1957}
1958
1961{
1962 maEndPasteOrDropHdl = rLink;
1963}
1964
1966{
1967 if( pPara && !pPara->HasFlag( nFlag ) )
1968 {
1969 if( IsUndoEnabled() && !IsInUndo() )
1970 InsertUndo( std::make_unique<OutlinerUndoChangeParaFlags>( this, GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags|nFlag ) );
1971
1972 pPara->SetFlag( nFlag );
1973 }
1974}
1975
1976bool Outliner::HasParaFlag( const Paragraph* pPara, ParaFlag nFlag )
1977{
1978 return pPara && pPara->HasFlag( nFlag );
1979}
1980
1981
1983{
1984 return pEditEngine->IsPageOverflow();
1985}
1986
1987std::optional<NonOverflowingText> Outliner::GetNonOverflowingText() const
1988{
1989 /* XXX:
1990 * nCount should be the number of paragraphs of the non overflowing text
1991 * nStart should be the starting paragraph of the non overflowing text (XXX: Always 0?)
1992 */
1993
1994 if ( GetParagraphCount() < 1 )
1995 return {};
1996
1997 // last non-overflowing paragraph is before the first overflowing one
1998 sal_Int32 nCount = pEditEngine->GetOverflowingParaNum();
1999 sal_Int32 nOverflowLine = pEditEngine->GetOverflowingLineNum(); // XXX: Unused for now
2000
2001 // Defensive check: overflowing para index beyond actual # of paragraphs?
2002 if ( nCount > GetParagraphCount()-1) {
2003 SAL_INFO("editeng.chaining",
2004 "[Overflowing] Ops, trying to retrieve para "
2005 << nCount << " when max index is " << GetParagraphCount()-1 );
2006 return {};
2007 }
2008
2009 if (nCount < 0)
2010 {
2011 SAL_INFO("editeng.chaining",
2012 "[Overflowing] No Overflowing text but GetNonOverflowinText called?!");
2013 return {};
2014 }
2015
2016 // NOTE: We want the selection of the overflowing text from here
2017 // At the same time we may want to consider the beginning of such text
2018 // in a more fine grained way (i.e. as GetNonOverflowingText did)
2019
2020/*
2021 sal_Int32 nHeadPara = pEditEngine->GetOverflowingParaNum();
2022 sal_uInt32 nParaCount = GetParagraphCount();
2023
2024 sal_uInt32 nLen = 0;
2025 for ( sal_Int32 nLine = 0;
2026 nLine < pEditEngine->GetOverflowingLineNum();
2027 nLine++) {
2028 nLen += GetLineLen(nHeadPara, nLine);
2029 }
2030
2031 sal_uInt32 nOverflowingPara = pEditEngine->GetOverflowingParaNum();
2032 ESelection aOverflowingTextSel;
2033 sal_Int32 nLastPara = nParaCount-1;
2034 sal_Int32 nLastParaLen = GetText(GetParagraph(nLastPara)).getLength();
2035 aOverflowingTextSel = ESelection(nOverflowingPara, nLen,
2036 nLastPara, nLastParaLen);
2037 bool bLastParaInterrupted =
2038 pEditEngine->GetOverflowingLineNum() > 0;
2039
2040 return new NonOverflowingText(aOverflowingTextSel, bLastParaInterrupted);
2041 **/
2042
2043
2044 // Only overflowing text, i.e. 1st line of 1st paragraph overflowing
2045 bool bItAllOverflew = nCount == 0 && nOverflowLine == 0;
2046 if ( bItAllOverflew )
2047 {
2048 ESelection aEmptySel(0,0,0,0);
2049 //EditTextObject *pTObj = pEditEngine->CreateTextObject(aEmptySel);
2050 bool const bLastParaInterrupted = true; // Last Para was interrupted since everything overflew
2051 return NonOverflowingText(aEmptySel, bLastParaInterrupted);
2052 } else { // Get the lines that of the overflowing para fit in the box
2053
2054 sal_Int32 nOverflowingPara = nCount;
2055 sal_uInt32 nLen = 0;
2056
2057 for ( sal_Int32 nLine = 0;
2058 nLine < pEditEngine->GetOverflowingLineNum();
2059 nLine++)
2060 {
2061 nLen += GetLineLen(nOverflowingPara, nLine);
2062 }
2063
2064 //sal_Int32 nStartPara = 0;
2065 //sal_Int32 nStartPos = 0;
2066 ESelection aOverflowingTextSelection;
2067
2068 const sal_Int32 nEndPara = GetParagraphCount()-1;
2069 const sal_Int32 nEndPos = pEditEngine->GetTextLen(nEndPara);
2070
2071 if (nLen == 0) {
2072 // XXX: What happens inside this case might be dependent on the joining paragraph or not-thingy
2073 // Overflowing paragraph is empty or first line overflowing: it's not "Non-Overflowing" text then
2074 sal_Int32 nParaLen = GetText(GetParagraph(nOverflowingPara-1)).getLength();
2075 aOverflowingTextSelection =
2076 ESelection(nOverflowingPara-1, nParaLen, nEndPara, nEndPos);
2077 } else {
2078 // We take until we have to from the overflowing paragraph
2079 aOverflowingTextSelection =
2080 ESelection(nOverflowingPara, nLen, nEndPara, nEndPos);
2081 }
2082 //EditTextObject *pTObj = pEditEngine->CreateTextObject(aNonOverflowingTextSelection);
2083
2084 //sal_Int32 nLastLine = GetLineCount(nOverflowingPara)-1;
2085 bool bLastParaInterrupted =
2086 pEditEngine->GetOverflowingLineNum() > 0;
2087
2088 return NonOverflowingText(aOverflowingTextSelection, bLastParaInterrupted);
2089 }
2090}
2091
2093{
2094 std::unique_ptr<EditTextObject> pEmptyText = pEditEngine->GetEmptyTextObject();
2095 OutlinerParaObject aPObj( std::move(pEmptyText) );
2097 return aPObj;
2098}
2099
2100std::optional<OverflowingText> Outliner::GetOverflowingText() const
2101{
2102 if ( pEditEngine->GetOverflowingParaNum() < 0)
2103 return {};
2104
2105
2106 // Defensive check: overflowing para index beyond actual # of paragraphs?
2107 if ( pEditEngine->GetOverflowingParaNum() > GetParagraphCount()-1) {
2108 SAL_INFO("editeng.chaining",
2109 "[Overflowing] Ops, trying to retrieve para "
2110 << pEditEngine->GetOverflowingParaNum() << " when max index is "
2111 << GetParagraphCount()-1 );
2112 return {};
2113 }
2114
2115 sal_Int32 nHeadPara = pEditEngine->GetOverflowingParaNum();
2116 sal_uInt32 nParaCount = GetParagraphCount();
2117
2118 sal_uInt32 nLen = 0;
2119 for ( sal_Int32 nLine = 0;
2120 nLine < pEditEngine->GetOverflowingLineNum();
2121 nLine++) {
2122 nLen += GetLineLen(nHeadPara, nLine);
2123 }
2124
2125 sal_uInt32 nOverflowingPara = pEditEngine->GetOverflowingParaNum();
2126 ESelection aOverflowingTextSel;
2127 sal_Int32 nLastPara = nParaCount-1;
2128 sal_Int32 nLastParaLen = GetText(GetParagraph(nLastPara)).getLength();
2129 aOverflowingTextSel = ESelection(nOverflowingPara, nLen,
2130 nLastPara, nLastParaLen);
2131 return OverflowingText(pEditEngine->CreateTransferable(aOverflowingTextSel));
2132
2133}
2134
2136{
2137 pEditEngine->ClearOverflowingParaNum();
2138}
2139
2141{
2142 bool bOwns = false;
2143 if (!pWriter)
2144 {
2145 pWriter = xmlNewTextWriterFilename("outliner.xml", 0);
2146 xmlTextWriterSetIndent(pWriter,1);
2147 (void)xmlTextWriterSetIndentString(pWriter, BAD_CAST(" "));
2148 (void)xmlTextWriterStartDocument(pWriter, nullptr, nullptr, nullptr);
2149 bOwns = true;
2150 }
2151
2152 (void)xmlTextWriterStartElement(pWriter, BAD_CAST("Outliner"));
2153 pParaList->dumpAsXml(pWriter);
2154 (void)xmlTextWriterEndElement(pWriter);
2155
2156 if (bOwns)
2157 {
2158 (void)xmlTextWriterEndDocument(pWriter);
2159 xmlFreeTextWriter(pWriter);
2160 }
2161}
2162
2163/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static vcl::Font CreateFontFromItemSet(const SfxItemSet &rItemSet, SvtScriptType nScriptType)
Definition: editeng.cxx:2701
std::optional< Color > const & GetFieldColor() const
Definition: outliner.hxx:534
void SetFieldColor(std::optional< Color > xCol)
Definition: outliner.hxx:535
std::optional< Color > const & GetTextColor() const
Definition: outliner.hxx:531
std::optional< FontLineStyle > const & GetFontLineStyle() const
Definition: outliner.hxx:537
const OUString & GetRepresentation() const
Definition: outliner.hxx:543
void HideCursor(bool bDeactivate=false)
Definition: editview.cxx:532
tools::Long GetDescent() const
tools::Long GetAscent() const
bool Draw(OutputDevice &rOut, const Point &rPt, const Size &rSz, const GraphicAttr *pAttr=nullptr) const
const ParagraphData & GetParagraphData(sal_Int32 nIndex) const
Definition: outlobj.cxx:194
sal_Int32 Count() const
Definition: outlobj.cxx:166
void SetOutlinerMode(OutlinerMode nNew)
Definition: outlobj.cxx:122
const EditTextObject & GetTextObject() const
Definition: outlobj.cxx:189
OutlinerMode GetOutlinerMode() const
Definition: outlobj.cxx:117
std::unique_ptr< EditView > pEditView
Definition: outliner.hxx:184
EDITENG_DLLPRIVATE sal_Int32 ImpCalcSelectedPages(bool bIncludeFirstSelected)
Definition: outlvw.cxx:801
void DrawingText(const Point &rStartPos, const OUString &rText, sal_Int32 nTextStart, sal_Int32 nTextLen, o3tl::span< const sal_Int32 > pDXArray, o3tl::span< const sal_Bool > pKashidaArray, const SvxFont &rFont, sal_Int32 nPara, sal_uInt8 nRightToLeft, const EEngineData::WrongSpellVector *pWrongSpellVector, const SvxFieldData *pFieldData, bool bEndOfLine, bool bEndOfParagraph, bool bEndOfBullet, const css::lang::Locale *pLocale, const Color &rOverlineColor, const Color &rTextLineColor)
Definition: outliner.cxx:1651
void Remove(Paragraph const *pPara, sal_Int32 nParaCount)
Definition: outliner.cxx:1629
bool Expand(Paragraph const *)
Definition: outliner.cxx:760
void SetBeginDropHdl(const Link< EditView *, void > &rLink)
sets a link that is called at the beginning of a drag operation at an edit view
Definition: outliner.cxx:1942
static bool HasParaFlag(const Paragraph *pPara, ParaFlag nFlag)
Definition: outliner.cxx:1976
SfxStyleSheetPool * GetStyleSheetPool()
Definition: outlin2.cxx:256
void SetMaxDepth(sal_Int16 nDepth)
Definition: outliner.cxx:221
void ImplCheckParagraphs(sal_Int32 nStart, sal_Int32 nEnd)
Definition: outliner.cxx:1417
void SetCharAttribs(sal_Int32 nPara, const SfxItemSet &rSet)
Set attributes from rSet an all characters of nPara.
Definition: outliner.cxx:755
void SetText(const OutlinerParaObject &)
Definition: outliner.cxx:559
void ClearOverflowingParaNum()
Definition: outliner.cxx:2135
OUString GetText(Paragraph const *pPara, sal_Int32 nParaCount=1) const
Definition: outliner.cxx:1615
void ImplBlockInsertionCallbacks(bool b)
Definition: outliner.cxx:1909
Link< OutlinerView *, bool > aRemovingPagesHdl
Definition: outliner.hxx:601
void SetLevelDependentStyleSheet(sal_Int32 nPara)
Definition: outliner.cxx:1902
bool IsParaIsNumberingRestart(sal_Int32 nPara) const
Definition: outliner.cxx:281
void SetFlatMode(bool bFlat)
Definition: outliner.cxx:1877
bool bPasting
Definition: outliner.hxx:616
const Size & GetPaperSize() const
Definition: outlin2.cxx:181
OutlinerMode GetOutlinerMode() const
Definition: outliner.hxx:952
friend class OutlinerEditEng
Definition: outliner.hxx:578
tools::Rectangle ImpCalcBulletArea(sal_Int32 nPara, bool bAdjust, bool bReturnPaperPos)
Definition: outliner.cxx:1484
void ParagraphInsertedHdl(Paragraph *)
Definition: outliner.cxx:1320
SfxUndoManager * SetUndoManager(SfxUndoManager *pNew)
Definition: outliner.cxx:1150
void DrawingTab(const Point &rStartPos, tools::Long nWidth, const OUString &rChar, const SvxFont &rFont, sal_Int32 nPara, sal_uInt8 nRightToLeft, bool bEndOfLine, bool bEndOfParagraph, const Color &rOverlineColor, const Color &rTextLineColor)
Definition: outliner.cxx:1673
void AddText(const OutlinerParaObject &, bool bAppend=false)
Definition: outliner.cxx:593
Paragraph * GetParagraph(sal_Int32 nAbsPos) const
Definition: outliner.cxx:1345
OutlinerParaObject GetEmptyParaObject() const
Definition: outliner.cxx:2092
const SvxNumberFormat * GetNumberFormat(sal_Int32 nPara) const
Definition: outliner.cxx:1360
void PaintBullet(sal_Int32 nPara, const Point &rStartPos, const Point &rOrigin, Degree10 nOrientation, OutputDevice &rOutDev)
Definition: outliner.cxx:875
void getGlobalScale(double &rFontX, double &rFontY, double &rSpacingX, double &rSpacingY) const
Definition: outlin2.cxx:494
std::optional< OutlinerParaObject > CreateParaObject(sal_Int32 nStartPara=0, sal_Int32 nParaCount=EE_PARA_ALL) const
Definition: outliner.cxx:361
sal_Int16 nMaxDepth
Definition: outliner.hxx:608
void Clear()
Definition: outliner.cxx:1857
sal_Int16 GetDepth(sal_Int32 nPara) const
Definition: outliner.cxx:229
void SetStyleSheet(sal_Int32 nPara, SfxStyleSheet *pStyle)
Definition: outliner.cxx:666
vcl::Font ImpCalcBulletFont(sal_Int32 nPara) const
Definition: outliner.cxx:810
std::unique_ptr< OutlinerEditEng > pEditEngine
Definition: outliner.hxx:587
bool ImplHasNumberFormat(sal_Int32 nPara) const
Definition: outliner.cxx:1355
bool ImpConvertEdtToOut(sal_Int32 nPara)
Definition: outliner.cxx:488
void InsertUndo(std::unique_ptr< EditUndo > pUndo)
Definition: outlin2.cxx:306
void SetDepth(Paragraph *pParagraph, sal_Int16 nNewDepth)
Definition: outliner.cxx:236
OutlinerView * GetView(size_t nIndex) const
Definition: outliner.cxx:1310
bool IsPageOverflow()
Definition: outliner.cxx:1982
Link< OutlinerView *, bool > aIndentingPagesHdl
Definition: outliner.hxx:600
void SetEndPasteOrDropHdl(const Link< PasteOrDropInfos *, void > &rLink)
sets a link that is called after a drop or paste operation.
Definition: outliner.cxx:1960
void SetParaAttribs(sal_Int32 nPara, const SfxItemSet &)
Definition: outliner.cxx:749
void ParaAttribsChanged(sal_Int32 nParagraph)
Definition: outliner.cxx:1441
void ImplCalcBulletText(sal_Int32 nPara, bool bRecalcLevel, bool bRecalcChildren)
Definition: outliner.cxx:1810
void ImplCheckNumBulletItem(sal_Int32 nPara)
Definition: outliner.cxx:676
bool IsUndoEnabled() const
Definition: outlin2.cxx:65
Size ImplGetBulletSize(sal_Int32 nPara)
Definition: outliner.cxx:1380
void StripPortions()
Definition: outliner.cxx:1644
void ImpTextPasted(sal_Int32 nStartPara, sal_Int32 nCount)
Definition: outliner.cxx:1155
Link< ParagraphHdlParam, void > aParaRemovingHdl
Definition: outliner.hxx:596
sal_Int32 GetAbsPos(Paragraph const *pPara) const
Definition: outliner.cxx:1334
bool bFirstParaIsEmpty
Definition: outliner.hxx:613
sal_Int32 GetBulletsNumberingStatus() const
Definition: outliner.cxx:354
std::optional< NonOverflowingText > GetNonOverflowingText() const
Definition: outliner.cxx:1987
void ImplCheckDepth(sal_Int16 &rnDepth) const
Definition: outliner.cxx:61
virtual OUString CalcFieldValue(const SvxFieldItem &rField, sal_Int32 nPara, sal_Int32 nPos, std::optional< Color > &rTxtColor, std::optional< Color > &rFldColor, std::optional< FontLineStyle > &rFldLineStyle)
Definition: outliner.cxx:637
bool Collapse(Paragraph const *)
Definition: outliner.cxx:783
SfxUndoManager & GetUndoManager()
Definition: outliner.cxx:1145
void UndoActionStart(sal_uInt16 nId)
Definition: outlin2.cxx:296
std::optional< OverflowingText > GetOverflowingText() const
Definition: outliner.cxx:2100
Link< DepthChangeHdlParam, void > aDepthChangedHdl
Definition: outliner.hxx:597
std::unique_ptr< ParagraphList > pParaList
Definition: outliner.hxx:589
void RemoveView(OutlinerView const *pView)
Definition: outliner.cxx:1284
OutlinerMode nOutlinerMode
Definition: outliner.hxx:611
static constexpr sal_Int16 gnMinDepth
Definition: outliner.hxx:609
size_t InsertView(OutlinerView *pView, size_t nIndex=size_t(-1))
Definition: outliner.cxx:1265
EBulletInfo GetBulletInfo(sal_Int32 nPara)
Definition: outliner.cxx:1586
OUString ImplGetBulletText(sal_Int32 nPara)
Definition: outliner.cxx:1889
bool ImpCanDeleteSelectedPages(OutlinerView *pCurView)
Definition: outliner.cxx:1227
sal_Int16 GetNumberingStartValue(sal_Int32 nPara) const
Definition: outliner.cxx:257
sal_Int32 mnFirstSelPage
Definition: outliner.hxx:592
void SetEndDropHdl(const Link< EditView *, void > &rLink)
sets a link that is called at the end of a drag operation at an edit view
Definition: outliner.cxx:1948
void SetToEmptyText()
Definition: outliner.cxx:392
Link< ParagraphHdlParam, void > aParaInsertedHdl
Definition: outliner.hxx:595
void StyleSheetChanged(SfxStyleSheet const *pStyle)
Definition: outliner.cxx:1463
Link< DrawPortionInfo *, void > aDrawPortionHdl
Definition: outliner.hxx:593
Link< PasteOrDropInfos *, void > maBeginPasteOrDropHdl
Definition: outliner.hxx:604
void dumpAsXml(xmlTextWriterPtr pWriter) const
Definition: outliner.cxx:2140
sal_uInt16 ImplGetNumbering(sal_Int32 nPara, const SvxNumberFormat *pParaFmt)
Definition: outliner.cxx:1756
void ImplSetLevelDependentStyleSheet(sal_Int32 nPara)
Definition: outliner.cxx:683
ViewList aViewList
Definition: outliner.hxx:590
SfxItemSet const & GetParaAttribs(sal_Int32 nPara) const
Definition: outliner.cxx:1699
Link< EditFieldInfo *, void > aCalcFieldValueHdl
Definition: outliner.hxx:602
void SetBeginPasteOrDropHdl(const Link< PasteOrDropInfos *, void > &rLink)
sets a link that is called before a drop or paste operation.
Definition: outliner.cxx:1954
bool IndentingPagesHdl(OutlinerView *)
Definition: outliner.cxx:1202
friend class OLUndoExpand
Definition: outliner.hxx:580
Outliner(SfxItemPool *pPool, OutlinerMode nMode)
Definition: outliner.cxx:1234
void SetParaFlag(Paragraph *pPara, ParaFlag nFlag)
Definition: outliner.cxx:1965
void DepthChangedHdl(Paragraph *, ParaFlag nPrevFlags)
Definition: outliner.cxx:1327
void ImplInitDepth(sal_Int32 nPara, sal_Int16 nDepth, bool bCreateUndo)
Definition: outliner.cxx:715
void SetRefDevice(OutputDevice *pRefDev)
Definition: outliner.cxx:1431
void ImpFilterIndents(sal_Int32 nFirstPara, sal_Int32 nLastPara)
Definition: outliner.cxx:1118
void SetNumberingStartValue(sal_Int32 nPara, sal_Int16 nNumberingStartValue)
Definition: outliner.cxx:264
bool RemovingPagesHdl(OutlinerView *)
Definition: outliner.cxx:1686
virtual ~Outliner() override
Definition: outliner.cxx:1258
bool IsVertical() const
Definition: outlin2.cxx:530
sal_Int32 nDepthChangedHdlPrevDepth
Definition: outliner.hxx:607
void ParagraphInserted(sal_Int32 nParagraph)
Definition: outliner.cxx:115
bool ImpCanIndentSelectedPages(OutlinerView *pCurView)
Definition: outliner.cxx:1209
bool HasChildren(Paragraph const *pParagraph) const
Definition: outliner.cxx:1350
ErrCode Read(SvStream &rInput, const OUString &rBaseURL, EETextFormat, SvKeyValueIterator *pHTTPHeaderAttrs=nullptr)
Definition: outliner.cxx:1085
Paragraph * Insert(const OUString &rText, sal_Int32 nAbsPos=EE_PARA_APPEND, sal_Int16 nDepth=0)
Definition: outliner.cxx:69
Link< PasteOrDropInfos *, void > maEndPasteOrDropHdl
Definition: outliner.hxx:605
sal_Int32 GetLineLen(sal_Int32 nParagraph, sal_Int32 nLine) const
Definition: outlin2.cxx:321
Link< DrawBulletInfo *, void > aDrawBulletHdl
Definition: outliner.hxx:594
sal_uInt8 nBlockInsCallback
Definition: outliner.hxx:614
void Init(OutlinerMode nMode)
Definition: outliner.cxx:185
bool IsInUndo() const
Definition: outlin2.cxx:311
size_t GetViewCount() const
Definition: outliner.cxx:1315
SfxStyleSheet * GetStyleSheet(sal_Int32 nPara)
Definition: outlin2.cxx:261
bool IsTopToBottom() const
Definition: outlin2.cxx:535
bool bStrippingPortions
Definition: outliner.hxx:615
void InvalidateBullet(sal_Int32 nPara)
Definition: outliner.cxx:1069
void ParagraphDeleted(sal_Int32 nParagraph)
Definition: outliner.cxx:150
void EnableUndo(bool bEnable)
Definition: outlin2.cxx:60
void UndoActionEnd()
Definition: outlin2.cxx:301
sal_Int32 GetParagraphCount() const
Definition: outliner.cxx:1340
void SetParaIsNumberingRestart(sal_Int32 nPara, bool bParaIsNumberingRestart)
Definition: outliner.cxx:288
bool IsForceAutoColor() const
Definition: outlin2.cxx:580
const vcl::Font & GetFont() const
void SetFont(const vcl::Font &rNewFont)
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void DrawLine(const Point &rStartPt, const Point &rEndPt)
SAL_WARN_UNUSED_RESULT Point LogicToLogic(const Point &rPtSource, const MapMode *pMapModeSource, const MapMode *pMapModeDest) const
void SetLineColor()
tools::Long GetTextWidth(const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
tools::Long GetTextArray(const OUString &rStr, KernArray *pDXAry, sal_Int32 nIndex=0, sal_Int32 nLen=-1, bool bCaret=false, vcl::text::TextLayoutCache const *=nullptr, SalLayoutGlyphs const *const pLayoutCache=nullptr) const
vcl::text::ComplexTextLayoutFlags GetLayoutMode() const
FontMetric GetFontMetric() const
const Color & GetLineColor() const
tools::Long GetTextHeight() const
void DrawText(const Point &rStartPt, const OUString &rStr, sal_Int32 nIndex=0, sal_Int32 nLen=-1, std::vector< tools::Rectangle > *pVector=nullptr, OUString *pDisplayText=nullptr, const SalLayoutGlyphs *pLayoutCache=nullptr)
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
sal_Int16 GetDepth() const
Definition: outliner.hxx:145
void SetNumberingStartValue(sal_Int16 nNumberingStartValue)
Definition: paralist.cxx:70
bool bVisible
Definition: outliner.hxx:133
bool IsParaIsNumberingRestart() const
Definition: outliner.hxx:150
sal_Int16 GetNumberingStartValue() const
Definition: outliner.hxx:147
bool HasFlag(ParaFlag nFlag) const
Definition: outliner.hxx:155
ParaFlag nFlags
Definition: outliner.hxx:132
void SetFlag(ParaFlag nFlag)
Definition: outliner.hxx:153
Size aBulSize
Definition: outliner.hxx:131
const OUString & GetText() const
Definition: outliner.hxx:139
void Invalidate()
Definition: outliner.hxx:137
void SetDepth(sal_Int16 nNewDepth)
Definition: outliner.hxx:138
void SetText(const OUString &rText)
Definition: outliner.hxx:136
void SetParaIsNumberingRestart(bool bParaIsNumberingRestart)
Definition: paralist.cxx:77
constexpr tools::Long Y() const
void setX(tools::Long nX)
void RotateAround(tools::Long &rX, tools::Long &rY, Degree10 nOrientation) const
void setY(tools::Long nY)
tools::Long AdjustY(tools::Long nVertMove)
tools::Long AdjustX(tools::Long nHorzMove)
constexpr tools::Long X() const
bool GetValue() const
sal_Int16 GetValue() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
const SfxPoolItem & Get(sal_uInt16 nWhich, bool bSrchInParent=true) const
virtual SfxStyleSheetBase * Find(const OUString &, SfxStyleFamily eFam, SfxStyleSearchBits n=SfxStyleSearchBits::All)
const OUString & GetName() const
SfxStyleFamily GetFamily() const
virtual void Clear()
constexpr tools::Long Height() const
void setWidth(tools::Long nWidth)
void setHeight(tools::Long nHeight)
constexpr tools::Long Width() const
SvxAdjust GetAdjust() const
Definition: adjustitem.hxx:108
const GraphicObject * GetGraphicObject(OUString const &referer=OUString()) const
Definition: frmitems.cxx:4392
This item stores a field (SvxFieldData).
Definition: flditem.hxx:70
short GetTextFirstLineOffset() const
Definition: lrspitem.hxx:346
tools::Long GetTextLeft() const
Definition: frmitems.cxx:567
const SvxNumRule & GetNumRule() const
Definition: numitem.hxx:325
sal_uInt16 GetLevelCount() const
Definition: numitem.hxx:298
const SvxNumberFormat * Get(sal_uInt16 nLevel) const
Definition: numitem.cxx:919
const SvxBrushItem * GetBrush() const
Definition: numitem.hxx:200
const Color & GetBulletColor() const
Definition: numitem.hxx:192
sal_uInt16 GetBulletRelSize() const
Definition: numitem.hxx:190
sal_Int32 GetFirstLineOffset() const
Definition: numitem.cxx:484
const std::optional< vcl::Font > & GetBulletFont() const
Definition: numitem.hxx:186
sal_UCS4 GetBulletChar() const
Definition: numitem.hxx:188
const Size & GetGraphicSize() const
Definition: numitem.hxx:204
sal_uInt16 GetStart() const
Definition: numitem.hxx:197
sal_Int32 GetAbsLSpace() const
Definition: numitem.cxx:478
SvxAdjust GetNumAdjust() const
Definition: numitem.hxx:171
const OUString & GetPrefix() const
Definition: numitem.hxx:173
const OUString & GetSuffix() const
Definition: numitem.hxx:175
short GetCharTextDistance() const
Definition: numitem.cxx:490
SvxNumType GetNumberingType() const
Definition: numitem.hxx:73
OUString GetNumStr(sal_Int32 nNo) const
Definition: numitem.cxx:108
Specialise std::optional template for the case where we are wrapping a o3tl::cow_wrapper type,...
Definition: outlobj.hxx:133
constexpr tools::Long GetWidth() const
constexpr void SetTop(tools::Long v)
constexpr tools::Long Top() const
constexpr Point TopLeft() const
constexpr void SetRight(tools::Long v)
constexpr Size GetSize() const
constexpr tools::Long Right() const
constexpr void SetBottom(tools::Long v)
constexpr tools::Long GetHeight() const
tools::Long AdjustBottom(tools::Long nVertMoveDelta)
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
void SetFontSize(const Size &)
void SetOrientation(Degree10 nLineOrientation)
void SetVertical(bool bVertical)
void SetColor(const Color &)
void SetUnderline(FontLineStyle)
const Size & GetFontSize() const
void SetAlignment(TextAlign)
void SetOverline(FontLineStyle)
rtl_TextEncoding GetCharSet() const
void SetRelief(FontRelief)
void SetEmphasisMark(FontEmphasisMark)
void SetStrikeout(FontStrikeout)
constexpr ::Color COL_AUTO(ColorTransparency, 0xFF, 0xFF, 0xFF, 0xFF)
constexpr ::Color COL_BLACK(0x00, 0x00, 0x00)
int nCount
#define DBG_ASSERT(sCon, aError)
#define EE_PARA_ALL
Definition: editdata.hxx:50
#define EDITUNDO_DRAGANDDROP
Definition: editdata.hxx:76
EETextFormat
Definition: editdata.hxx:35
#define EE_PARA_APPEND
Definition: editdata.hxx:49
EEControlBits
Definition: editstat.hxx:28
constexpr TypedWhichId< SfxBoolItem > EE_PARA_BULLETSTATE(EE_PARA_START+9)
constexpr TypedWhichId< SvxAdjustItem > EE_PARA_JUST(EE_PARA_START+16)
constexpr TypedWhichId< SvxLRSpaceItem > EE_PARA_LRSPACE(EE_PARA_START+13)
constexpr TypedWhichId< SfxInt16Item > EE_PARA_OUTLLEVEL(EE_PARA_START+11)
constexpr TypedWhichId< SvxLRSpaceItem > EE_PARA_OUTLLRSPACE(EE_PARA_START+10)
constexpr TypedWhichId< SvxNumBulletItem > EE_PARA_NUMBULLET(EE_PARA_START+5)
struct _xmlTextWriter * xmlTextWriterPtr
LINESTYLE_NONE
STRIKEOUT_NONE
ALIGN_BOTTOM
ALIGN_BASELINE
sal_Int32 nIndex
OUString aName
sal_Int64 n
LINEEND_LF
TOOLS_DLLPUBLIC OString convertLineEnd(const OString &rIn, LineEnd eLineEnd)
sal_uInt16 nPos
const char * pLocale
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
aStr
aBuf
std::vector< WrongSpellClass > WrongSpellVector
Definition: eedata.hxx:42
B2IRange fround(const B2DRange &rRange)
OString stripStart(const OString &rIn, char c)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
sal_Int32 toInt32(std::u16string_view str, sal_Int16 radix=10)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
constexpr T & temporary(T &&x)
long Long
ComplexTextLayoutFlags
#define SVX_MAX_NUM
Definition: numdef.hxx:23
IMPL_LINK(Outliner, ParaVisibleStateChangedHdl, Paragraph &, rPara, void)
Definition: outliner.cxx:1704
static bool isSameNumbering(const SvxNumberFormat &rN1, const SvxNumberFormat &rN2)
Definition: outliner.cxx:1742
IMPL_LINK_NOARG(Outliner, BeginMovingParagraphsHdl, MoveParagraphsInfo &, void)
Definition: outliner.cxx:1710
ParaFlag
Definition: outliner.hxx:97
OutlinerMode
Definition: outliner.hxx:563
#define OLUNDO_COLLAPSE
Definition: outliner.hxx:111
#define OLUNDO_EXPAND
Definition: outliner.hxx:110
::std::vector< ParagraphData > ParagraphDataVector
Sequence< Property > aInfos
static SfxItemSet & rSet
sal_uInt16 nType
Definition: outliner.hxx:557
tools::Rectangle aBounds
Definition: outliner.hxx:554
SvxFont aFont
Definition: outliner.hxx:553
sal_Int32 nParagraph
Definition: outliner.hxx:556
OUString aText
Definition: outliner.hxx:555
bool bVisible
Definition: outliner.hxx:558
bool HasRange() const
Definition: editdata.hxx:151
sal_uInt16 nFirstLineMaxAscent
Definition: editdata.hxx:266
@ SVX_NUM_NUMBER_NONE
Definition: svxenum.hxx:150
@ SVX_NUM_BITMAP
Definition: svxenum.hxx:153
@ SVX_NUM_CHAR_SPECIAL
Definition: svxenum.hxx:151
unsigned char sal_uInt8
sal_uInt16 sal_Unicode
sal_uInt32 sal_UCS4