1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: outliner.cxx,v $
10 * $Revision: 1.75.20.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 #include <outl_pch.hxx>
37 #include <svtools/style.hxx>
38 #include <vcl/wrkwin.hxx>
40 #include <svx/outliner.hxx>
41 #include <paralist.hxx>
42 #include <svx/outlobj.hxx>
43 #include <outleeng.hxx>
44 #include <outlundo.hxx>
45 #include <svx/eeitem.hxx>
46 #include <editstat.hxx>
47 #include <svx/scripttypeitem.hxx>
48 #include <svx/editobj.hxx>
49 #include <svtools/itemset.hxx>
50 #include <svtools/whiter.hxx>
51 #include <vcl/metric.hxx>
52 #include <svx/numitem.hxx>
53 #include <svx/adjitem.hxx>
54 #include <vcl/graph.hxx>
55 #include <vcl/gdimtf.hxx>
56 #include <vcl/metaact.hxx>
57 #include <goodies/grfmgr.hxx>
58 #include <svx/svxfont.hxx>
59 #include <svx/brshitem.hxx>
60 #include <svtools/itempool.hxx>
62 // #101498# calculate if it's RTL or not
63 #include <unicode/ubidi.h>
65 #define DEFAULT_SCALE 75
67 static const USHORT nDefStyles
= 3; // Sonderbehandlung fuer die ersten 3 Ebenen
68 static const USHORT nDefBulletIndent
= 800;
69 static const USHORT nDefBulletWidth
= 700;
70 static const USHORT pDefBulletIndents
[nDefStyles
]= { 1400, 800, 800 };
71 static const USHORT pDefBulletWidths
[nDefStyles
] = { 1000, 850, 700 };
73 USHORT
lcl_ImplGetDefBulletWidth( sal_Int16 nDepth
)
75 return ( nDepth
< nDefStyles
) ? pDefBulletWidths
[nDepth
] : nDefBulletWidth
;
78 USHORT
lcl_ImplGetDefBulletIndent( sal_Int16 nDepth
)
84 for ( sal_Int16 n
= 0; n
<= nDepth
; n
++ )
86 ( ( n
< nDefStyles
) ? pDefBulletIndents
[n
] : nDefBulletIndent
);
92 // ----------------------------------------------------------------------
94 // ----------------------------------------------------------------------
97 void Outliner::ImplCheckDepth( sal_Int16
& rnDepth
) const
99 if( rnDepth
< nMinDepth
)
101 else if( rnDepth
> nMaxDepth
)
105 Paragraph
* Outliner::Insert(const XubString
& rText
, ULONG nAbsPos
, sal_Int16 nDepth
)
107 DBG_CHKTHIS(Outliner
,0);
108 DBG_ASSERT(pParaList
->GetParagraphCount(),"Insert:No Paras");
112 ImplCheckDepth( nDepth
);
114 ULONG nParagraphCount
= pParaList
->GetParagraphCount();
115 if( nAbsPos
> nParagraphCount
)
116 nAbsPos
= nParagraphCount
;
118 if( bFirstParaIsEmpty
)
120 pPara
= pParaList
->GetParagraph( 0 );
121 if( pPara
->GetDepth() != nDepth
)
123 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
124 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
125 pPara
->SetDepth( nDepth
);
126 pHdlParagraph
= pPara
;
129 pPara
->nFlags
|= PARAFLAG_HOLDDEPTH
;
130 SetText( rText
, pPara
);
134 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
135 pEditEngine
->SetUpdateMode( FALSE
);
136 ImplBlockInsertionCallbacks( TRUE
);
137 pPara
= new Paragraph( nDepth
);
138 pParaList
->Insert( pPara
, nAbsPos
);
139 pEditEngine
->InsertParagraph( (USHORT
)nAbsPos
, String() );
140 DBG_ASSERT(pPara
==pParaList
->GetParagraph(nAbsPos
),"Insert:Failed");
141 ImplInitDepth( (USHORT
)nAbsPos
, nDepth
, FALSE
);
142 pHdlParagraph
= pPara
;
143 ParagraphInsertedHdl();
144 pPara
->nFlags
|= PARAFLAG_HOLDDEPTH
;
145 SetText( rText
, pPara
);
146 ImplBlockInsertionCallbacks( FALSE
);
147 pEditEngine
->SetUpdateMode( bUpdate
);
149 bFirstParaIsEmpty
= FALSE
;
150 DBG_ASSERT(pEditEngine
->GetParagraphCount()==pParaList
->GetParagraphCount(),"SetText failed");
155 void Outliner::ParagraphInserted( USHORT nPara
)
157 DBG_CHKTHIS(Outliner
,0);
159 if ( bBlockInsCallback
)
162 if( bPasting
|| pEditEngine
->IsInUndo() )
164 Paragraph
* pPara
= new Paragraph( -1 );
165 pParaList
->Insert( pPara
, nPara
);
166 if( pEditEngine
->IsInUndo() )
168 pPara
->nFlags
= PARAFLAG_SETBULLETTEXT
;
169 pPara
->bVisible
= TRUE
;
170 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_OUTLLEVEL
);
171 pPara
->SetDepth( rLevel
.GetValue() );
176 sal_Int16 nDepth
= -1;
177 Paragraph
* pParaBefore
= pParaList
->GetParagraph( nPara
-1 );
179 nDepth
= pParaBefore
->GetDepth();
181 Paragraph
* pPara
= new Paragraph( nDepth
);
182 pParaList
->Insert( pPara
, nPara
);
184 if( !pEditEngine
->IsInUndo() )
186 ImplCalcBulletText( nPara
, TRUE
, FALSE
);
187 pHdlParagraph
= pPara
;
188 ParagraphInsertedHdl();
193 void Outliner::ParagraphDeleted( USHORT nPara
)
195 DBG_CHKTHIS(Outliner
,0);
197 if ( bBlockInsCallback
|| ( nPara
== EE_PARA_ALL
) )
200 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
204 sal_Int16 nDepth
= pPara
->GetDepth();
206 if( !pEditEngine
->IsInUndo() )
208 pHdlParagraph
= pPara
;
209 ParagraphRemovingHdl();
212 pParaList
->Remove( nPara
);
215 if( !pEditEngine
->IsInUndo() && !bPasting
)
217 pPara
= pParaList
->GetParagraph( nPara
);
218 if ( pPara
&& ( pPara
->GetDepth() > nDepth
) )
220 ImplCalcBulletText( nPara
, TRUE
, FALSE
);
221 // naechsten auf gleicher Ebene suchen...
222 while ( pPara
&& pPara
->GetDepth() > nDepth
)
223 pPara
= pParaList
->GetParagraph( ++nPara
);
226 if ( pPara
&& ( pPara
->GetDepth() == nDepth
) )
227 ImplCalcBulletText( nPara
, TRUE
, FALSE
);
231 void Outliner::Init( USHORT nMode
)
233 nOutlinerMode
= nMode
;
237 ULONG nCtrl
= pEditEngine
->GetControlWord();
238 nCtrl
&= ~(EE_CNTRL_OUTLINER
|EE_CNTRL_OUTLINER2
);
242 switch ( ImplGetOutlinerMode() )
244 case OUTLINERMODE_TEXTOBJECT
:
245 case OUTLINERMODE_TITLEOBJECT
:
248 case OUTLINERMODE_OUTLINEOBJECT
:
249 nCtrl
|= EE_CNTRL_OUTLINER2
;
251 case OUTLINERMODE_OUTLINEVIEW
:
252 nCtrl
|= EE_CNTRL_OUTLINER
;
255 default: DBG_ERROR( "Outliner::Init - Invalid Mode!" );
258 pEditEngine
->SetControlWord( nCtrl
);
260 ImplInitDepth( 0, GetMinDepth(), FALSE
);
262 GetUndoManager().Clear();
265 void Outliner::SetMaxDepth( sal_Int16 nDepth
, BOOL bCheckParagraphs
)
267 if( nMaxDepth
!= nDepth
)
269 nMaxDepth
= Min( nDepth
, (sal_Int16
)(SVX_MAX_NUM
-1) );
271 if( bCheckParagraphs
)
273 USHORT nParagraphs
= (USHORT
)pParaList
->GetParagraphCount();
274 for ( USHORT nPara
= 0; nPara
< nParagraphs
; nPara
++ )
276 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
277 if( pPara
&& pPara
->GetDepth() > nMaxDepth
)
279 SetDepth( pPara
, nMaxDepth
);
286 sal_Int16
Outliner::GetDepth( ULONG nPara
) const
288 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
289 DBG_ASSERT( pPara
, "Outliner::GetDepth - Paragraph not found!" );
290 return pPara
? pPara
->GetDepth() : -1;
293 void Outliner::SetDepth( Paragraph
* pPara
, sal_Int16 nNewDepth
)
295 DBG_CHKTHIS(Outliner
,0);
297 ImplCheckDepth( nNewDepth
);
299 if ( nNewDepth
!= pPara
->GetDepth() )
301 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
302 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
303 pHdlParagraph
= pPara
;
305 USHORT nPara
= (USHORT
)GetAbsPos( pPara
);
306 ImplInitDepth( nPara
, nNewDepth
, TRUE
);
307 ImplCalcBulletText( nPara
, FALSE
, FALSE
);
309 if ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
)
310 ImplSetLevelDependendStyleSheet( nPara
);
316 sal_Int16
Outliner::GetNumberingStartValue( sal_uInt16 nPara
)
318 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
319 DBG_ASSERT( pPara
, "Outliner::GetNumberingStartValue - Paragraph not found!" );
320 return pPara
? pPara
->GetNumberingStartValue() : -1;
323 void Outliner::SetNumberingStartValue( sal_uInt16 nPara
, sal_Int16 nNumberingStartValue
)
325 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
326 DBG_ASSERT( pPara
, "Outliner::GetNumberingStartValue - Paragraph not found!" );
327 if( pPara
&& pPara
->GetNumberingStartValue() != nNumberingStartValue
)
329 if( IsUndoEnabled() && !IsInUndo() )
330 InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara
,
331 pPara
->GetNumberingStartValue(), nNumberingStartValue
,
332 pPara
->IsParaIsNumberingRestart(), pPara
->IsParaIsNumberingRestart() ) );
334 pPara
->SetNumberingStartValue( nNumberingStartValue
);
335 // --> OD 2009-03-10 #i100014#
336 // It is not a good idea to substract 1 from a count and cast the result
337 // to USHORT without check, if the count is 0.
338 ImplCheckParagraphs( nPara
, (USHORT
) (pParaList
->GetParagraphCount()) );
340 pEditEngine
->SetModified();
344 sal_Bool
Outliner::IsParaIsNumberingRestart( sal_uInt16 nPara
)
346 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
347 DBG_ASSERT( pPara
, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
348 return pPara
? pPara
->IsParaIsNumberingRestart() : sal_False
;
351 void Outliner::SetParaIsNumberingRestart( sal_uInt16 nPara
, sal_Bool bParaIsNumberingRestart
)
353 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
354 DBG_ASSERT( pPara
, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
355 if( pPara
&& (pPara
->IsParaIsNumberingRestart() != bParaIsNumberingRestart
) )
357 if( IsUndoEnabled() && !IsInUndo() )
358 InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara
,
359 pPara
->GetNumberingStartValue(), pPara
->GetNumberingStartValue(),
360 pPara
->IsParaIsNumberingRestart(), bParaIsNumberingRestart
) );
362 pPara
->SetParaIsNumberingRestart( bParaIsNumberingRestart
);
363 // --> OD 2009-03-10 #i100014#
364 // It is not a good idea to substract 1 from a count and cast the result
365 // to USHORT without check, if the count is 0.
366 ImplCheckParagraphs( nPara
, (USHORT
) (pParaList
->GetParagraphCount()) );
368 pEditEngine
->SetModified();
372 OutlinerParaObject
* Outliner::CreateParaObject( USHORT nStartPara
, USHORT nCount
) const
374 DBG_CHKTHIS(Outliner
,0);
376 if ( sal::static_int_cast
< ULONG
>( nStartPara
+ nCount
) >
377 pParaList
->GetParagraphCount() )
378 nCount
= sal::static_int_cast
< USHORT
>(
379 pParaList
->GetParagraphCount() - nStartPara
);
381 // When a new OutlinerParaObject is created because a paragraph is just beeing deleted,
382 // it can happen that the ParaList is not updated yet...
383 if ( ( nStartPara
+ nCount
) > pEditEngine
->GetParagraphCount() )
384 nCount
= pEditEngine
->GetParagraphCount() - nStartPara
;
389 EditTextObject
* pText
= pEditEngine
->CreateTextObject( nStartPara
, nCount
);
390 const bool bIsEditDoc(OUTLINERMODE_TEXTOBJECT
== ImplGetOutlinerMode());
391 ParagraphDataVector
aParagraphDataVector(nCount
);
392 const sal_uInt16
nLastPara(nStartPara
+ nCount
- 1);
394 for(sal_uInt16
nPara(nStartPara
); nPara
<= nLastPara
; nPara
++)
396 aParagraphDataVector
[nPara
-nStartPara
] = *GetParagraph(nPara
);
399 OutlinerParaObject
* pPObj
= new OutlinerParaObject(*pText
, aParagraphDataVector
, bIsEditDoc
);
400 pPObj
->SetOutlinerMode(GetMode());
406 void Outliner::SetText( const XubString
& rText
, Paragraph
* pPara
)
408 DBG_CHKTHIS(Outliner
,0);
409 DBG_ASSERT(pPara
,"SetText:No Para");
411 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
412 pEditEngine
->SetUpdateMode( FALSE
);
413 ImplBlockInsertionCallbacks( TRUE
);
415 USHORT nPara
= (USHORT
)pParaList
->GetAbsPos( pPara
);
419 pEditEngine
->SetText( nPara
, rText
);
420 ImplInitDepth( nPara
, pPara
->GetDepth(), FALSE
);
424 XubString
aText( rText
);
425 aText
.ConvertLineEnd( LINEEND_LF
);
427 if( aText
.GetChar( aText
.Len()-1 ) == '\x0A' )
428 aText
.Erase( aText
.Len()-1, 1 ); // letzten Umbruch loeschen
430 USHORT nCount
= aText
.GetTokenCount( '\x0A' );
432 USHORT nInsPos
= nPara
+1;
433 while( nCount
> nPos
)
435 XubString aStr
= aText
.GetToken( nPos
, '\x0A' );
440 pPara
= new Paragraph( -1 );
444 nCurDepth
= pPara
->GetDepth();
446 // Im Outliner-Modus die Tabulatoren filtern und die
447 // Einrueckung ueber ein LRSpaceItem einstellen
448 // Im EditEngine-Modus ueber Maltes Tabulatoren einruecken
449 if( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
) ||
450 ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW
) )
454 while ( ( nTabs
< aStr
.Len() ) && ( aStr
.GetChar( nTabs
) == '\t' ) )
457 aStr
.Erase( 0, nTabs
);
459 // Tiefe beibehalten ? (siehe Outliner::Insert)
460 if( !(pPara
->nFlags
& PARAFLAG_HOLDDEPTH
) )
463 ImplCheckDepth( nCurDepth
);
464 pPara
->SetDepth( nCurDepth
);
465 pPara
->nFlags
&= (~PARAFLAG_HOLDDEPTH
);
468 if( nPos
) // nicht mit dem ersten Absatz
470 pParaList
->Insert( pPara
, nInsPos
);
471 pEditEngine
->InsertParagraph( nInsPos
, aStr
);
472 pHdlParagraph
= pPara
;
473 ParagraphInsertedHdl();
478 pEditEngine
->SetText( nInsPos
, aStr
);
480 ImplInitDepth( nInsPos
, nCurDepth
, FALSE
);
486 DBG_ASSERT(pParaList
->GetParagraphCount()==pEditEngine
->GetParagraphCount(),"SetText failed!");
487 bFirstParaIsEmpty
= FALSE
;
488 ImplBlockInsertionCallbacks( FALSE
);
489 pEditEngine
->SetUpdateMode( bUpdate
);
492 // pView == 0 -> Tabulatoren nicht beachten
494 bool Outliner::ImpConvertEdtToOut( sal_uInt32 nPara
,EditView
* pView
)
496 DBG_CHKTHIS(Outliner
,0);
498 bool bConverted
= false;
502 // const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nPara );
503 // bool bAlreadyOutliner = rAttrs.GetItemState( EE_PARA_OUTLLRSPACE ) == SFX_ITEM_ON ? true : false;
506 XubString
aHeading_US( RTL_CONSTASCII_USTRINGPARAM( "heading" ) );
507 XubString
aNumber_US( RTL_CONSTASCII_USTRINGPARAM( "Numbering" ) );
509 XubString
aStr( pEditEngine
->GetText( (USHORT
)nPara
) );
510 xub_Unicode
* pPtr
= (xub_Unicode
*)aStr
.GetBuffer();
512 USHORT nHeadingNumberStart
= 0;
513 USHORT nNumberingNumberStart
= 0;
514 SfxStyleSheet
* pStyle
= pEditEngine
->GetStyleSheet( (USHORT
)nPara
);
517 aName
= pStyle
->GetName();
519 if ( ( nSearch
= aName
.Search( aHeading_US
) ) != STRING_NOTFOUND
)
520 nHeadingNumberStart
= nSearch
+ aHeading_US
.Len();
521 else if ( ( nSearch
= aName
.Search( aNumber_US
) ) != STRING_NOTFOUND
)
522 nNumberingNumberStart
= nSearch
+ aNumber_US
.Len();
525 if ( nHeadingNumberStart
|| nNumberingNumberStart
)
527 // PowerPoint-Import ?
528 if( nHeadingNumberStart
&& ( aStr
.Len() >= 2 ) &&
529 ( pPtr
[0] != '\t' ) && ( pPtr
[1] == '\t' ) )
532 aDelSel
= ESelection( (USHORT
)nPara
, 0, (USHORT
)nPara
, 2 );
535 USHORT nPos
= nHeadingNumberStart
? nHeadingNumberStart
: nNumberingNumberStart
;
536 String aLevel
= aName
.Copy( nPos
);
537 aLevel
.EraseLeadingChars( ' ' );
538 nTabs
= sal::static_int_cast
< USHORT
>(aLevel
.ToInt32());
540 nTabs
--; // ebene 0 = "heading 1"
545 // Fuehrende Tabulatoren filtern
546 while( *pPtr
== '\t' )
551 // Tabulatoren aus dem Text entfernen
553 aDelSel
= ESelection( (USHORT
)nPara
, 0, (USHORT
)nPara
, nTabs
);
556 if ( aDelSel
.HasRange() )
560 pView
->SetSelection( aDelSel
);
561 pView
->DeleteSelected();
564 pEditEngine
->QuickDelete( aDelSel
);
567 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( sal::static_int_cast
< sal_uInt16
>(nPara
), EE_PARA_OUTLLEVEL
);
568 sal_Int16 nOutlLevel
= rLevel
.GetValue();
570 ImplCheckDepth( nOutlLevel
);
571 ImplInitDepth( sal::static_int_cast
< sal_uInt16
>(nPara
), nOutlLevel
, FALSE
);
576 void Outliner::SetText( const OutlinerParaObject
& rPObj
)
578 DBG_CHKTHIS(Outliner
,0);
580 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
581 pEditEngine
->SetUpdateMode( FALSE
);
583 BOOL bUndo
= pEditEngine
->IsUndoEnabled();
586 Init( rPObj
.GetOutlinerMode() );
588 ImplBlockInsertionCallbacks( TRUE
);
589 pEditEngine
->SetText(rPObj
.GetTextObject());
590 if( rPObj
.Count() != pEditEngine
->GetParagraphCount() )
595 bFirstParaIsEmpty
= FALSE
;
597 pParaList
->Clear( TRUE
);
598 for( USHORT nCurPara
= 0; nCurPara
< rPObj
.Count(); nCurPara
++ )
600 Paragraph
* pPara
= new Paragraph( rPObj
.GetParagraphData(nCurPara
));
601 ImplCheckDepth( pPara
->nDepth
);
603 pParaList
->Insert( pPara
, LIST_APPEND
);
604 ImplCheckNumBulletItem( nCurPara
);
607 // --> OD 2009-03-10 #i100014#
608 // It is not a good idea to substract 1 from a count and cast the result
609 // to USHORT without check, if the count is 0.
610 ImplCheckParagraphs( 0, (USHORT
) (pParaList
->GetParagraphCount()) );
614 ImplBlockInsertionCallbacks( FALSE
);
615 pEditEngine
->SetUpdateMode( bUpdate
);
617 DBG_ASSERT( pParaList
->GetParagraphCount()==rPObj
.Count(),"SetText failed");
618 DBG_ASSERT( pEditEngine
->GetParagraphCount()==rPObj
.Count(),"SetText failed");
621 void Outliner::AddText( const OutlinerParaObject
& rPObj
)
623 DBG_CHKTHIS(Outliner
,0);
626 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
627 pEditEngine
->SetUpdateMode( FALSE
);
629 ImplBlockInsertionCallbacks( TRUE
);
631 if( bFirstParaIsEmpty
)
633 pParaList
->Clear( TRUE
);
634 pEditEngine
->SetText(rPObj
.GetTextObject());
639 nPara
= pParaList
->GetParagraphCount();
640 pEditEngine
->InsertParagraph( EE_PARA_APPEND
, rPObj
.GetTextObject() );
642 bFirstParaIsEmpty
= FALSE
;
644 for( USHORT n
= 0; n
< rPObj
.Count(); n
++ )
646 pPara
= new Paragraph( rPObj
.GetParagraphData(n
) );
647 pParaList
->Insert( pPara
, LIST_APPEND
);
648 USHORT nP
= sal::static_int_cast
< USHORT
>(nPara
+n
);
649 DBG_ASSERT(pParaList
->GetAbsPos(pPara
)==nP
,"AddText:Out of sync");
650 ImplInitDepth( nP
, pPara
->GetDepth(), FALSE
);
652 DBG_ASSERT( pEditEngine
->GetParagraphCount()==pParaList
->GetParagraphCount(), "SetText: OutOfSync" );
654 // --> OD 2009-03-10 #i100014#
655 // It is not a good idea to substract 1 from a count and cast the result
656 // to USHORT without check, if the count is 0.
657 ImplCheckParagraphs( (USHORT
)nPara
, (USHORT
) (pParaList
->GetParagraphCount()) );
660 ImplBlockInsertionCallbacks( FALSE
);
661 pEditEngine
->SetUpdateMode( bUpdate
);
664 void __EXPORT
Outliner::FieldClicked( const SvxFieldItem
& rField
, USHORT nPara
, USHORT nPos
)
666 DBG_CHKTHIS(Outliner
,0);
668 if ( aFieldClickedHdl
.IsSet() )
670 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
671 aFldInfo
.SetSimpleClick( TRUE
);
672 aFieldClickedHdl
.Call( &aFldInfo
);
677 void __EXPORT
Outliner::FieldSelected( const SvxFieldItem
& rField
, USHORT nPara
, USHORT nPos
)
679 DBG_CHKTHIS(Outliner
,0);
680 if ( !aFieldClickedHdl
.IsSet() )
683 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
684 aFldInfo
.SetSimpleClick( FALSE
);
685 aFieldClickedHdl
.Call( &aFldInfo
);
689 XubString __EXPORT
Outliner::CalcFieldValue( const SvxFieldItem
& rField
, USHORT nPara
, USHORT nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
691 DBG_CHKTHIS(Outliner
,0);
692 if ( !aCalcFieldValueHdl
.IsSet() )
693 return String( ' ' );
695 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
696 // Die FldColor ist mit COL_LIGHTGRAY voreingestellt.
698 aFldInfo
.SetFldColor( *rpFldColor
);
700 aCalcFieldValueHdl
.Call( &aFldInfo
);
701 if ( aFldInfo
.GetTxtColor() )
704 rpTxtColor
= new Color( *aFldInfo
.GetTxtColor() );
708 rpFldColor
= aFldInfo
.GetFldColor() ? new Color( *aFldInfo
.GetFldColor() ) : 0;
710 return aFldInfo
.GetRepresentation();
713 void Outliner::SetStyleSheet( ULONG nPara
, SfxStyleSheet
* pStyle
)
715 DBG_CHKTHIS(Outliner
,0);
716 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
719 pEditEngine
->SetStyleSheet( (USHORT
)nPara
, pStyle
);
720 pPara
->nFlags
|= PARAFLAG_SETBULLETTEXT
;
721 ImplCheckNumBulletItem( (USHORT
) nPara
);
725 void Outliner::SetVisible( Paragraph
* pPara
, BOOL bVisible
)
727 DBG_CHKTHIS(Outliner
,0);
728 DBG_ASSERT( pPara
, "SetVisible: pPara = NULL" );
732 pPara
->bVisible
= bVisible
;
733 ULONG nPara
= pParaList
->GetAbsPos( pPara
);
734 pEditEngine
->ShowParagraph( (USHORT
)nPara
, bVisible
);
738 void Outliner::ImplCheckNumBulletItem( USHORT nPara
)
740 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
742 pPara
->aBulSize
.Width() = -1;
745 void Outliner::ImplSetLevelDependendStyleSheet( USHORT nPara
, SfxStyleSheet
* pLevelStyle
)
747 DBG_CHKTHIS(Outliner
,0);
749 DBG_ASSERT( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
) || ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW
), "SetLevelDependendStyleSheet: Wrong Mode!" );
751 SfxStyleSheet
* pStyle
= pLevelStyle
;
753 pStyle
= GetStyleSheet( nPara
);
757 sal_Int16 nDepth
= GetDepth( nPara
);
761 String
aNewStyleSheetName( pStyle
->GetName() );
762 aNewStyleSheetName
.Erase( aNewStyleSheetName
.Len()-1, 1 );
763 aNewStyleSheetName
+= String::CreateFromInt32( nDepth
+1 );
764 SfxStyleSheet
* pNewStyle
= (SfxStyleSheet
*)GetStyleSheetPool()->Find( aNewStyleSheetName
, pStyle
->GetFamily() );
765 DBG_ASSERT( pNewStyle
, "AutoStyleSheetName - Style not found!" );
766 if ( pNewStyle
&& ( pNewStyle
!= GetStyleSheet( nPara
) ) )
768 SfxItemSet
aOldAttrs( GetParaAttribs( nPara
) );
769 SetStyleSheet( nPara
, pNewStyle
);
770 if ( aOldAttrs
.GetItemState( EE_PARA_NUMBULLET
) == SFX_ITEM_ON
)
772 SfxItemSet
aAttrs( GetParaAttribs( nPara
) );
773 aAttrs
.Put( aOldAttrs
.Get( EE_PARA_NUMBULLET
) );
774 SetParaAttribs( nPara
, aAttrs
);
780 void Outliner::ImplInitDepth( USHORT nPara
, sal_Int16 nDepth
, BOOL bCreateUndo
, BOOL bUndoAction
)
782 DBG_CHKTHIS(Outliner
,0);
784 DBG_ASSERT( ( nDepth
>= nMinDepth
) && ( nDepth
<= nMaxDepth
), "ImplInitDepth - Depth is invalid!" );
786 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
789 sal_Int16 nOldDepth
= pPara
->GetDepth();
790 pPara
->SetDepth( nDepth
);
792 // Bei IsInUndo brauchen Attribute und Style nicht eingestellt werden,
793 // dort werden die alten Werte durch die EditEngine restauriert.
797 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
798 pEditEngine
->SetUpdateMode( FALSE
);
800 BOOL bUndo
= bCreateUndo
&& IsUndoEnabled();
801 if ( bUndo
&& bUndoAction
)
802 UndoActionStart( OLUNDO_DEPTH
);
804 SfxItemSet
aAttrs( pEditEngine
->GetParaAttribs( nPara
) );
805 aAttrs
.Put( SfxInt16Item( EE_PARA_OUTLLEVEL
, nDepth
) );
806 pEditEngine
->SetParaAttribs( nPara
, aAttrs
);
807 ImplCheckNumBulletItem( nPara
);
808 ImplCalcBulletText( nPara
, FALSE
, FALSE
);
812 InsertUndo( new OutlinerUndoChangeDepth( this, nPara
, nOldDepth
, nDepth
) );
814 UndoActionEnd( OLUNDO_DEPTH
);
817 pEditEngine
->SetUpdateMode( bUpdate
);
821 void Outliner::SetParaAttribs( USHORT nPara
, const SfxItemSet
& rSet
)
823 DBG_CHKTHIS(Outliner
,0);
825 pEditEngine
->SetParaAttribs( nPara
, rSet
);
828 BOOL
Outliner::Expand( Paragraph
* pPara
)
830 DBG_CHKTHIS(Outliner
,0);
832 if ( pParaList
->HasHiddenChilds( pPara
) )
834 OLUndoExpand
* pUndo
= 0;
835 BOOL bUndo
= IsUndoEnabled() && !IsInUndo();
838 UndoActionStart( OLUNDO_EXPAND
);
839 pUndo
= new OLUndoExpand( this, OLUNDO_EXPAND
);
841 pUndo
->nCount
= (USHORT
)pParaList
->GetAbsPos( pPara
);
843 pHdlParagraph
= pPara
;
845 pParaList
->Expand( pPara
);
847 InvalidateBullet( pPara
, pParaList
->GetAbsPos(pPara
) );
851 UndoActionEnd( OLUNDO_EXPAND
);
859 BOOL
Outliner::Collapse( Paragraph
* pPara
)
861 DBG_CHKTHIS(Outliner
,0);
862 if ( pParaList
->HasVisibleChilds( pPara
) ) // expandiert
864 OLUndoExpand
* pUndo
= 0;
867 if( !IsInUndo() && IsUndoEnabled() )
871 UndoActionStart( OLUNDO_COLLAPSE
);
872 pUndo
= new OLUndoExpand( this, OLUNDO_COLLAPSE
);
874 pUndo
->nCount
= (USHORT
)pParaList
->GetAbsPos( pPara
);
877 pHdlParagraph
= pPara
;
878 bIsExpanding
= FALSE
;
879 pParaList
->Collapse( pPara
);
881 InvalidateBullet( pPara
, pParaList
->GetAbsPos(pPara
) );
885 UndoActionEnd( OLUNDO_COLLAPSE
);
893 Font
Outliner::ImpCalcBulletFont( USHORT nPara
) const
895 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
896 DBG_ASSERT( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) && ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
), "ImpCalcBulletFont: Missing or BitmapBullet!" );
898 Font aStdFont
; //#107508#
899 if ( !pEditEngine
->IsFlatMode() )
901 ESelection
aSel( nPara
, 0, nPara
, 0 );
902 aStdFont
= EditEngine::CreateFontFromItemSet( pEditEngine
->GetAttribs( aSel
), GetScriptType( aSel
) );
906 aStdFont
= pEditEngine
->GetStandardFont( nPara
);
910 if ( pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
912 aBulletFont
= *pFmt
->GetBulletFont();
916 aBulletFont
= aStdFont
;
917 aBulletFont
.SetUnderline( UNDERLINE_NONE
);
918 aBulletFont
.SetOverline( UNDERLINE_NONE
);
919 aBulletFont
.SetStrikeout( STRIKEOUT_NONE
);
920 aBulletFont
.SetEmphasisMark( EMPHASISMARK_NONE
);
921 aBulletFont
.SetRelief( RELIEF_NONE
);
924 // #107508# Use original scale...
925 USHORT nStretchX
, nStretchY
;
926 const_cast<Outliner
*>(this)->GetGlobalCharStretching(nStretchX
, nStretchY
);
928 USHORT nScale
= pFmt
->GetBulletRelSize() * nStretchY
/ 100;
929 ULONG nScaledLineHeight
= aStdFont
.GetSize().Height();
930 nScaledLineHeight
*= nScale
*10;
931 nScaledLineHeight
/= 1000;
933 aBulletFont
.SetAlign( ALIGN_BOTTOM
);
934 aBulletFont
.SetSize( Size( 0, nScaledLineHeight
) );
935 BOOL bVertical
= IsVertical();
936 aBulletFont
.SetVertical( bVertical
);
937 aBulletFont
.SetOrientation( bVertical
? 2700 : 0 );
939 Color
aColor( COL_AUTO
);
940 if( !pEditEngine
->IsFlatMode() && !( pEditEngine
->GetControlWord() & EE_CNTRL_NOCOLORS
) )
942 aColor
= pFmt
->GetBulletColor();
945 if ( ( aColor
== COL_AUTO
) || ( IsForceAutoColor() ) )
946 aColor
= pEditEngine
->GetAutoColor();
948 aBulletFont
.SetColor( aColor
);
952 void Outliner::PaintBullet( USHORT nPara
, const Point
& rStartPos
,
953 const Point
& rOrigin
, short nOrientation
, OutputDevice
* pOutDev
)
955 DBG_CHKTHIS(Outliner
,0);
957 bool bDrawBullet
= false;
960 const SfxBoolItem
& rBulletState
= (const SfxBoolItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_BULLETSTATE
);
961 bDrawBullet
= rBulletState
.GetValue() ? true : false;
964 if ( ImplHasBullet( nPara
) && bDrawBullet
)
966 BOOL bVertical
= IsVertical();
968 BOOL bRightToLeftPara
= pEditEngine
->IsRightToLeft( nPara
);
970 Rectangle
aBulletArea( ImpCalcBulletArea( nPara
, TRUE
, FALSE
) );
971 USHORT nStretchX
, nStretchY
;
972 GetGlobalCharStretching(nStretchX
, nStretchY
);
973 aBulletArea
= Rectangle( Point(aBulletArea
.Left()*nStretchX
/100,
975 Size(aBulletArea
.GetWidth()*nStretchX
/100,
976 aBulletArea
.GetHeight()) );
978 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
979 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
980 if ( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
) )
982 if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
984 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
985 // #2338# Use base line
986 BOOL bSymbol
= pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
;
987 aBulletFont
.SetAlign( bSymbol
? ALIGN_BOTTOM
: ALIGN_BASELINE
);
988 Font aOldFont
= pOutDev
->GetFont();
989 pOutDev
->SetFont( aBulletFont
);
991 ParagraphInfos aParaInfos
= pEditEngine
->GetParagraphInfos( nPara
);
995 // aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
996 aTextPos
.Y() = rStartPos
.Y() + ( bSymbol
? aBulletArea
.Bottom() : aParaInfos
.nFirstLineMaxAscent
);
997 if ( !bRightToLeftPara
)
998 aTextPos
.X() = rStartPos
.X() + aBulletArea
.Left();
1000 aTextPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Left();
1004 // aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
1005 aTextPos
.X() = rStartPos
.X() - ( bSymbol
? aBulletArea
.Bottom() : aParaInfos
.nFirstLineMaxAscent
);
1006 aTextPos
.Y() = rStartPos
.Y() + aBulletArea
.Left();
1011 // Sowohl TopLeft als auch BottomLeft nicht ganz richtig, da
1012 // in EditEngine BaseLine...
1013 double nRealOrientation
= nOrientation
*F_PI1800
;
1014 double nCos
= cos( nRealOrientation
);
1015 double nSin
= sin( nRealOrientation
);
1018 aTextPos
-= rOrigin
;
1020 aRotatedPos
.X()=(long) (nCos
*aTextPos
.X() + nSin
*aTextPos
.Y());
1021 aRotatedPos
.Y()=(long) - (nSin
*aTextPos
.X() - nCos
*aTextPos
.Y());
1022 aTextPos
= aRotatedPos
;
1024 aTextPos
+= rOrigin
;
1025 Font
aRotatedFont( aBulletFont
);
1026 aRotatedFont
.SetOrientation( nOrientation
);
1027 pOutDev
->SetFont( aRotatedFont
);
1030 // #105803# VCL will care for brackets and so on...
1031 ULONG nLayoutMode
= pOutDev
->GetLayoutMode();
1032 nLayoutMode
&= ~(TEXT_LAYOUT_BIDI_RTL
|TEXT_LAYOUT_COMPLEX_DISABLED
|TEXT_LAYOUT_BIDI_STRONG
);
1033 if ( bRightToLeftPara
)
1034 nLayoutMode
|= TEXT_LAYOUT_BIDI_RTL
;
1035 pOutDev
->SetLayoutMode( nLayoutMode
);
1037 if(bStrippingPortions
)
1039 const Font
aSvxFont(pOutDev
->GetFont());
1040 sal_Int32
* pBuf
= new sal_Int32
[ pPara
->GetText().Len() ];
1041 pOutDev
->GetTextArray( pPara
->GetText(), pBuf
);
1045 // aTextPos is Bottom, go to Baseline
1046 FontMetric
aMetric(pOutDev
->GetFontMetric());
1047 aTextPos
.Y() -= aMetric
.GetDescent();
1050 DrawingText(aTextPos
, pPara
->GetText(), 0, pPara
->GetText().Len(), pBuf
,
1051 aSvxFont
, nPara
, 0xFFFF, 0xFF, 0, 0, false, false, true, 0, Color(), Color());
1057 pOutDev
->DrawText( aTextPos
, pPara
->GetText() );
1060 pOutDev
->SetFont( aOldFont
);
1064 if ( pFmt
->GetBrush()->GetGraphicObject() )
1069 aBulletPos
.Y() = rStartPos
.Y() + aBulletArea
.Top();
1070 if ( !bRightToLeftPara
)
1071 aBulletPos
.X() = rStartPos
.X() + aBulletArea
.Left();
1073 aBulletPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Right();
1077 aBulletPos
.X() = rStartPos
.X() - aBulletArea
.Bottom();
1078 aBulletPos
.Y() = rStartPos
.Y() + aBulletArea
.Left();
1081 if(bStrippingPortions
)
1083 if(aDrawBulletHdl
.IsSet())
1085 // call something analog to aDrawPortionHdl (if set) and feed it something
1086 // analog to DrawPortionInfo...
1087 // created aDrawBulletHdl, Set/GetDrawBulletHdl.
1088 // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
1089 DrawBulletInfo
aDrawBulletInfo(
1090 *pFmt
->GetBrush()->GetGraphicObject(),
1094 aDrawBulletHdl
.Call(&aDrawBulletInfo
);
1099 // MT: Remove CAST when KA made the Draw-Method const
1100 ((GraphicObject
*)pFmt
->GetBrush()->GetGraphicObject())->Draw( pOutDev
, aBulletPos
, pPara
->aBulSize
);
1106 // Bei zusammengeklappten Absaetzen einen Strich vor den Text malen.
1107 if( pParaList
->HasChilds(pPara
) && !pParaList
->HasVisibleChilds(pPara
) &&
1108 !bStrippingPortions
&& !nOrientation
)
1110 long nWidth
= pOutDev
->PixelToLogic( Size( 10, 0 ) ).Width();
1112 Point aStartPos
, aEndPos
;
1115 aStartPos
.Y() = rStartPos
.Y() + aBulletArea
.Bottom();
1116 if ( !bRightToLeftPara
)
1117 aStartPos
.X() = rStartPos
.X() + aBulletArea
.Right();
1119 aStartPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Left();
1120 aEndPos
= aStartPos
;
1121 aEndPos
.X() += nWidth
;
1125 aStartPos
.X() = rStartPos
.X() - aBulletArea
.Bottom();
1126 aStartPos
.Y() = rStartPos
.Y() + aBulletArea
.Right();
1127 aEndPos
= aStartPos
;
1128 aEndPos
.Y() += nWidth
;
1131 const Color
& rOldLineColor
= pOutDev
->GetLineColor();
1132 pOutDev
->SetLineColor( Color( COL_BLACK
) );
1133 pOutDev
->DrawLine( aStartPos
, aEndPos
);
1134 pOutDev
->SetLineColor( rOldLineColor
);
1139 void Outliner::InvalidateBullet( Paragraph
* /*pPara*/, ULONG nPara
)
1141 DBG_CHKTHIS(Outliner
,0);
1143 long nLineHeight
= (long)pEditEngine
->GetLineHeight((USHORT
)nPara
);
1144 OutlinerView
* pView
= aViewList
.First();
1147 Point
aPos( pView
->pEditView
->GetWindowPosTopLeft((USHORT
)nPara
) );
1148 Rectangle
aRect( pView
->GetOutputArea() );
1149 aRect
.Right() = aPos
.X();
1150 aRect
.Top() = aPos
.Y();
1151 aRect
.Bottom() = aPos
.Y();
1152 aRect
.Bottom() += nLineHeight
;
1154 pView
->GetWindow()->Invalidate( aRect
);
1155 pView
= aViewList
.Next();
1159 ULONG
Outliner::Read( SvStream
& rInput
, const String
& rBaseURL
, USHORT eFormat
, SvKeyValueIterator
* pHTTPHeaderAttrs
)
1161 DBG_CHKTHIS(Outliner
,0);
1163 BOOL bOldUndo
= pEditEngine
->IsUndoEnabled();
1164 EnableUndo( FALSE
);
1166 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
1167 pEditEngine
->SetUpdateMode( FALSE
);
1171 ImplBlockInsertionCallbacks( TRUE
);
1172 ULONG nRet
= pEditEngine
->Read( rInput
, rBaseURL
, (EETextFormat
)eFormat
, pHTTPHeaderAttrs
);
1174 bFirstParaIsEmpty
= FALSE
;
1176 USHORT nParas
= pEditEngine
->GetParagraphCount();
1177 pParaList
->Clear( TRUE
);
1179 for ( n
= 0; n
< nParas
; n
++ )
1181 Paragraph
* pPara
= new Paragraph( 0 );
1182 pParaList
->Insert( pPara
, LIST_APPEND
);
1184 if ( eFormat
== EE_FORMAT_BIN
)
1186 const SfxItemSet
& rAttrs
= pEditEngine
->GetParaAttribs( n
);
1187 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) rAttrs
.Get( EE_PARA_OUTLLEVEL
);
1188 sal_Int16 nDepth
= rLevel
.GetValue();
1189 ImplInitDepth( n
, nDepth
, FALSE
);
1193 if ( eFormat
!= EE_FORMAT_BIN
)
1195 ImpFilterIndents( 0, nParas
-1 );
1198 ImplBlockInsertionCallbacks( FALSE
);
1199 pEditEngine
->SetUpdateMode( bUpdate
);
1200 EnableUndo( bOldUndo
);
1206 void Outliner::ImpFilterIndents( ULONG nFirstPara
, ULONG nLastPara
)
1208 DBG_CHKTHIS(Outliner
,0);
1210 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
1211 pEditEngine
->SetUpdateMode( FALSE
);
1213 Paragraph
* pLastConverted
= NULL
;
1214 for( ULONG nPara
= nFirstPara
; nPara
<= nLastPara
; nPara
++ )
1216 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1219 if( ImpConvertEdtToOut( nPara
) )
1221 pLastConverted
= pPara
;
1223 else if ( pLastConverted
)
1225 // Normale Absaetze unter der Ueberschrift anordnen...
1226 pPara
->SetDepth( pLastConverted
->GetDepth() );
1229 ImplInitDepth( (USHORT
)nPara
, pPara
->GetDepth(), FALSE
);
1233 pEditEngine
->SetUpdateMode( bUpdate
);
1236 SfxUndoManager
& Outliner::GetUndoManager()
1238 DBG_CHKTHIS(Outliner
,0);
1239 return pEditEngine
->GetUndoManager();
1242 void Outliner::ImpTextPasted( ULONG nStartPara
, USHORT nCount
)
1244 DBG_CHKTHIS(Outliner
,0);
1246 BOOL bUpdate
= pEditEngine
->GetUpdateMode();
1247 pEditEngine
->SetUpdateMode( FALSE
);
1249 const ULONG nStart
= nStartPara
;
1251 Paragraph
* pPara
= pParaList
->GetParagraph( nStartPara
);
1252 // Paragraph* pLastConverted = NULL;
1253 // bool bFirst = true;
1255 while( nCount
&& pPara
)
1257 if( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT
)
1259 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
1260 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
1262 ImpConvertEdtToOut( nStartPara
);
1264 pHdlParagraph
= pPara
;
1266 if( nStartPara
== nStart
)
1268 // the existing paragraph has changed depth or flags
1269 if( (pPara
->GetDepth() != nDepthChangedHdlPrevDepth
) || (pPara
->nFlags
!= mnDepthChangeHdlPrevFlags
) )
1273 else // EditEngine-Modus
1275 sal_Int16 nDepth
= -1;
1276 const SfxItemSet
& rAttrs
= pEditEngine
->GetParaAttribs( (USHORT
)nStartPara
);
1277 if ( rAttrs
.GetItemState( EE_PARA_OUTLLEVEL
) == SFX_ITEM_ON
)
1279 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) rAttrs
.Get( EE_PARA_OUTLLEVEL
);
1280 nDepth
= rLevel
.GetValue();
1282 if ( nDepth
!= GetDepth( nStartPara
) )
1283 ImplInitDepth( (USHORT
)nStartPara
, nDepth
, FALSE
);
1288 pPara
= pParaList
->GetParagraph( nStartPara
);
1291 pEditEngine
->SetUpdateMode( bUpdate
);
1293 DBG_ASSERT(pParaList
->GetParagraphCount()==pEditEngine
->GetParagraphCount(),"ImpTextPasted failed");
1296 long Outliner::IndentingPagesHdl( OutlinerView
* pView
)
1298 DBG_CHKTHIS(Outliner
,0);
1299 if( !aIndentingPagesHdl
.IsSet() )
1301 return aIndentingPagesHdl
.Call( pView
);
1304 BOOL
Outliner::ImpCanIndentSelectedPages( OutlinerView
* pCurView
)
1306 DBG_CHKTHIS(Outliner
,0);
1307 // Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
1308 // schon eingestellt sein
1310 // Wenn der erste Absatz auf Ebene 0 liegt darf er auf keinen Fall
1311 // eingerueckt werden, evtl folgen aber weitere auf Ebene 0.
1312 if ( ( mnFirstSelPage
== 0 ) && ( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT
) )
1314 if ( nDepthChangedHdlPrevDepth
== 1 ) // ist die einzige Seite
1317 pCurView
->ImpCalcSelectedPages( FALSE
); // ohne die erste
1319 return (BOOL
)IndentingPagesHdl( pCurView
);
1323 BOOL
Outliner::ImpCanDeleteSelectedPages( OutlinerView
* pCurView
)
1325 DBG_CHKTHIS(Outliner
,0);
1326 // Die selektierten Seiten muessen vorher durch ImpCalcSelectedPages
1327 // schon eingestellt sein
1328 return (BOOL
)RemovingPagesHdl( pCurView
);
1331 Outliner::Outliner( SfxItemPool
* pPool
, USHORT nMode
)
1334 DBG_CTOR( Outliner
, 0 );
1336 bStrippingPortions
= FALSE
;
1340 bBlockInsCallback
= FALSE
;
1344 pParaList
= new ParagraphList
;
1345 pParaList
->SetVisibleStateChangedHdl( LINK( this, Outliner
, ParaVisibleStateChangedHdl
) );
1346 Paragraph
* pPara
= new Paragraph( 0 );
1347 pParaList
->Insert( pPara
, LIST_APPEND
);
1348 bFirstParaIsEmpty
= TRUE
;
1350 pEditEngine
= new OutlinerEditEng( this, pPool
);
1351 pEditEngine
->SetBeginMovingParagraphsHdl( LINK( this, Outliner
, BeginMovingParagraphsHdl
) );
1352 pEditEngine
->SetEndMovingParagraphsHdl( LINK( this, Outliner
, EndMovingParagraphsHdl
) );
1353 pEditEngine
->SetBeginPasteOrDropHdl( LINK( this, Outliner
, BeginPasteOrDropHdl
) );
1354 pEditEngine
->SetEndPasteOrDropHdl( LINK( this, Outliner
, EndPasteOrDropHdl
) );
1359 Outliner::~Outliner()
1361 DBG_DTOR(Outliner
,0);
1363 pParaList
->Clear( TRUE
);
1368 ULONG
Outliner::InsertView( OutlinerView
* pView
, ULONG nIndex
)
1370 DBG_CHKTHIS(Outliner
,0);
1372 aViewList
.Insert( pView
, nIndex
);
1373 pEditEngine
->InsertView( pView
->pEditView
, (USHORT
)nIndex
);
1374 return aViewList
.GetPos( pView
);
1377 OutlinerView
* Outliner::RemoveView( OutlinerView
* pView
)
1379 DBG_CHKTHIS(Outliner
,0);
1381 ULONG nPos
= aViewList
.GetPos( pView
);
1382 if ( nPos
!= LIST_ENTRY_NOTFOUND
)
1384 pView
->pEditView
->HideCursor(); // HACK wg. BugId 10006
1385 pEditEngine
->RemoveView( pView
->pEditView
);
1386 aViewList
.Remove( nPos
);
1388 return NULL
; // MT: return ueberfluessig
1391 OutlinerView
* Outliner::RemoveView( ULONG nIndex
)
1393 DBG_CHKTHIS(Outliner
,0);
1395 EditView
* pEditView
= pEditEngine
->GetView( (USHORT
)nIndex
);
1396 pEditView
->HideCursor(); // HACK wg. BugId 10006
1398 pEditEngine
->RemoveView( (USHORT
)nIndex
);
1399 aViewList
.Remove( nIndex
);
1400 return NULL
; // MT: return ueberfluessig
1404 OutlinerView
* Outliner::GetView( ULONG nIndex
) const
1406 DBG_CHKTHIS(Outliner
,0);
1407 return aViewList
.GetObject( nIndex
);
1410 ULONG
Outliner::GetViewCount() const
1412 DBG_CHKTHIS(Outliner
,0);
1413 return aViewList
.Count();
1416 void Outliner::ParagraphInsertedHdl()
1418 DBG_CHKTHIS(Outliner
,0);
1420 aParaInsertedHdl
.Call( this );
1424 void Outliner::ParagraphRemovingHdl()
1426 DBG_CHKTHIS(Outliner
,0);
1428 aParaRemovingHdl
.Call( this );
1432 void Outliner::DepthChangedHdl()
1434 DBG_CHKTHIS(Outliner
,0);
1436 aDepthChangedHdl
.Call( this );
1440 ULONG
Outliner::GetAbsPos( Paragraph
* pPara
)
1442 DBG_CHKTHIS(Outliner
,0);
1443 DBG_ASSERT(pPara
,"GetAbsPos:No Para");
1444 return pParaList
->GetAbsPos( pPara
);
1447 ULONG
Outliner::GetParagraphCount() const
1449 DBG_CHKTHIS(Outliner
,0);
1450 return pParaList
->GetParagraphCount();
1453 Paragraph
* Outliner::GetParagraph( ULONG nAbsPos
) const
1455 DBG_CHKTHIS(Outliner
,0);
1456 return pParaList
->GetParagraph( nAbsPos
);
1459 BOOL
Outliner::HasChilds( Paragraph
* pParagraph
) const
1461 DBG_CHKTHIS(Outliner
,0);
1462 return pParaList
->HasChilds( pParagraph
);
1465 BOOL
Outliner::ImplHasBullet( USHORT nPara
) const
1467 return GetNumberFormat(nPara
) != 0;
1470 const SvxNumberFormat
* Outliner::GetNumberFormat( USHORT nPara
) const
1472 const SvxNumberFormat
* pFmt
= NULL
;
1474 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1478 sal_Int16 nDepth
= pPara
? pPara
->GetDepth() : -1;
1482 const SvxNumBulletItem
& rNumBullet
= (const SvxNumBulletItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_NUMBULLET
);
1483 if ( rNumBullet
.GetNumRule()->GetLevelCount() > nDepth
)
1484 pFmt
= rNumBullet
.GetNumRule()->Get( nDepth
);
1490 Size
Outliner::ImplGetBulletSize( USHORT nPara
)
1492 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1496 if( pPara
->aBulSize
.Width() == -1 )
1498 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1499 DBG_ASSERT( pFmt
, "ImplGetBulletSize - no Bullet!" );
1501 if ( pFmt
->GetNumberingType() == SVX_NUM_NUMBER_NONE
)
1503 pPara
->aBulSize
= Size( 0, 0 );
1505 else if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
1507 String aBulletText
= ImplGetBulletText( nPara
);
1508 OutputDevice
* pRefDev
= pEditEngine
->GetRefDevice();
1509 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
1510 Font
aRefFont( pRefDev
->GetFont());
1511 pRefDev
->SetFont( aBulletFont
);
1512 pPara
->aBulSize
.Width() = pRefDev
->GetTextWidth( aBulletText
);
1513 pPara
->aBulSize
.Height() = pRefDev
->GetTextHeight();
1514 pRefDev
->SetFont( aRefFont
);
1518 pPara
->aBulSize
= OutputDevice::LogicToLogic( pFmt
->GetGraphicSize(), MAP_100TH_MM
, pEditEngine
->GetRefDevice()->GetMapMode() );
1522 return pPara
->aBulSize
;
1525 void Outliner::ImplCheckParagraphs( USHORT nStart
, USHORT nEnd
)
1527 DBG_CHKTHIS( Outliner
, 0 );
1529 // --> OD 2009-03-10 #i100014#
1530 // assure that the following for-loop does not loop forever
1531 for ( USHORT n
= nStart
; n
< nEnd
; n
++ )
1534 Paragraph
* pPara
= pParaList
->GetParagraph( n
);
1537 pPara
->Invalidate();
1538 ImplCalcBulletText( n
, FALSE
, FALSE
);
1543 void Outliner::SetRefDevice( OutputDevice
* pRefDev
)
1545 DBG_CHKTHIS(Outliner
,0);
1546 pEditEngine
->SetRefDevice( pRefDev
);
1547 for ( USHORT n
= (USHORT
) pParaList
->GetParagraphCount(); n
; )
1549 Paragraph
* pPara
= pParaList
->GetParagraph( --n
);
1550 pPara
->Invalidate();
1554 void Outliner::ParaAttribsChanged( USHORT nPara
)
1556 DBG_CHKTHIS(Outliner
,0);
1558 // Der Outliner hat kein eigenes Undo, wenn Absaetz getrennt/verschmolzen werden.
1559 // Beim ParagraphInserted ist das Attribut EE_PARA_OUTLLEVEL
1560 // ggf. noch nicht eingestellt, dies wird aber benoetigt um die Tiefe
1561 // des Absatzes zu bestimmen.
1563 if( pEditEngine
->IsInUndo() )
1565 if ( pParaList
->GetParagraphCount() == pEditEngine
->GetParagraphCount() )
1567 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1568 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_OUTLLEVEL
);
1569 if ( pPara
&& pPara
->GetDepth() != rLevel
.GetValue() )
1571 pPara
->SetDepth( rLevel
.GetValue() );
1572 ImplCalcBulletText( nPara
, TRUE
, TRUE
);
1578 void Outliner::StyleSheetChanged( SfxStyleSheet
* pStyle
)
1580 DBG_CHKTHIS(Outliner
,0);
1582 // Die EditEngine ruft StyleSheetChanged auch fuer abgeleitete Styles.
1583 // MT: Hier wurde frueher alle Absaetze durch ein ImpRecalcParaAttribs
1584 // gejagt, die die besagte Vorlage haben, warum?
1585 // => Eigentlich kann sich nur die Bullet-Repraesentation aendern...
1587 USHORT nParas
= (USHORT
)pParaList
->GetParagraphCount();
1588 for( USHORT nPara
= 0; nPara
< nParas
; nPara
++ )
1590 if ( pEditEngine
->GetStyleSheet( nPara
) == pStyle
)
1592 ImplCheckNumBulletItem( nPara
);
1593 ImplCalcBulletText( nPara
, FALSE
, FALSE
);
1594 // #97333# EditEngine formats changed paragraphs before calling this method,
1595 // so they are not reformatted now and use wrong bullet indent
1596 pEditEngine
->QuickMarkInvalid( ESelection( nPara
, 0, nPara
, 0 ) );
1601 Rectangle
Outliner::ImpCalcBulletArea( USHORT nPara
, BOOL bAdjust
, BOOL bReturnPaperPos
)
1603 // Bullet-Bereich innerhalb des Absatzes...
1604 Rectangle aBulletArea
;
1606 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1610 Size
aBulletSize( ImplGetBulletSize( nPara
) );
1612 BOOL bOutlineMode
= ( pEditEngine
->GetControlWord() & EE_CNTRL_OUTLINER
) != 0;
1614 // the ODF attribut text:space-before which holds the spacing to add to the left of the label
1615 const short nSpaceBefore
= pFmt
->GetAbsLSpace() + pFmt
->GetFirstLineOffset();
1617 const SvxLRSpaceItem
& rLR
= (const SvxLRSpaceItem
&) pEditEngine
->GetParaAttrib( nPara
, bOutlineMode
? EE_PARA_OUTLLRSPACE
: EE_PARA_LRSPACE
);
1618 aTopLeft
.X() = rLR
.GetTxtLeft() + rLR
.GetTxtFirstLineOfst() + nSpaceBefore
;
1620 long nBulletWidth
= Max( (long) -rLR
.GetTxtFirstLineOfst(), (long) ((-pFmt
->GetFirstLineOffset()) + pFmt
->GetCharTextDistance()) );
1621 if ( nBulletWidth
< aBulletSize
.Width() ) // Bullet macht sich Platz
1622 nBulletWidth
= aBulletSize
.Width();
1624 if ( bAdjust
&& !bOutlineMode
)
1626 // Bei zentriert/rechtsbuendig anpassen
1627 const SvxAdjustItem
& rItem
= (const SvxAdjustItem
&)pEditEngine
->GetParaAttrib( nPara
, EE_PARA_JUST
);
1628 if ( ( !pEditEngine
->IsRightToLeft( nPara
) && ( rItem
.GetAdjust() != SVX_ADJUST_LEFT
) ) ||
1629 ( pEditEngine
->IsRightToLeft( nPara
) && ( rItem
.GetAdjust() != SVX_ADJUST_RIGHT
) ) )
1631 aTopLeft
.X() = pEditEngine
->GetFirstLineStartX( nPara
) - nBulletWidth
;
1636 ParagraphInfos aInfos
= pEditEngine
->GetParagraphInfos( nPara
);
1637 if ( aInfos
.bValid
)
1639 aTopLeft
.Y() = /* aInfos.nFirstLineOffset + */ // #91076# nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
1640 aInfos
.nFirstLineHeight
- aInfos
.nFirstLineTextHeight
1641 + aInfos
.nFirstLineTextHeight
/ 2
1642 - aBulletSize
.Height() / 2;
1643 // ggf. lieber auf der Baseline ausgeben...
1644 if( ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
) && ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) && ( pFmt
->GetNumberingType() != SVX_NUM_CHAR_SPECIAL
) )
1646 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
1647 if ( aBulletFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
)
1649 OutputDevice
* pRefDev
= pEditEngine
->GetRefDevice();
1650 Font aOldFont
= pRefDev
->GetFont();
1651 pRefDev
->SetFont( aBulletFont
);
1652 FontMetric
aMetric( pRefDev
->GetFontMetric() );
1653 // Leading der ersten Zeile...
1654 aTopLeft
.Y() = /* aInfos.nFirstLineOffset + */ aInfos
.nFirstLineMaxAscent
;
1655 aTopLeft
.Y() -= aMetric
.GetAscent();
1656 pRefDev
->SetFont( aOldFont
);
1662 if( pFmt
->GetNumAdjust() == SVX_ADJUST_RIGHT
)
1664 aTopLeft
.X() += nBulletWidth
- aBulletSize
.Width();
1666 else if( pFmt
->GetNumAdjust() == SVX_ADJUST_CENTER
)
1668 aTopLeft
.X() += ( nBulletWidth
- aBulletSize
.Width() ) / 2;
1671 if ( aTopLeft
.X() < 0 ) // dann draengeln
1674 aBulletArea
= Rectangle( aTopLeft
, aBulletSize
);
1676 if ( bReturnPaperPos
)
1678 Size
aBulletSize( aBulletArea
.GetSize() );
1679 Point
aBulletDocPos( aBulletArea
.TopLeft() );
1680 aBulletDocPos
.Y() += pEditEngine
->GetDocPosTopLeft( nPara
).Y();
1681 Point
aBulletPos( aBulletDocPos
);
1685 aBulletPos
.Y() = aBulletDocPos
.X();
1686 aBulletPos
.X() = GetPaperSize().Width() - aBulletDocPos
.Y();
1688 aBulletPos
.X() -= aBulletSize
.Height();
1689 Size
aSz( aBulletSize
);
1690 aBulletSize
.Width() = aSz
.Height();
1691 aBulletSize
.Height() = aSz
.Width();
1693 else if ( pEditEngine
->IsRightToLeft( nPara
) )
1695 aBulletPos
.X() = GetPaperSize().Width() - aBulletDocPos
.X() - aBulletSize
.Width();
1698 aBulletArea
= Rectangle( aBulletPos
, aBulletSize
);
1703 void Outliner::ExpandHdl()
1705 DBG_CHKTHIS(Outliner
,0);
1706 aExpandHdl
.Call( this );
1709 EBulletInfo
Outliner::GetBulletInfo( USHORT nPara
)
1713 aInfo
.nParagraph
= nPara
;
1714 aInfo
.bVisible
= ImplHasBullet( nPara
);
1716 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1717 aInfo
.nType
= pFmt
? pFmt
->GetNumberingType() : 0;
1721 if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
1723 aInfo
.aText
= ImplGetBulletText( nPara
);
1725 if( pFmt
->GetBulletFont() )
1726 aInfo
.aFont
= *pFmt
->GetBulletFont();
1728 else if ( pFmt
->GetBrush()->GetGraphicObject() )
1730 aInfo
.aGraphic
= pFmt
->GetBrush()->GetGraphicObject()->GetGraphic();
1734 if ( aInfo
.bVisible
)
1736 aInfo
.aBounds
= ImpCalcBulletArea( nPara
, TRUE
, TRUE
);
1742 XubString
Outliner::GetText( Paragraph
* pParagraph
, ULONG nCount
) const
1744 DBG_CHKTHIS(Outliner
,0);
1747 USHORT nStartPara
= (USHORT
) pParaList
->GetAbsPos( pParagraph
);
1748 for ( USHORT n
= 0; n
< nCount
; n
++ )
1750 aText
+= pEditEngine
->GetText( nStartPara
+ n
);
1751 if ( (n
+1) < (USHORT
)nCount
)
1757 void Outliner::Remove( Paragraph
* pPara
, ULONG nParaCount
)
1759 DBG_CHKTHIS(Outliner
,0);
1761 ULONG nPos
= pParaList
->GetAbsPos( pPara
);
1762 if( !nPos
&& ( nParaCount
>= pParaList
->GetParagraphCount() ) )
1768 for( USHORT n
= 0; n
< (USHORT
)nParaCount
; n
++ )
1769 pEditEngine
->RemoveParagraph( (USHORT
) nPos
);
1773 void Outliner::StripPortions()
1775 DBG_CHKTHIS(Outliner
,0);
1776 bStrippingPortions
= TRUE
;
1777 pEditEngine
->StripPortions();
1778 bStrippingPortions
= FALSE
;
1782 void Outliner::DrawingText( const Point
& rStartPos
, const XubString
& rText
, USHORT nTextStart
, USHORT nTextLen
, const sal_Int32
* pDXArray
,const SvxFont
& rFont
,
1783 USHORT nPara
, USHORT nIndex
, BYTE nRightToLeft
,
1784 const EEngineData::WrongSpellVector
* pWrongSpellVector
,
1785 const SvxFieldData
* pFieldData
,
1787 bool bEndOfParagraph
,
1789 const ::com::sun::star::lang::Locale
* pLocale
,
1790 const Color
& rOverlineColor
,
1791 const Color
& rTextLineColor
)
1793 DBG_CHKTHIS(Outliner
,0);
1795 if(aDrawPortionHdl
.IsSet())
1798 DrawPortionInfo
aInfo( rStartPos
, rText
, nTextStart
, nTextLen
, rFont
, nPara
, nIndex
, pDXArray
, pWrongSpellVector
,
1799 pFieldData
, pLocale
, rOverlineColor
, rTextLineColor
, nRightToLeft
, bEndOfLine
, bEndOfParagraph
, bEndOfBullet
);
1801 aDrawPortionHdl
.Call( &aInfo
);
1805 long Outliner::RemovingPagesHdl( OutlinerView
* pView
)
1807 DBG_CHKTHIS(Outliner
,0);
1808 return aRemovingPagesHdl
.IsSet() ? aRemovingPagesHdl
.Call( pView
) : TRUE
;
1811 BOOL
Outliner::ImpCanDeleteSelectedPages( OutlinerView
* pCurView
, USHORT _nFirstPage
, USHORT nPages
)
1813 DBG_CHKTHIS(Outliner
,0);
1815 nDepthChangedHdlPrevDepth
= nPages
;
1816 mnFirstSelPage
= _nFirstPage
;
1818 return (BOOL
)RemovingPagesHdl( pCurView
);
1821 SfxItemSet
Outliner::GetParaAttribs( USHORT nPara
)
1823 DBG_CHKTHIS(Outliner
,0);
1824 return pEditEngine
->GetParaAttribs( nPara
);
1827 IMPL_LINK( Outliner
, ParaVisibleStateChangedHdl
, Paragraph
*, pPara
)
1829 DBG_CHKTHIS(Outliner
,0);
1831 ULONG nPara
= pParaList
->GetAbsPos( pPara
);
1832 pEditEngine
->ShowParagraph( (USHORT
)nPara
, pPara
->IsVisible() );
1837 IMPL_LINK( Outliner
, BeginMovingParagraphsHdl
, MoveParagraphsInfo
*, EMPTYARG
)
1839 DBG_CHKTHIS(Outliner
,0);
1842 GetBeginMovingHdl().Call( this );
1847 IMPL_LINK( Outliner
, BeginPasteOrDropHdl
, PasteOrDropInfos
*, pInfos
)
1849 UndoActionStart( EDITUNDO_DRAGANDDROP
);
1850 maBeginPasteOrDropHdl
.Call(pInfos
);
1854 IMPL_LINK( Outliner
, EndPasteOrDropHdl
, PasteOrDropInfos
*, pInfos
)
1857 ImpTextPasted( pInfos
->nStartPara
, pInfos
->nEndPara
- pInfos
->nStartPara
+ 1 );
1858 maEndPasteOrDropHdl
.Call( pInfos
);
1859 UndoActionEnd( EDITUNDO_DRAGANDDROP
);
1863 IMPL_LINK( Outliner
, EndMovingParagraphsHdl
, MoveParagraphsInfo
*, pInfos
)
1865 DBG_CHKTHIS(Outliner
,0);
1867 pParaList
->MoveParagraphs( pInfos
->nStartPara
, pInfos
->nDestPara
, pInfos
->nEndPara
- pInfos
->nStartPara
+ 1 );
1868 USHORT nChangesStart
= Min( pInfos
->nStartPara
, pInfos
->nDestPara
);
1869 USHORT nParas
= (USHORT
)pParaList
->GetParagraphCount();
1870 for ( USHORT n
= nChangesStart
; n
< nParas
; n
++ )
1871 ImplCalcBulletText( n
, FALSE
, FALSE
);
1874 aEndMovingHdl
.Call( this );
1879 sal_uInt16
Outliner::ImplGetNumbering( USHORT nPara
, const SvxNumberFormat
* pParaFmt
)
1881 sal_uInt16 nNumber
= pParaFmt
->GetStart() - 1;
1883 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1884 const sal_Int16 nParaDepth
= pPara
->GetDepth();
1888 pPara
= pParaList
->GetParagraph( nPara
);
1889 const sal_Int16 nDepth
= pPara
->GetDepth();
1891 // ignore paragraphs that are below our paragraph
1892 if( nDepth
> nParaDepth
)
1895 // stop on paragraphs that are above our paragraph
1896 if( nDepth
< nParaDepth
)
1899 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1901 pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
||
1902 pFmt
->GetNumberingType() == SVX_NUM_NUMBER_NONE
)
1903 break; // no number format, or no numbering - stop here
1905 const SfxBoolItem
& rBulletState
= (const SfxBoolItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_BULLETSTATE
);
1907 if( rBulletState
.GetValue() )
1910 // same depth, same number format, check for restart
1911 const sal_Int16 nNumberingStartValue
= pPara
->GetNumberingStartValue();
1912 if( (nNumberingStartValue
!= -1) || pPara
->IsParaIsNumberingRestart() )
1914 if( nNumberingStartValue
!= -1 )
1915 nNumber
+= nNumberingStartValue
- 1;
1924 void Outliner::ImplCalcBulletText( USHORT nPara
, BOOL bRecalcLevel
, BOOL bRecalcChilds
)
1926 DBG_CHKTHIS(Outliner
,0);
1928 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1929 USHORT nRelPos
= 0xFFFF;
1933 XubString aBulletText
;
1934 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1935 if( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) )
1937 aBulletText
+= pFmt
->GetPrefix();
1938 if( pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
1940 aBulletText
+= pFmt
->GetBulletChar();
1942 else if( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
)
1944 aBulletText
+= pFmt
->GetNumStr( ImplGetNumbering( nPara
, pFmt
) );
1946 aBulletText
+= pFmt
->GetSuffix();
1949 if( aBulletText
!= pPara
->GetText() )
1950 pPara
->SetText( aBulletText
);
1952 pPara
->nFlags
&= (~PARAFLAG_SETBULLETTEXT
);
1956 if ( nRelPos
!= 0xFFFF )
1959 sal_Int16 nDepth
= pPara
->GetDepth();
1960 pPara
= pParaList
->GetParagraph( ++nPara
);
1961 if ( !bRecalcChilds
)
1963 while ( pPara
&& ( pPara
->GetDepth() > nDepth
) )
1964 pPara
= pParaList
->GetParagraph( ++nPara
);
1967 if ( pPara
&& ( pPara
->GetDepth() < nDepth
) )
1977 void Outliner::Clear()
1979 DBG_CHKTHIS(Outliner
,0);
1981 if( !bFirstParaIsEmpty
)
1983 ImplBlockInsertionCallbacks( TRUE
);
1984 pEditEngine
->Clear();
1985 pParaList
->Clear( TRUE
);
1986 pParaList
->Insert( new Paragraph( nMinDepth
), LIST_APPEND
);
1987 bFirstParaIsEmpty
= TRUE
;
1988 ImplBlockInsertionCallbacks( FALSE
);
1992 Paragraph
* pPara
= pParaList
->GetParagraph( 0 );
1994 pPara
->SetDepth( nMinDepth
);
1998 void Outliner::SetFlatMode( BOOL bFlat
)
2000 DBG_CHKTHIS(Outliner
,0);
2002 if( bFlat
!= pEditEngine
->IsFlatMode() )
2004 for ( USHORT nPara
= (USHORT
)pParaList
->GetParagraphCount(); nPara
; )
2005 pParaList
->GetParagraph( --nPara
)->aBulSize
.Width() = -1;
2007 pEditEngine
->SetFlatMode( bFlat
);
2011 String
Outliner::ImplGetBulletText( USHORT nPara
)
2014 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
2017 // MT: Optimierung mal wieder aktivieren...
2018 // if( pPara->nFlags & PARAFLAG_SETBULLETTEXT )
2019 ImplCalcBulletText( nPara
, FALSE
, FALSE
);
2020 aRes
= pPara
->GetText();
2025 // this is needed for StarOffice Api
2026 void Outliner::SetLevelDependendStyleSheet( USHORT nPara
)
2028 SfxItemSet
aOldAttrs( pEditEngine
->GetParaAttribs( nPara
) );
2029 ImplSetLevelDependendStyleSheet( nPara
);
2030 pEditEngine
->SetParaAttribs( nPara
, aOldAttrs
);
2033 SV_IMPL_PTRARR( NotifyList
, EENotifyPtr
);
2035 void Outliner::ImplBlockInsertionCallbacks( BOOL b
)
2039 bBlockInsCallback
++;
2043 DBG_ASSERT( bBlockInsCallback
, "ImplBlockInsertionCallbacks ?!" );
2044 bBlockInsCallback
--;
2045 if ( !bBlockInsCallback
)
2047 // Call blocked notify events...
2048 while ( pEditEngine
->aNotifyCache
.Count() )
2050 EENotify
* pNotify
= pEditEngine
->aNotifyCache
[0];
2051 // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
2052 pEditEngine
->aNotifyCache
.Remove( 0 );
2053 pEditEngine
->aOutlinerNotifyHdl
.Call( pNotify
);
2060 IMPL_LINK( Outliner
, EditEngineNotifyHdl
, EENotify
*, pNotify
)
2062 if ( !bBlockInsCallback
)
2064 pEditEngine
->aOutlinerNotifyHdl
.Call( pNotify
);
2068 EENotify
* pNewNotify
= new EENotify( *pNotify
);
2069 pEditEngine
->aNotifyCache
.Insert( pNewNotify
, pEditEngine
->aNotifyCache
.Count() );
2075 /** sets a link that is called at the beginning of a drag operation at an edit view */
2076 void Outliner::SetBeginDropHdl( const Link
& rLink
)
2078 pEditEngine
->SetBeginDropHdl( rLink
);
2081 Link
Outliner::GetBeginDropHdl() const
2083 return pEditEngine
->GetBeginDropHdl();
2086 /** sets a link that is called at the end of a drag operation at an edit view */
2087 void Outliner::SetEndDropHdl( const Link
& rLink
)
2089 pEditEngine
->SetEndDropHdl( rLink
);
2092 Link
Outliner::GetEndDropHdl() const
2094 return pEditEngine
->GetEndDropHdl();
2097 /** sets a link that is called before a drop or paste operation. */
2098 void Outliner::SetBeginPasteOrDropHdl( const Link
& rLink
)
2100 maBeginPasteOrDropHdl
= rLink
;
2103 /** sets a link that is called after a drop or paste operation. */
2104 void Outliner::SetEndPasteOrDropHdl( const Link
& rLink
)
2106 maEndPasteOrDropHdl
= rLink
;
2109 void Outliner::SetParaFlag( Paragraph
* pPara
, sal_uInt16 nFlag
)
2111 if( pPara
&& !pPara
->HasFlag( nFlag
) )
2113 if( IsUndoEnabled() && !IsInUndo() )
2114 InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16
)GetAbsPos( pPara
), pPara
->nFlags
, pPara
->nFlags
|nFlag
) );
2116 pPara
->SetFlag( nFlag
);
2120 void Outliner::RemoveParaFlag( Paragraph
* pPara
, sal_uInt16 nFlag
)
2122 if( pPara
&& pPara
->HasFlag( nFlag
) )
2124 if( IsUndoEnabled() && !IsInUndo() )
2125 InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16
)GetAbsPos( pPara
), pPara
->nFlags
, pPara
->nFlags
& ~nFlag
) );
2127 pPara
->RemoveFlag( nFlag
);
2131 bool Outliner::HasParaFlag( const Paragraph
* pPara
, sal_uInt16 nFlag
) const
2133 return pPara
&& pPara
->HasFlag( nFlag
);
2137 sal_Bool
DrawPortionInfo::IsRTL() const
2139 if(0xFF == mnBiDiLevel
)
2141 // Use Bidi functions from icu 2.0 to calculate if this portion
2143 UErrorCode
nError(U_ZERO_ERROR
);
2144 UBiDi
* pBidi
= ubidi_openSized(mrText
.Len(), 0, &nError
);
2145 nError
= U_ZERO_ERROR
;
2147 // I do not have this info here. Is it necessary? I'll have to ask MT.
2148 const BYTE nDefaultDir
= UBIDI_LTR
; //IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
2150 ubidi_setPara(pBidi
, reinterpret_cast<const UChar
*>(mrText
.GetBuffer()), mrText
.Len(), nDefaultDir
, NULL
, &nError
); // UChar != sal_Unicode in MinGW
2151 nError
= U_ZERO_ERROR
;
2153 // sal_Int32 nCount(ubidi_countRuns(pBidi, &nError));
2157 UBiDiLevel nCurrDir
;
2159 ubidi_getLogicalRun(pBidi
, nStart
, &nEnd
, &nCurrDir
);
2163 // remember on-demand calculated state
2164 ((DrawPortionInfo
*)this)->mnBiDiLevel
= nCurrDir
;
2167 return (1 == (mnBiDiLevel
% 2));