1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
30 #include <comphelper/string.hxx>
31 #include <svl/intitem.hxx>
32 #include <editeng/editeng.hxx>
33 #include <editeng/editview.hxx>
34 #include <editeng/editdata.hxx>
35 #include <editeng/eerdll.hxx>
36 #include <editeng/lrspitem.hxx>
37 #include <editeng/fhgtitem.hxx>
40 #include <svl/style.hxx>
41 #include <vcl/wrkwin.hxx>
43 #include <editeng/outliner.hxx>
44 #include <paralist.hxx>
45 #include <editeng/outlobj.hxx>
46 #include <outleeng.hxx>
47 #include <outlundo.hxx>
48 #include <editeng/eeitem.hxx>
49 #include <editeng/editstat.hxx>
50 #include <editeng/scripttypeitem.hxx>
51 #include <editeng/editobj.hxx>
52 #include <svl/itemset.hxx>
53 #include <svl/whiter.hxx>
54 #include <vcl/metric.hxx>
55 #include <editeng/numitem.hxx>
56 #include <editeng/adjitem.hxx>
57 #include <vcl/graph.hxx>
58 #include <vcl/gdimtf.hxx>
59 #include <vcl/metaact.hxx>
60 #include <svtools/grfmgr.hxx>
61 #include <editeng/svxfont.hxx>
62 #include <editeng/brshitem.hxx>
63 #include <svl/itempool.hxx>
65 // calculate if it's RTL or not
66 #include <unicode/ubidi.h>
70 #define DEFAULT_SCALE 75
72 static const sal_uInt16 nDefStyles
= 3; // Special treatment for the first 3 levels
73 static const sal_uInt16 nDefBulletIndent
= 800;
74 static const sal_uInt16 nDefBulletWidth
= 700;
75 static const sal_uInt16 pDefBulletIndents
[nDefStyles
]= { 1400, 800, 800 };
76 static const sal_uInt16 pDefBulletWidths
[nDefStyles
] = { 1000, 850, 700 };
78 // ----------------------------------------------------------------------
80 // ----------------------------------------------------------------------
83 void Outliner::ImplCheckDepth( sal_Int16
& rnDepth
) const
85 if( rnDepth
< nMinDepth
)
87 else if( rnDepth
> nMaxDepth
)
91 Paragraph
* Outliner::Insert(const XubString
& rText
, sal_uLong nAbsPos
, sal_Int16 nDepth
)
93 DBG_CHKTHIS(Outliner
,0);
94 DBG_ASSERT(pParaList
->GetParagraphCount(),"Insert:No Paras");
98 ImplCheckDepth( nDepth
);
100 sal_uLong nParagraphCount
= pParaList
->GetParagraphCount();
101 if( nAbsPos
> nParagraphCount
)
102 nAbsPos
= nParagraphCount
;
104 if( bFirstParaIsEmpty
)
106 pPara
= pParaList
->GetParagraph( 0 );
107 if( pPara
->GetDepth() != nDepth
)
109 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
110 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
111 pPara
->SetDepth( nDepth
);
112 pHdlParagraph
= pPara
;
115 pPara
->nFlags
|= PARAFLAG_HOLDDEPTH
;
116 SetText( rText
, pPara
);
120 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
121 pEditEngine
->SetUpdateMode( sal_False
);
122 ImplBlockInsertionCallbacks( sal_True
);
123 pPara
= new Paragraph( nDepth
);
124 pParaList
->Insert( pPara
, nAbsPos
);
125 pEditEngine
->InsertParagraph( (sal_uInt16
)nAbsPos
, String() );
126 DBG_ASSERT(pPara
==pParaList
->GetParagraph(nAbsPos
),"Insert:Failed");
127 ImplInitDepth( (sal_uInt16
)nAbsPos
, nDepth
, sal_False
);
128 pHdlParagraph
= pPara
;
129 ParagraphInsertedHdl();
130 pPara
->nFlags
|= PARAFLAG_HOLDDEPTH
;
131 SetText( rText
, pPara
);
132 ImplBlockInsertionCallbacks( sal_False
);
133 pEditEngine
->SetUpdateMode( bUpdate
);
135 bFirstParaIsEmpty
= sal_False
;
136 DBG_ASSERT(pEditEngine
->GetParagraphCount()==pParaList
->GetParagraphCount(),"SetText failed");
141 void Outliner::ParagraphInserted( sal_uInt16 nPara
)
143 DBG_CHKTHIS(Outliner
,0);
145 if ( bBlockInsCallback
)
148 if( bPasting
|| pEditEngine
->IsInUndo() )
150 Paragraph
* pPara
= new Paragraph( -1 );
151 pParaList
->Insert( pPara
, nPara
);
152 if( pEditEngine
->IsInUndo() )
154 pPara
->nFlags
= PARAFLAG_SETBULLETTEXT
;
155 pPara
->bVisible
= sal_True
;
156 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_OUTLLEVEL
);
157 pPara
->SetDepth( rLevel
.GetValue() );
162 sal_Int16 nDepth
= -1;
163 Paragraph
* pParaBefore
= pParaList
->GetParagraph( nPara
-1 );
165 nDepth
= pParaBefore
->GetDepth();
167 Paragraph
* pPara
= new Paragraph( nDepth
);
168 pParaList
->Insert( pPara
, nPara
);
170 if( !pEditEngine
->IsInUndo() )
172 ImplCalcBulletText( nPara
, sal_True
, sal_False
);
173 pHdlParagraph
= pPara
;
174 ParagraphInsertedHdl();
179 void Outliner::ParagraphDeleted( sal_uInt16 nPara
)
181 DBG_CHKTHIS(Outliner
,0);
183 if ( bBlockInsCallback
|| ( nPara
== EE_PARA_ALL
) )
186 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
190 sal_Int16 nDepth
= pPara
->GetDepth();
192 if( !pEditEngine
->IsInUndo() )
194 pHdlParagraph
= pPara
;
195 ParagraphRemovingHdl();
198 pParaList
->Remove( nPara
);
201 if( !pEditEngine
->IsInUndo() && !bPasting
)
203 pPara
= pParaList
->GetParagraph( nPara
);
204 if ( pPara
&& ( pPara
->GetDepth() > nDepth
) )
206 ImplCalcBulletText( nPara
, sal_True
, sal_False
);
207 // Search for next on the this level ...
208 while ( pPara
&& pPara
->GetDepth() > nDepth
)
209 pPara
= pParaList
->GetParagraph( ++nPara
);
212 if ( pPara
&& ( pPara
->GetDepth() == nDepth
) )
213 ImplCalcBulletText( nPara
, sal_True
, sal_False
);
217 void Outliner::Init( sal_uInt16 nMode
)
219 nOutlinerMode
= nMode
;
223 sal_uLong nCtrl
= pEditEngine
->GetControlWord();
224 nCtrl
&= ~(EE_CNTRL_OUTLINER
|EE_CNTRL_OUTLINER2
);
228 switch ( ImplGetOutlinerMode() )
230 case OUTLINERMODE_TEXTOBJECT
:
231 case OUTLINERMODE_TITLEOBJECT
:
234 case OUTLINERMODE_OUTLINEOBJECT
:
235 nCtrl
|= EE_CNTRL_OUTLINER2
;
237 case OUTLINERMODE_OUTLINEVIEW
:
238 nCtrl
|= EE_CNTRL_OUTLINER
;
241 default: OSL_FAIL( "Outliner::Init - Invalid Mode!" );
244 pEditEngine
->SetControlWord( nCtrl
);
246 ImplInitDepth( 0, GetMinDepth(), sal_False
);
248 GetUndoManager().Clear();
251 void Outliner::SetMaxDepth( sal_Int16 nDepth
, sal_Bool bCheckParagraphs
)
253 if( nMaxDepth
!= nDepth
)
255 nMaxDepth
= Min( nDepth
, (sal_Int16
)(SVX_MAX_NUM
-1) );
257 if( bCheckParagraphs
)
259 sal_uInt16 nParagraphs
= (sal_uInt16
)pParaList
->GetParagraphCount();
260 for ( sal_uInt16 nPara
= 0; nPara
< nParagraphs
; nPara
++ )
262 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
263 if( pPara
&& pPara
->GetDepth() > nMaxDepth
)
265 SetDepth( pPara
, nMaxDepth
);
272 sal_Int16
Outliner::GetDepth( sal_uLong nPara
) const
274 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
275 DBG_ASSERT( pPara
, "Outliner::GetDepth - Paragraph not found!" );
276 return pPara
? pPara
->GetDepth() : -1;
279 void Outliner::SetDepth( Paragraph
* pPara
, sal_Int16 nNewDepth
)
281 DBG_CHKTHIS(Outliner
,0);
283 ImplCheckDepth( nNewDepth
);
285 if ( nNewDepth
!= pPara
->GetDepth() )
287 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
288 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
289 pHdlParagraph
= pPara
;
291 sal_uInt16 nPara
= (sal_uInt16
)GetAbsPos( pPara
);
292 ImplInitDepth( nPara
, nNewDepth
, sal_True
);
293 ImplCalcBulletText( nPara
, sal_False
, sal_False
);
295 if ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
)
296 ImplSetLevelDependendStyleSheet( nPara
);
302 sal_Int16
Outliner::GetNumberingStartValue( sal_uInt16 nPara
)
304 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
305 DBG_ASSERT( pPara
, "Outliner::GetNumberingStartValue - Paragraph not found!" );
306 return pPara
? pPara
->GetNumberingStartValue() : -1;
309 void Outliner::SetNumberingStartValue( sal_uInt16 nPara
, sal_Int16 nNumberingStartValue
)
311 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
312 DBG_ASSERT( pPara
, "Outliner::GetNumberingStartValue - Paragraph not found!" );
313 if( pPara
&& pPara
->GetNumberingStartValue() != nNumberingStartValue
)
315 if( IsUndoEnabled() && !IsInUndo() )
316 InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara
,
317 pPara
->GetNumberingStartValue(), nNumberingStartValue
,
318 pPara
->IsParaIsNumberingRestart(), pPara
->IsParaIsNumberingRestart() ) );
320 pPara
->SetNumberingStartValue( nNumberingStartValue
);
322 // It is not a good idea to substract 1 from a count and cast the result
323 // to USHORT without check, if the count is 0.
324 ImplCheckParagraphs( nPara
, (sal_uInt16
) (pParaList
->GetParagraphCount()) );
325 pEditEngine
->SetModified();
329 sal_Bool
Outliner::IsParaIsNumberingRestart( sal_uInt16 nPara
)
331 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
332 DBG_ASSERT( pPara
, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
333 return pPara
? pPara
->IsParaIsNumberingRestart() : sal_False
;
336 void Outliner::SetParaIsNumberingRestart( sal_uInt16 nPara
, sal_Bool bParaIsNumberingRestart
)
338 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
339 DBG_ASSERT( pPara
, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
340 if( pPara
&& (pPara
->IsParaIsNumberingRestart() != bParaIsNumberingRestart
) )
342 if( IsUndoEnabled() && !IsInUndo() )
343 InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara
,
344 pPara
->GetNumberingStartValue(), pPara
->GetNumberingStartValue(),
345 pPara
->IsParaIsNumberingRestart(), bParaIsNumberingRestart
) );
347 pPara
->SetParaIsNumberingRestart( bParaIsNumberingRestart
);
349 // It is not a good idea to substract 1 from a count and cast the result
350 // to USHORT without check, if the count is 0.
351 ImplCheckParagraphs( nPara
, (sal_uInt16
) (pParaList
->GetParagraphCount()) );
352 pEditEngine
->SetModified();
356 OutlinerParaObject
* Outliner::CreateParaObject( sal_uInt16 nStartPara
, sal_uInt16 nCount
) const
358 DBG_CHKTHIS(Outliner
,0);
360 if ( sal::static_int_cast
< sal_uLong
>( nStartPara
+ nCount
) >
361 pParaList
->GetParagraphCount() )
362 nCount
= sal::static_int_cast
< sal_uInt16
>(
363 pParaList
->GetParagraphCount() - nStartPara
);
365 // When a new OutlinerParaObject is created because a paragraph is just beeing deleted,
366 // it can happen that the ParaList is not updated yet...
367 if ( ( nStartPara
+ nCount
) > pEditEngine
->GetParagraphCount() )
368 nCount
= pEditEngine
->GetParagraphCount() - nStartPara
;
373 EditTextObject
* pText
= pEditEngine
->CreateTextObject( nStartPara
, nCount
);
374 const bool bIsEditDoc(OUTLINERMODE_TEXTOBJECT
== ImplGetOutlinerMode());
375 ParagraphDataVector
aParagraphDataVector(nCount
);
376 const sal_uInt16
nLastPara(nStartPara
+ nCount
- 1);
378 for(sal_uInt16
nPara(nStartPara
); nPara
<= nLastPara
; nPara
++)
380 aParagraphDataVector
[nPara
-nStartPara
] = *GetParagraph(nPara
);
383 OutlinerParaObject
* pPObj
= new OutlinerParaObject(*pText
, aParagraphDataVector
, bIsEditDoc
);
384 pPObj
->SetOutlinerMode(GetMode());
390 void Outliner::SetText( const XubString
& rText
, Paragraph
* pPara
)
392 DBG_CHKTHIS(Outliner
,0);
393 DBG_ASSERT(pPara
,"SetText:No Para");
395 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
396 pEditEngine
->SetUpdateMode( sal_False
);
397 ImplBlockInsertionCallbacks( sal_True
);
399 sal_uInt16 nPara
= (sal_uInt16
)pParaList
->GetAbsPos( pPara
);
403 pEditEngine
->SetText( nPara
, rText
);
404 ImplInitDepth( nPara
, pPara
->GetDepth(), sal_False
);
408 XubString
aText(convertLineEnd(rText
, LINEEND_LF
));
410 if( aText
.GetChar( aText
.Len()-1 ) == '\x0A' )
411 aText
.Erase( aText
.Len()-1, 1 ); // Delete the last break
413 sal_uInt16 nCount
= comphelper::string::getTokenCount(aText
, '\x0A');
415 sal_uInt16 nInsPos
= nPara
+1;
416 while( nCount
> nPos
)
418 XubString aStr
= aText
.GetToken( nPos
, '\x0A' );
423 pPara
= new Paragraph( -1 );
427 nCurDepth
= pPara
->GetDepth();
429 // In the outliner mode, filter the tabs and set the indentation
430 // about a LRSpaceItem. In EditEngine mode intend over old tabs
431 if( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
) ||
432 ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW
) )
435 sal_uInt16 nTabs
= 0;
436 while ( ( nTabs
< aStr
.Len() ) && ( aStr
.GetChar( nTabs
) == '\t' ) )
439 aStr
.Erase( 0, nTabs
);
441 // Keep depth? (see Outliner::Insert)
442 if( !(pPara
->nFlags
& PARAFLAG_HOLDDEPTH
) )
445 ImplCheckDepth( nCurDepth
);
446 pPara
->SetDepth( nCurDepth
);
447 pPara
->nFlags
&= (~PARAFLAG_HOLDDEPTH
);
450 if( nPos
) // not with the first paragraph
452 pParaList
->Insert( pPara
, nInsPos
);
453 pEditEngine
->InsertParagraph( nInsPos
, aStr
);
454 pHdlParagraph
= pPara
;
455 ParagraphInsertedHdl();
460 pEditEngine
->SetText( nInsPos
, aStr
);
462 ImplInitDepth( nInsPos
, nCurDepth
, sal_False
);
468 DBG_ASSERT(pParaList
->GetParagraphCount()==pEditEngine
->GetParagraphCount(),"SetText failed!");
469 bFirstParaIsEmpty
= sal_False
;
470 ImplBlockInsertionCallbacks( sal_False
);
471 pEditEngine
->SetUpdateMode( bUpdate
);
474 // pView == 0 -> Ignore tabs
476 bool Outliner::ImpConvertEdtToOut( sal_uInt32 nPara
,EditView
* pView
)
478 DBG_CHKTHIS(Outliner
,0);
480 bool bConverted
= false;
481 sal_uInt16 nTabs
= 0;
484 // const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nPara );
485 // bool bAlreadyOutliner = rAttrs.GetItemState( EE_PARA_OUTLLRSPACE ) == SFX_ITEM_ON ? true : false;
488 XubString
aHeading_US( RTL_CONSTASCII_USTRINGPARAM( "heading" ) );
489 XubString
aNumber_US( RTL_CONSTASCII_USTRINGPARAM( "Numbering" ) );
491 XubString
aStr( pEditEngine
->GetText( (sal_uInt16
)nPara
) );
492 xub_Unicode
* pPtr
= (xub_Unicode
*)aStr
.GetBuffer();
494 sal_uInt16 nHeadingNumberStart
= 0;
495 sal_uInt16 nNumberingNumberStart
= 0;
496 SfxStyleSheet
* pStyle
= pEditEngine
->GetStyleSheet( (sal_uInt16
)nPara
);
499 aName
= pStyle
->GetName();
501 if ( ( nSearch
= aName
.Search( aHeading_US
) ) != STRING_NOTFOUND
)
502 nHeadingNumberStart
= nSearch
+ aHeading_US
.Len();
503 else if ( ( nSearch
= aName
.Search( aNumber_US
) ) != STRING_NOTFOUND
)
504 nNumberingNumberStart
= nSearch
+ aNumber_US
.Len();
507 if ( nHeadingNumberStart
|| nNumberingNumberStart
)
509 // PowerPoint import ?
510 if( nHeadingNumberStart
&& ( aStr
.Len() >= 2 ) &&
511 ( pPtr
[0] != '\t' ) && ( pPtr
[1] == '\t' ) )
513 // Extract Bullet and Tab
514 aDelSel
= ESelection( (sal_uInt16
)nPara
, 0, (sal_uInt16
)nPara
, 2 );
517 sal_uInt16 nPos
= nHeadingNumberStart
? nHeadingNumberStart
: nNumberingNumberStart
;
518 String aLevel
= aName
.Copy( nPos
);
519 aLevel
.EraseLeadingChars( ' ' );
520 nTabs
= sal::static_int_cast
< sal_uInt16
>(aLevel
.ToInt32());
522 nTabs
--; // Level 0 = "heading 1"
523 bConverted
= sal_True
;
527 // filter leading tabs
528 while( *pPtr
== '\t' )
533 // Remove tabs from the text
535 aDelSel
= ESelection( (sal_uInt16
)nPara
, 0, (sal_uInt16
)nPara
, nTabs
);
538 if ( aDelSel
.HasRange() )
542 pView
->SetSelection( aDelSel
);
543 pView
->DeleteSelected();
546 pEditEngine
->QuickDelete( aDelSel
);
549 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( sal::static_int_cast
< sal_uInt16
>(nPara
), EE_PARA_OUTLLEVEL
);
550 sal_Int16 nOutlLevel
= rLevel
.GetValue();
552 ImplCheckDepth( nOutlLevel
);
553 ImplInitDepth( sal::static_int_cast
< sal_uInt16
>(nPara
), nOutlLevel
, sal_False
);
558 void Outliner::SetText( const OutlinerParaObject
& rPObj
)
560 DBG_CHKTHIS(Outliner
,0);
562 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
563 pEditEngine
->SetUpdateMode( sal_False
);
565 sal_Bool bUndo
= pEditEngine
->IsUndoEnabled();
566 EnableUndo( sal_False
);
568 Init( rPObj
.GetOutlinerMode() );
570 ImplBlockInsertionCallbacks( sal_True
);
571 pEditEngine
->SetText(rPObj
.GetTextObject());
572 if( rPObj
.Count() != pEditEngine
->GetParagraphCount() )
577 bFirstParaIsEmpty
= sal_False
;
579 pParaList
->Clear( sal_True
);
580 for( sal_uInt16 nCurPara
= 0; nCurPara
< rPObj
.Count(); nCurPara
++ )
582 Paragraph
* pPara
= new Paragraph( rPObj
.GetParagraphData(nCurPara
));
583 ImplCheckDepth( pPara
->nDepth
);
585 pParaList
->Append(pPara
);
586 ImplCheckNumBulletItem( nCurPara
);
590 // It is not a good idea to substract 1 from a count and cast the result
591 // to USHORT without check, if the count is 0.
592 ImplCheckParagraphs( 0, (sal_uInt16
) (pParaList
->GetParagraphCount()) );
595 ImplBlockInsertionCallbacks( sal_False
);
596 pEditEngine
->SetUpdateMode( bUpdate
);
598 DBG_ASSERT( pParaList
->GetParagraphCount()==rPObj
.Count(),"SetText failed");
599 DBG_ASSERT( pEditEngine
->GetParagraphCount()==rPObj
.Count(),"SetText failed");
602 void Outliner::AddText( const OutlinerParaObject
& rPObj
)
604 DBG_CHKTHIS(Outliner
,0);
607 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
608 pEditEngine
->SetUpdateMode( sal_False
);
610 ImplBlockInsertionCallbacks( sal_True
);
612 if( bFirstParaIsEmpty
)
614 pParaList
->Clear( sal_True
);
615 pEditEngine
->SetText(rPObj
.GetTextObject());
620 nPara
= pParaList
->GetParagraphCount();
621 pEditEngine
->InsertParagraph( EE_PARA_APPEND
, rPObj
.GetTextObject() );
623 bFirstParaIsEmpty
= sal_False
;
625 for( sal_uInt16 n
= 0; n
< rPObj
.Count(); n
++ )
627 pPara
= new Paragraph( rPObj
.GetParagraphData(n
) );
628 pParaList
->Append(pPara
);
629 sal_uInt16 nP
= sal::static_int_cast
< sal_uInt16
>(nPara
+n
);
630 DBG_ASSERT(pParaList
->GetAbsPos(pPara
)==nP
,"AddText:Out of sync");
631 ImplInitDepth( nP
, pPara
->GetDepth(), sal_False
);
633 DBG_ASSERT( pEditEngine
->GetParagraphCount()==pParaList
->GetParagraphCount(), "SetText: OutOfSync" );
636 // It is not a good idea to substract 1 from a count and cast the result
637 // to USHORT without check, if the count is 0.
638 ImplCheckParagraphs( (sal_uInt16
)nPara
, (sal_uInt16
) (pParaList
->GetParagraphCount()) );
640 ImplBlockInsertionCallbacks( sal_False
);
641 pEditEngine
->SetUpdateMode( bUpdate
);
644 void Outliner::FieldClicked( const SvxFieldItem
& rField
, sal_uInt16 nPara
, sal_uInt16 nPos
)
646 DBG_CHKTHIS(Outliner
,0);
648 if ( aFieldClickedHdl
.IsSet() )
650 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
651 aFldInfo
.SetSimpleClick( sal_True
);
652 aFieldClickedHdl
.Call( &aFldInfo
);
657 void Outliner::FieldSelected( const SvxFieldItem
& rField
, sal_uInt16 nPara
, sal_uInt16 nPos
)
659 DBG_CHKTHIS(Outliner
,0);
660 if ( !aFieldClickedHdl
.IsSet() )
663 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
664 aFldInfo
.SetSimpleClick( sal_False
);
665 aFieldClickedHdl
.Call( &aFldInfo
);
669 XubString
Outliner::CalcFieldValue( const SvxFieldItem
& rField
, sal_uInt16 nPara
, sal_uInt16 nPos
, Color
*& rpTxtColor
, Color
*& rpFldColor
)
671 DBG_CHKTHIS(Outliner
,0);
672 if ( !aCalcFieldValueHdl
.IsSet() )
673 return String( ' ' );
675 EditFieldInfo
aFldInfo( this, rField
, nPara
, nPos
);
676 // The FldColor is preset with COL_LIGHTGRAY.
678 aFldInfo
.SetFldColor( *rpFldColor
);
680 aCalcFieldValueHdl
.Call( &aFldInfo
);
681 if ( aFldInfo
.GetTxtColor() )
684 rpTxtColor
= new Color( *aFldInfo
.GetTxtColor() );
688 rpFldColor
= aFldInfo
.GetFldColor() ? new Color( *aFldInfo
.GetFldColor() ) : 0;
690 return aFldInfo
.GetRepresentation();
693 void Outliner::SetStyleSheet( sal_uLong nPara
, SfxStyleSheet
* pStyle
)
695 DBG_CHKTHIS(Outliner
,0);
696 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
699 pEditEngine
->SetStyleSheet( (sal_uInt16
)nPara
, pStyle
);
700 pPara
->nFlags
|= PARAFLAG_SETBULLETTEXT
;
701 ImplCheckNumBulletItem( (sal_uInt16
) nPara
);
705 void Outliner::ImplCheckNumBulletItem( sal_uInt16 nPara
)
707 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
709 pPara
->aBulSize
.Width() = -1;
712 void Outliner::ImplSetLevelDependendStyleSheet( sal_uInt16 nPara
, SfxStyleSheet
* pLevelStyle
)
714 DBG_CHKTHIS(Outliner
,0);
716 DBG_ASSERT( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT
) || ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW
), "SetLevelDependendStyleSheet: Wrong Mode!" );
718 SfxStyleSheet
* pStyle
= pLevelStyle
;
720 pStyle
= GetStyleSheet( nPara
);
724 sal_Int16 nDepth
= GetDepth( nPara
);
728 String
aNewStyleSheetName( pStyle
->GetName() );
729 aNewStyleSheetName
.Erase( aNewStyleSheetName
.Len()-1, 1 );
730 aNewStyleSheetName
+= String::CreateFromInt32( nDepth
+1 );
731 SfxStyleSheet
* pNewStyle
= (SfxStyleSheet
*)GetStyleSheetPool()->Find( aNewStyleSheetName
, pStyle
->GetFamily() );
732 DBG_ASSERT( pNewStyle
, "AutoStyleSheetName - Style not found!" );
733 if ( pNewStyle
&& ( pNewStyle
!= GetStyleSheet( nPara
) ) )
735 SfxItemSet
aOldAttrs( GetParaAttribs( nPara
) );
736 SetStyleSheet( nPara
, pNewStyle
);
737 if ( aOldAttrs
.GetItemState( EE_PARA_NUMBULLET
) == SFX_ITEM_ON
)
739 SfxItemSet
aAttrs( GetParaAttribs( nPara
) );
740 aAttrs
.Put( aOldAttrs
.Get( EE_PARA_NUMBULLET
) );
741 SetParaAttribs( nPara
, aAttrs
);
747 void Outliner::ImplInitDepth( sal_uInt16 nPara
, sal_Int16 nDepth
, sal_Bool bCreateUndo
, sal_Bool bUndoAction
)
749 DBG_CHKTHIS(Outliner
,0);
751 DBG_ASSERT( ( nDepth
>= nMinDepth
) && ( nDepth
<= nMaxDepth
), "ImplInitDepth - Depth is invalid!" );
753 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
756 sal_Int16 nOldDepth
= pPara
->GetDepth();
757 pPara
->SetDepth( nDepth
);
759 // For IsInUndo attributes and style do not have to be set, there
760 // the old values are restored by the EditEngine.
763 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
764 pEditEngine
->SetUpdateMode( sal_False
);
766 sal_Bool bUndo
= bCreateUndo
&& IsUndoEnabled();
767 if ( bUndo
&& bUndoAction
)
768 UndoActionStart( OLUNDO_DEPTH
);
770 SfxItemSet
aAttrs( pEditEngine
->GetParaAttribs( nPara
) );
771 aAttrs
.Put( SfxInt16Item( EE_PARA_OUTLLEVEL
, nDepth
) );
772 pEditEngine
->SetParaAttribs( nPara
, aAttrs
);
773 ImplCheckNumBulletItem( nPara
);
774 ImplCalcBulletText( nPara
, sal_False
, sal_False
);
778 InsertUndo( new OutlinerUndoChangeDepth( this, nPara
, nOldDepth
, nDepth
) );
780 UndoActionEnd( OLUNDO_DEPTH
);
783 pEditEngine
->SetUpdateMode( bUpdate
);
787 void Outliner::SetParaAttribs( sal_uInt16 nPara
, const SfxItemSet
& rSet
)
789 DBG_CHKTHIS(Outliner
,0);
791 pEditEngine
->SetParaAttribs( nPara
, rSet
);
794 sal_Bool
Outliner::Expand( Paragraph
* pPara
)
796 DBG_CHKTHIS(Outliner
,0);
798 if ( pParaList
->HasHiddenChildren( pPara
) )
800 OLUndoExpand
* pUndo
= 0;
801 sal_Bool bUndo
= IsUndoEnabled() && !IsInUndo();
804 UndoActionStart( OLUNDO_EXPAND
);
805 pUndo
= new OLUndoExpand( this, OLUNDO_EXPAND
);
807 pUndo
->nCount
= (sal_uInt16
)pParaList
->GetAbsPos( pPara
);
809 pHdlParagraph
= pPara
;
810 bIsExpanding
= sal_True
;
811 pParaList
->Expand( pPara
);
813 InvalidateBullet( pPara
, pParaList
->GetAbsPos(pPara
) );
817 UndoActionEnd( OLUNDO_EXPAND
);
825 sal_Bool
Outliner::Collapse( Paragraph
* pPara
)
827 DBG_CHKTHIS(Outliner
,0);
828 if ( pParaList
->HasVisibleChildren( pPara
) ) // expanded
830 OLUndoExpand
* pUndo
= 0;
831 sal_Bool bUndo
= sal_False
;
833 if( !IsInUndo() && IsUndoEnabled() )
837 UndoActionStart( OLUNDO_COLLAPSE
);
838 pUndo
= new OLUndoExpand( this, OLUNDO_COLLAPSE
);
840 pUndo
->nCount
= (sal_uInt16
)pParaList
->GetAbsPos( pPara
);
843 pHdlParagraph
= pPara
;
844 bIsExpanding
= sal_False
;
845 pParaList
->Collapse( pPara
);
847 InvalidateBullet( pPara
, pParaList
->GetAbsPos(pPara
) );
851 UndoActionEnd( OLUNDO_COLLAPSE
);
859 Font
Outliner::ImpCalcBulletFont( sal_uInt16 nPara
) const
861 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
862 DBG_ASSERT( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) && ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
), "ImpCalcBulletFont: Missing or BitmapBullet!" );
865 if ( !pEditEngine
->IsFlatMode() )
867 ESelection
aSel( nPara
, 0, nPara
, 0 );
868 aStdFont
= EditEngine::CreateFontFromItemSet( pEditEngine
->GetAttribs( aSel
), GetScriptType( aSel
) );
872 aStdFont
= pEditEngine
->GetStandardFont( nPara
);
876 if ( pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
878 aBulletFont
= *pFmt
->GetBulletFont();
882 aBulletFont
= aStdFont
;
883 aBulletFont
.SetUnderline( UNDERLINE_NONE
);
884 aBulletFont
.SetOverline( UNDERLINE_NONE
);
885 aBulletFont
.SetStrikeout( STRIKEOUT_NONE
);
886 aBulletFont
.SetEmphasisMark( EMPHASISMARK_NONE
);
887 aBulletFont
.SetRelief( RELIEF_NONE
);
890 // Use original scale...
891 sal_uInt16 nStretchX
, nStretchY
;
892 const_cast<Outliner
*>(this)->GetGlobalCharStretching(nStretchX
, nStretchY
);
894 sal_uInt16 nScale
= pFmt
->GetBulletRelSize() * nStretchY
/ 100;
895 sal_uLong nScaledLineHeight
= aStdFont
.GetSize().Height();
896 nScaledLineHeight
*= nScale
*10;
897 nScaledLineHeight
/= 1000;
899 aBulletFont
.SetAlign( ALIGN_BOTTOM
);
900 aBulletFont
.SetSize( Size( 0, nScaledLineHeight
) );
901 sal_Bool bVertical
= IsVertical();
902 aBulletFont
.SetVertical( bVertical
);
903 aBulletFont
.SetOrientation( bVertical
? 2700 : 0 );
905 Color
aColor( COL_AUTO
);
906 if( !pEditEngine
->IsFlatMode() && !( pEditEngine
->GetControlWord() & EE_CNTRL_NOCOLORS
) )
908 aColor
= pFmt
->GetBulletColor();
911 if ( ( aColor
== COL_AUTO
) || ( IsForceAutoColor() ) )
912 aColor
= pEditEngine
->GetAutoColor();
914 aBulletFont
.SetColor( aColor
);
918 void Outliner::PaintBullet( sal_uInt16 nPara
, const Point
& rStartPos
,
919 const Point
& rOrigin
, short nOrientation
, OutputDevice
* pOutDev
)
921 DBG_CHKTHIS(Outliner
,0);
923 bool bDrawBullet
= false;
926 const SfxBoolItem
& rBulletState
= (const SfxBoolItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_BULLETSTATE
);
927 bDrawBullet
= rBulletState
.GetValue() ? true : false;
930 if ( ImplHasBullet( nPara
) && bDrawBullet
)
932 sal_Bool bVertical
= IsVertical();
934 sal_Bool bRightToLeftPara
= pEditEngine
->IsRightToLeft( nPara
);
936 Rectangle
aBulletArea( ImpCalcBulletArea( nPara
, sal_True
, sal_False
) );
937 sal_uInt16 nStretchX
, nStretchY
;
938 GetGlobalCharStretching(nStretchX
, nStretchY
);
939 aBulletArea
= Rectangle( Point(aBulletArea
.Left()*nStretchX
/100,
941 Size(aBulletArea
.GetWidth()*nStretchX
/100,
942 aBulletArea
.GetHeight()) );
944 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
945 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
946 if ( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
) )
948 if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
950 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
952 sal_Bool bSymbol
= pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
;
953 aBulletFont
.SetAlign( bSymbol
? ALIGN_BOTTOM
: ALIGN_BASELINE
);
954 Font aOldFont
= pOutDev
->GetFont();
955 pOutDev
->SetFont( aBulletFont
);
957 ParagraphInfos aParaInfos
= pEditEngine
->GetParagraphInfos( nPara
);
961 // aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
962 aTextPos
.Y() = rStartPos
.Y() + ( bSymbol
? aBulletArea
.Bottom() : aParaInfos
.nFirstLineMaxAscent
);
963 if ( !bRightToLeftPara
)
964 aTextPos
.X() = rStartPos
.X() + aBulletArea
.Left();
966 aTextPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Left();
970 // aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
971 aTextPos
.X() = rStartPos
.X() - ( bSymbol
? aBulletArea
.Bottom() : aParaInfos
.nFirstLineMaxAscent
);
972 aTextPos
.Y() = rStartPos
.Y() + aBulletArea
.Left();
977 // Both TopLeft and bottom left is not quite correct,
978 // since in EditEngine baseline ...
979 double nRealOrientation
= nOrientation
*F_PI1800
;
980 double nCos
= cos( nRealOrientation
);
981 double nSin
= sin( nRealOrientation
);
986 aRotatedPos
.X()=(long) (nCos
*aTextPos
.X() + nSin
*aTextPos
.Y());
987 aRotatedPos
.Y()=(long) - (nSin
*aTextPos
.X() - nCos
*aTextPos
.Y());
988 aTextPos
= aRotatedPos
;
991 Font
aRotatedFont( aBulletFont
);
992 aRotatedFont
.SetOrientation( nOrientation
);
993 pOutDev
->SetFont( aRotatedFont
);
996 // VCL will take care of brackets and so on...
997 sal_uLong nLayoutMode
= pOutDev
->GetLayoutMode();
998 nLayoutMode
&= ~(TEXT_LAYOUT_BIDI_RTL
|TEXT_LAYOUT_COMPLEX_DISABLED
|TEXT_LAYOUT_BIDI_STRONG
);
999 if ( bRightToLeftPara
)
1000 nLayoutMode
|= TEXT_LAYOUT_BIDI_RTL
;
1001 pOutDev
->SetLayoutMode( nLayoutMode
);
1003 if(bStrippingPortions
)
1005 const Font
aSvxFont(pOutDev
->GetFont());
1006 sal_Int32
* pBuf
= new sal_Int32
[ pPara
->GetText().Len() ];
1007 pOutDev
->GetTextArray( pPara
->GetText(), pBuf
);
1011 // aTextPos is Bottom, go to Baseline
1012 FontMetric
aMetric(pOutDev
->GetFontMetric());
1013 aTextPos
.Y() -= aMetric
.GetDescent();
1016 DrawingText(aTextPos
, pPara
->GetText(), 0, pPara
->GetText().Len(), pBuf
,
1017 aSvxFont
, nPara
, 0xFFFF, 0xFF, 0, 0, false, false, true, 0, Color(), Color());
1023 pOutDev
->DrawText( aTextPos
, pPara
->GetText() );
1026 pOutDev
->SetFont( aOldFont
);
1030 if ( pFmt
->GetBrush()->GetGraphicObject() )
1035 aBulletPos
.Y() = rStartPos
.Y() + aBulletArea
.Top();
1036 if ( !bRightToLeftPara
)
1037 aBulletPos
.X() = rStartPos
.X() + aBulletArea
.Left();
1039 aBulletPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Right();
1043 aBulletPos
.X() = rStartPos
.X() - aBulletArea
.Bottom();
1044 aBulletPos
.Y() = rStartPos
.Y() + aBulletArea
.Left();
1047 if(bStrippingPortions
)
1049 if(aDrawBulletHdl
.IsSet())
1051 // call something analog to aDrawPortionHdl (if set) and feed it something
1052 // analog to DrawPortionInfo...
1053 // created aDrawBulletHdl, Set/GetDrawBulletHdl.
1054 // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
1055 DrawBulletInfo
aDrawBulletInfo(
1056 *pFmt
->GetBrush()->GetGraphicObject(),
1060 aDrawBulletHdl
.Call(&aDrawBulletInfo
);
1065 // Remove CAST when KA made the Draw-Method const
1066 ((GraphicObject
*)pFmt
->GetBrush()->GetGraphicObject())->Draw( pOutDev
, aBulletPos
, pPara
->aBulSize
);
1072 // In case of collapsed subparagraphs paint a line before the text.
1073 if( pParaList
->HasChildren(pPara
) && !pParaList
->HasVisibleChildren(pPara
) &&
1074 !bStrippingPortions
&& !nOrientation
)
1076 long nWidth
= pOutDev
->PixelToLogic( Size( 10, 0 ) ).Width();
1078 Point aStartPos
, aEndPos
;
1081 aStartPos
.Y() = rStartPos
.Y() + aBulletArea
.Bottom();
1082 if ( !bRightToLeftPara
)
1083 aStartPos
.X() = rStartPos
.X() + aBulletArea
.Right();
1085 aStartPos
.X() = rStartPos
.X() + GetPaperSize().Width() - aBulletArea
.Left();
1086 aEndPos
= aStartPos
;
1087 aEndPos
.X() += nWidth
;
1091 aStartPos
.X() = rStartPos
.X() - aBulletArea
.Bottom();
1092 aStartPos
.Y() = rStartPos
.Y() + aBulletArea
.Right();
1093 aEndPos
= aStartPos
;
1094 aEndPos
.Y() += nWidth
;
1097 const Color
& rOldLineColor
= pOutDev
->GetLineColor();
1098 pOutDev
->SetLineColor( Color( COL_BLACK
) );
1099 pOutDev
->DrawLine( aStartPos
, aEndPos
);
1100 pOutDev
->SetLineColor( rOldLineColor
);
1105 void Outliner::InvalidateBullet( Paragraph
* /*pPara*/, sal_uLong nPara
)
1107 DBG_CHKTHIS(Outliner
,0);
1109 long nLineHeight
= (long)pEditEngine
->GetLineHeight((sal_uInt16
)nPara
);
1110 for ( size_t i
= 0, n
= aViewList
.size(); i
< n
; ++i
)
1112 OutlinerView
* pView
= aViewList
[ i
];
1113 Point
aPos( pView
->pEditView
->GetWindowPosTopLeft((sal_uInt16
)nPara
) );
1114 Rectangle
aRect( pView
->GetOutputArea() );
1115 aRect
.Right() = aPos
.X();
1116 aRect
.Top() = aPos
.Y();
1117 aRect
.Bottom() = aPos
.Y();
1118 aRect
.Bottom() += nLineHeight
;
1120 pView
->GetWindow()->Invalidate( aRect
);
1124 sal_uLong
Outliner::Read( SvStream
& rInput
, const String
& rBaseURL
, sal_uInt16 eFormat
, SvKeyValueIterator
* pHTTPHeaderAttrs
)
1126 DBG_CHKTHIS(Outliner
,0);
1128 sal_Bool bOldUndo
= pEditEngine
->IsUndoEnabled();
1129 EnableUndo( sal_False
);
1131 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
1132 pEditEngine
->SetUpdateMode( sal_False
);
1136 ImplBlockInsertionCallbacks( sal_True
);
1137 sal_uLong nRet
= pEditEngine
->Read( rInput
, rBaseURL
, (EETextFormat
)eFormat
, pHTTPHeaderAttrs
);
1139 bFirstParaIsEmpty
= sal_False
;
1141 sal_uInt16 nParas
= pEditEngine
->GetParagraphCount();
1142 pParaList
->Clear( sal_True
);
1144 for ( n
= 0; n
< nParas
; n
++ )
1146 Paragraph
* pPara
= new Paragraph( 0 );
1147 pParaList
->Append(pPara
);
1149 if ( eFormat
== EE_FORMAT_BIN
)
1151 const SfxItemSet
& rAttrs
= pEditEngine
->GetParaAttribs( n
);
1152 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) rAttrs
.Get( EE_PARA_OUTLLEVEL
);
1153 sal_Int16 nDepth
= rLevel
.GetValue();
1154 ImplInitDepth( n
, nDepth
, sal_False
);
1158 if ( eFormat
!= EE_FORMAT_BIN
)
1160 ImpFilterIndents( 0, nParas
-1 );
1163 ImplBlockInsertionCallbacks( sal_False
);
1164 pEditEngine
->SetUpdateMode( bUpdate
);
1165 EnableUndo( bOldUndo
);
1171 void Outliner::ImpFilterIndents( sal_uLong nFirstPara
, sal_uLong nLastPara
)
1173 DBG_CHKTHIS(Outliner
,0);
1175 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
1176 pEditEngine
->SetUpdateMode( sal_False
);
1178 Paragraph
* pLastConverted
= NULL
;
1179 for( sal_uLong nPara
= nFirstPara
; nPara
<= nLastPara
; nPara
++ )
1181 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1184 if( ImpConvertEdtToOut( nPara
) )
1186 pLastConverted
= pPara
;
1188 else if ( pLastConverted
)
1190 // Arrange normal paragraphs below the heading ...
1191 pPara
->SetDepth( pLastConverted
->GetDepth() );
1194 ImplInitDepth( (sal_uInt16
)nPara
, pPara
->GetDepth(), sal_False
);
1198 pEditEngine
->SetUpdateMode( bUpdate
);
1201 ::svl::IUndoManager
& Outliner::GetUndoManager()
1203 DBG_CHKTHIS(Outliner
,0);
1204 return pEditEngine
->GetUndoManager();
1207 void Outliner::ImpTextPasted( sal_uLong nStartPara
, sal_uInt16 nCount
)
1209 DBG_CHKTHIS(Outliner
,0);
1211 sal_Bool bUpdate
= pEditEngine
->GetUpdateMode();
1212 pEditEngine
->SetUpdateMode( sal_False
);
1214 const sal_uLong nStart
= nStartPara
;
1216 Paragraph
* pPara
= pParaList
->GetParagraph( nStartPara
);
1218 while( nCount
&& pPara
)
1220 if( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT
)
1222 nDepthChangedHdlPrevDepth
= pPara
->GetDepth();
1223 mnDepthChangeHdlPrevFlags
= pPara
->nFlags
;
1225 ImpConvertEdtToOut( nStartPara
);
1227 pHdlParagraph
= pPara
;
1229 if( nStartPara
== nStart
)
1231 // the existing paragraph has changed depth or flags
1232 if( (pPara
->GetDepth() != nDepthChangedHdlPrevDepth
) || (pPara
->nFlags
!= mnDepthChangeHdlPrevFlags
) )
1236 else // EditEngine mode
1238 sal_Int16 nDepth
= -1;
1239 const SfxItemSet
& rAttrs
= pEditEngine
->GetParaAttribs( (sal_uInt16
)nStartPara
);
1240 if ( rAttrs
.GetItemState( EE_PARA_OUTLLEVEL
) == SFX_ITEM_ON
)
1242 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) rAttrs
.Get( EE_PARA_OUTLLEVEL
);
1243 nDepth
= rLevel
.GetValue();
1245 if ( nDepth
!= GetDepth( nStartPara
) )
1246 ImplInitDepth( (sal_uInt16
)nStartPara
, nDepth
, sal_False
);
1251 pPara
= pParaList
->GetParagraph( nStartPara
);
1254 pEditEngine
->SetUpdateMode( bUpdate
);
1256 DBG_ASSERT(pParaList
->GetParagraphCount()==pEditEngine
->GetParagraphCount(),"ImpTextPasted failed");
1259 long Outliner::IndentingPagesHdl( OutlinerView
* pView
)
1261 DBG_CHKTHIS(Outliner
,0);
1262 if( !aIndentingPagesHdl
.IsSet() )
1264 return aIndentingPagesHdl
.Call( pView
);
1267 sal_Bool
Outliner::ImpCanIndentSelectedPages( OutlinerView
* pCurView
)
1269 DBG_CHKTHIS(Outliner
,0);
1270 // The selected pages must already be set in advance through
1271 // ImpCalcSelectedPages
1273 // If the first paragraph is on level 0 it can not indented in any case,
1274 // possible there might be indentations in the following on the 0 level.
1275 if ( ( mnFirstSelPage
== 0 ) && ( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT
) )
1277 if ( nDepthChangedHdlPrevDepth
== 1 ) // is the only page
1280 pCurView
->ImpCalcSelectedPages( sal_False
); // without the first
1282 return (sal_Bool
)IndentingPagesHdl( pCurView
);
1286 sal_Bool
Outliner::ImpCanDeleteSelectedPages( OutlinerView
* pCurView
)
1288 DBG_CHKTHIS(Outliner
,0);
1289 // The selected pages must already be set in advance through
1290 // ImpCalcSelectedPages
1291 return (sal_Bool
)RemovingPagesHdl( pCurView
);
1294 Outliner::Outliner( SfxItemPool
* pPool
, sal_uInt16 nMode
)
1297 DBG_CTOR( Outliner
, 0 );
1299 bStrippingPortions
= sal_False
;
1300 bPasting
= sal_False
;
1303 bBlockInsCallback
= sal_False
;
1307 pParaList
= new ParagraphList
;
1308 pParaList
->SetVisibleStateChangedHdl( LINK( this, Outliner
, ParaVisibleStateChangedHdl
) );
1309 Paragraph
* pPara
= new Paragraph( 0 );
1310 pParaList
->Append(pPara
);
1311 bFirstParaIsEmpty
= sal_True
;
1313 pEditEngine
= new OutlinerEditEng( this, pPool
);
1314 pEditEngine
->SetBeginMovingParagraphsHdl( LINK( this, Outliner
, BeginMovingParagraphsHdl
) );
1315 pEditEngine
->SetEndMovingParagraphsHdl( LINK( this, Outliner
, EndMovingParagraphsHdl
) );
1316 pEditEngine
->SetBeginPasteOrDropHdl( LINK( this, Outliner
, BeginPasteOrDropHdl
) );
1317 pEditEngine
->SetEndPasteOrDropHdl( LINK( this, Outliner
, EndPasteOrDropHdl
) );
1322 Outliner::~Outliner()
1324 DBG_DTOR(Outliner
,0);
1326 pParaList
->Clear( sal_True
);
1331 size_t Outliner::InsertView( OutlinerView
* pView
, size_t nIndex
)
1333 DBG_CHKTHIS(Outliner
,0);
1336 if ( nIndex
>= aViewList
.size() )
1338 aViewList
.push_back( pView
);
1339 ActualIndex
= aViewList
.size() - 1;
1343 ViewList::iterator it
= aViewList
.begin();
1344 advance( it
, nIndex
);
1345 ActualIndex
= nIndex
;
1347 pEditEngine
->InsertView( pView
->pEditView
, (sal_uInt16
)nIndex
);
1351 OutlinerView
* Outliner::RemoveView( OutlinerView
* pView
)
1353 DBG_CHKTHIS(Outliner
,0);
1355 for ( ViewList::iterator it
= aViewList
.begin(); it
!= aViewList
.end(); ++it
)
1359 pView
->pEditView
->HideCursor(); // HACK
1360 pEditEngine
->RemoveView( pView
->pEditView
);
1361 aViewList
.erase( it
);
1365 return NULL
; // return superfluous
1368 OutlinerView
* Outliner::RemoveView( size_t nIndex
)
1370 DBG_CHKTHIS(Outliner
,0);
1372 EditView
* pEditView
= pEditEngine
->GetView( (sal_uInt16
)nIndex
);
1373 pEditView
->HideCursor(); // HACK
1375 pEditEngine
->RemoveView( (sal_uInt16
)nIndex
);
1378 ViewList::iterator it
= aViewList
.begin();
1379 advance( it
, nIndex
);
1380 aViewList
.erase( it
);
1383 return NULL
; // return superfluous
1387 OutlinerView
* Outliner::GetView( size_t nIndex
) const
1389 DBG_CHKTHIS(Outliner
,0);
1390 return ( nIndex
>= aViewList
.size() ) ? NULL
: aViewList
[ nIndex
];
1393 size_t Outliner::GetViewCount() const
1395 DBG_CHKTHIS(Outliner
,0);
1396 return aViewList
.size();
1399 void Outliner::ParagraphInsertedHdl()
1401 DBG_CHKTHIS(Outliner
,0);
1403 aParaInsertedHdl
.Call( this );
1407 void Outliner::ParagraphRemovingHdl()
1409 DBG_CHKTHIS(Outliner
,0);
1411 aParaRemovingHdl
.Call( this );
1415 void Outliner::DepthChangedHdl()
1417 DBG_CHKTHIS(Outliner
,0);
1419 aDepthChangedHdl
.Call( this );
1423 sal_uLong
Outliner::GetAbsPos( Paragraph
* pPara
)
1425 DBG_CHKTHIS(Outliner
,0);
1426 DBG_ASSERT(pPara
,"GetAbsPos:No Para");
1427 return pParaList
->GetAbsPos( pPara
);
1430 sal_uLong
Outliner::GetParagraphCount() const
1432 DBG_CHKTHIS(Outliner
,0);
1433 return pParaList
->GetParagraphCount();
1436 Paragraph
* Outliner::GetParagraph( sal_uLong nAbsPos
) const
1438 DBG_CHKTHIS(Outliner
,0);
1439 return pParaList
->GetParagraph( nAbsPos
);
1442 sal_Bool
Outliner::HasChildren( Paragraph
* pParagraph
) const
1444 DBG_CHKTHIS(Outliner
,0);
1445 return pParaList
->HasChildren( pParagraph
);
1448 sal_Bool
Outliner::ImplHasBullet( sal_uInt16 nPara
) const
1450 return GetNumberFormat(nPara
) != 0;
1453 const SvxNumberFormat
* Outliner::GetNumberFormat( sal_uInt16 nPara
) const
1455 const SvxNumberFormat
* pFmt
= NULL
;
1457 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1461 sal_Int16 nDepth
= pPara
? pPara
->GetDepth() : -1;
1465 const SvxNumBulletItem
& rNumBullet
= (const SvxNumBulletItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_NUMBULLET
);
1466 if ( rNumBullet
.GetNumRule()->GetLevelCount() > nDepth
)
1467 pFmt
= rNumBullet
.GetNumRule()->Get( nDepth
);
1473 Size
Outliner::ImplGetBulletSize( sal_uInt16 nPara
)
1475 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1479 if( pPara
->aBulSize
.Width() == -1 )
1481 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1482 DBG_ASSERT( pFmt
, "ImplGetBulletSize - no Bullet!" );
1484 if ( pFmt
->GetNumberingType() == SVX_NUM_NUMBER_NONE
)
1486 pPara
->aBulSize
= Size( 0, 0 );
1488 else if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
1490 String aBulletText
= ImplGetBulletText( nPara
);
1491 OutputDevice
* pRefDev
= pEditEngine
->GetRefDevice();
1492 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
1493 Font
aRefFont( pRefDev
->GetFont());
1494 pRefDev
->SetFont( aBulletFont
);
1495 pPara
->aBulSize
.Width() = pRefDev
->GetTextWidth( aBulletText
);
1496 pPara
->aBulSize
.Height() = pRefDev
->GetTextHeight();
1497 pRefDev
->SetFont( aRefFont
);
1501 pPara
->aBulSize
= OutputDevice::LogicToLogic( pFmt
->GetGraphicSize(), MAP_100TH_MM
, pEditEngine
->GetRefDevice()->GetMapMode() );
1505 return pPara
->aBulSize
;
1508 void Outliner::ImplCheckParagraphs( sal_uInt16 nStart
, sal_uInt16 nEnd
)
1510 DBG_CHKTHIS( Outliner
, 0 );
1513 // assure that the following for-loop does not loop forever
1514 for ( sal_uInt16 n
= nStart
; n
< nEnd
; n
++ )
1516 Paragraph
* pPara
= pParaList
->GetParagraph( n
);
1519 pPara
->Invalidate();
1520 ImplCalcBulletText( n
, sal_False
, sal_False
);
1525 void Outliner::SetRefDevice( OutputDevice
* pRefDev
)
1527 DBG_CHKTHIS(Outliner
,0);
1528 pEditEngine
->SetRefDevice( pRefDev
);
1529 for ( sal_uInt16 n
= (sal_uInt16
) pParaList
->GetParagraphCount(); n
; )
1531 Paragraph
* pPara
= pParaList
->GetParagraph( --n
);
1532 pPara
->Invalidate();
1536 void Outliner::ParaAttribsChanged( sal_uInt16 nPara
)
1538 DBG_CHKTHIS(Outliner
,0);
1540 // The Outliner does not have an undo of its own, when paragraphs are
1541 // separated/merged. When ParagraphInserted the attribute EE_PARA_OUTLLEVEL
1542 // may not be set, this is however needed when the depth of the paragraph
1543 // is to be determined.
1544 if( pEditEngine
->IsInUndo() )
1546 if ( pParaList
->GetParagraphCount() == pEditEngine
->GetParagraphCount() )
1548 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1549 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_OUTLLEVEL
);
1550 if ( pPara
&& pPara
->GetDepth() != rLevel
.GetValue() )
1552 pPara
->SetDepth( rLevel
.GetValue() );
1553 ImplCalcBulletText( nPara
, sal_True
, sal_True
);
1559 void Outliner::StyleSheetChanged( SfxStyleSheet
* pStyle
)
1561 DBG_CHKTHIS(Outliner
,0);
1563 // The EditEngine calls StyleSheetChanged also for derived styles.
1564 // Here all the paragraphs, which had the said template, used to be
1565 // hunted by a ImpRecalcParaAttribs, why?
1566 // => only the Bullet-representation can really change...
1567 sal_uInt16 nParas
= (sal_uInt16
)pParaList
->GetParagraphCount();
1568 for( sal_uInt16 nPara
= 0; nPara
< nParas
; nPara
++ )
1570 if ( pEditEngine
->GetStyleSheet( nPara
) == pStyle
)
1572 ImplCheckNumBulletItem( nPara
);
1573 ImplCalcBulletText( nPara
, sal_False
, sal_False
);
1574 // EditEngine formats changed paragraphs before calling this method,
1575 // so they are not reformatted now and use wrong bullet indent
1576 pEditEngine
->QuickMarkInvalid( ESelection( nPara
, 0, nPara
, 0 ) );
1581 Rectangle
Outliner::ImpCalcBulletArea( sal_uInt16 nPara
, sal_Bool bAdjust
, sal_Bool bReturnPaperPos
)
1583 // Bullet area within the paragraph ...
1584 Rectangle aBulletArea
;
1586 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1590 Size
aBulletSize( ImplGetBulletSize( nPara
) );
1592 sal_Bool bOutlineMode
= ( pEditEngine
->GetControlWord() & EE_CNTRL_OUTLINER
) != 0;
1594 // the ODF attribut text:space-before which holds the spacing to add to the left of the label
1595 const short nSpaceBefore
= pFmt
->GetAbsLSpace() + pFmt
->GetFirstLineOffset();
1597 const SvxLRSpaceItem
& rLR
= (const SvxLRSpaceItem
&) pEditEngine
->GetParaAttrib( nPara
, bOutlineMode
? EE_PARA_OUTLLRSPACE
: EE_PARA_LRSPACE
);
1598 aTopLeft
.X() = rLR
.GetTxtLeft() + rLR
.GetTxtFirstLineOfst() + nSpaceBefore
;
1600 long nBulletWidth
= Max( (long) -rLR
.GetTxtFirstLineOfst(), (long) ((-pFmt
->GetFirstLineOffset()) + pFmt
->GetCharTextDistance()) );
1601 if ( nBulletWidth
< aBulletSize
.Width() ) // The Bullet creates its space
1602 nBulletWidth
= aBulletSize
.Width();
1604 if ( bAdjust
&& !bOutlineMode
)
1606 // Adjust when centered or align right
1607 const SvxAdjustItem
& rItem
= (const SvxAdjustItem
&)pEditEngine
->GetParaAttrib( nPara
, EE_PARA_JUST
);
1608 if ( ( !pEditEngine
->IsRightToLeft( nPara
) && ( rItem
.GetAdjust() != SVX_ADJUST_LEFT
) ) ||
1609 ( pEditEngine
->IsRightToLeft( nPara
) && ( rItem
.GetAdjust() != SVX_ADJUST_RIGHT
) ) )
1611 aTopLeft
.X() = pEditEngine
->GetFirstLineStartX( nPara
) - nBulletWidth
;
1616 ParagraphInfos aInfos
= pEditEngine
->GetParagraphInfos( nPara
);
1617 if ( aInfos
.bValid
)
1619 aTopLeft
.Y() = /* aInfos.nFirstLineOffset + */ // nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
1620 aInfos
.nFirstLineHeight
- aInfos
.nFirstLineTextHeight
1621 + aInfos
.nFirstLineTextHeight
/ 2
1622 - aBulletSize
.Height() / 2;
1623 // may prefer to print out on the baseline ...
1624 if( ( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
) && ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) && ( pFmt
->GetNumberingType() != SVX_NUM_CHAR_SPECIAL
) )
1626 Font
aBulletFont( ImpCalcBulletFont( nPara
) );
1627 if ( aBulletFont
.GetCharSet() != RTL_TEXTENCODING_SYMBOL
)
1629 OutputDevice
* pRefDev
= pEditEngine
->GetRefDevice();
1630 Font aOldFont
= pRefDev
->GetFont();
1631 pRefDev
->SetFont( aBulletFont
);
1632 FontMetric
aMetric( pRefDev
->GetFontMetric() );
1633 // Leading on the first line ...
1634 aTopLeft
.Y() = /* aInfos.nFirstLineOffset + */ aInfos
.nFirstLineMaxAscent
;
1635 aTopLeft
.Y() -= aMetric
.GetAscent();
1636 pRefDev
->SetFont( aOldFont
);
1642 if( pFmt
->GetNumAdjust() == SVX_ADJUST_RIGHT
)
1644 aTopLeft
.X() += nBulletWidth
- aBulletSize
.Width();
1646 else if( pFmt
->GetNumAdjust() == SVX_ADJUST_CENTER
)
1648 aTopLeft
.X() += ( nBulletWidth
- aBulletSize
.Width() ) / 2;
1651 if ( aTopLeft
.X() < 0 ) // then push
1654 aBulletArea
= Rectangle( aTopLeft
, aBulletSize
);
1656 if ( bReturnPaperPos
)
1658 Size
aBulletSize( aBulletArea
.GetSize() );
1659 Point
aBulletDocPos( aBulletArea
.TopLeft() );
1660 aBulletDocPos
.Y() += pEditEngine
->GetDocPosTopLeft( nPara
).Y();
1661 Point
aBulletPos( aBulletDocPos
);
1665 aBulletPos
.Y() = aBulletDocPos
.X();
1666 aBulletPos
.X() = GetPaperSize().Width() - aBulletDocPos
.Y();
1668 aBulletPos
.X() -= aBulletSize
.Height();
1669 Size
aSz( aBulletSize
);
1670 aBulletSize
.Width() = aSz
.Height();
1671 aBulletSize
.Height() = aSz
.Width();
1673 else if ( pEditEngine
->IsRightToLeft( nPara
) )
1675 aBulletPos
.X() = GetPaperSize().Width() - aBulletDocPos
.X() - aBulletSize
.Width();
1678 aBulletArea
= Rectangle( aBulletPos
, aBulletSize
);
1683 void Outliner::ExpandHdl()
1685 DBG_CHKTHIS(Outliner
,0);
1686 aExpandHdl
.Call( this );
1689 EBulletInfo
Outliner::GetBulletInfo( sal_uInt16 nPara
)
1693 aInfo
.nParagraph
= nPara
;
1694 aInfo
.bVisible
= ImplHasBullet( nPara
);
1696 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1697 aInfo
.nType
= pFmt
? pFmt
->GetNumberingType() : 0;
1701 if( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
)
1703 aInfo
.aText
= ImplGetBulletText( nPara
);
1705 if( pFmt
->GetBulletFont() )
1706 aInfo
.aFont
= *pFmt
->GetBulletFont();
1708 else if ( pFmt
->GetBrush()->GetGraphicObject() )
1710 aInfo
.aGraphic
= pFmt
->GetBrush()->GetGraphicObject()->GetGraphic();
1714 if ( aInfo
.bVisible
)
1716 aInfo
.aBounds
= ImpCalcBulletArea( nPara
, sal_True
, sal_True
);
1722 XubString
Outliner::GetText( Paragraph
* pParagraph
, sal_uLong nCount
) const
1724 DBG_CHKTHIS(Outliner
,0);
1727 sal_uInt16 nStartPara
= (sal_uInt16
) pParaList
->GetAbsPos( pParagraph
);
1728 for ( sal_uInt16 n
= 0; n
< nCount
; n
++ )
1730 aText
+= pEditEngine
->GetText( nStartPara
+ n
);
1731 if ( (n
+1) < (sal_uInt16
)nCount
)
1737 void Outliner::Remove( Paragraph
* pPara
, sal_uLong nParaCount
)
1739 DBG_CHKTHIS(Outliner
,0);
1741 sal_uLong nPos
= pParaList
->GetAbsPos( pPara
);
1742 if( !nPos
&& ( nParaCount
>= pParaList
->GetParagraphCount() ) )
1748 for( sal_uInt16 n
= 0; n
< (sal_uInt16
)nParaCount
; n
++ )
1749 pEditEngine
->RemoveParagraph( (sal_uInt16
) nPos
);
1753 void Outliner::StripPortions()
1755 DBG_CHKTHIS(Outliner
,0);
1756 bStrippingPortions
= sal_True
;
1757 pEditEngine
->StripPortions();
1758 bStrippingPortions
= sal_False
;
1761 void Outliner::DrawingText( const Point
& rStartPos
, const XubString
& rText
, sal_uInt16 nTextStart
, sal_uInt16 nTextLen
, const sal_Int32
* pDXArray
,const SvxFont
& rFont
,
1762 sal_uInt16 nPara
, sal_uInt16 nIndex
, sal_uInt8 nRightToLeft
,
1763 const EEngineData::WrongSpellVector
* pWrongSpellVector
,
1764 const SvxFieldData
* pFieldData
,
1766 bool bEndOfParagraph
,
1768 const ::com::sun::star::lang::Locale
* pLocale
,
1769 const Color
& rOverlineColor
,
1770 const Color
& rTextLineColor
)
1772 DBG_CHKTHIS(Outliner
,0);
1774 if(aDrawPortionHdl
.IsSet())
1776 DrawPortionInfo
aInfo( rStartPos
, rText
, nTextStart
, nTextLen
, rFont
, nPara
, nIndex
, pDXArray
, pWrongSpellVector
,
1777 pFieldData
, pLocale
, rOverlineColor
, rTextLineColor
, nRightToLeft
, false, 0, bEndOfLine
, bEndOfParagraph
, bEndOfBullet
);
1779 aDrawPortionHdl
.Call( &aInfo
);
1783 void Outliner::DrawingTab( const Point
& rStartPos
, long nWidth
, const String
& rChar
, const SvxFont
& rFont
,
1784 sal_uInt16 nPara
, xub_StrLen nIndex
, sal_uInt8 nRightToLeft
, bool bEndOfLine
, bool bEndOfParagraph
,
1785 const Color
& rOverlineColor
, const Color
& rTextLineColor
)
1787 if(aDrawPortionHdl
.IsSet())
1789 DrawPortionInfo
aInfo( rStartPos
, rChar
, 0, rChar
.Len(), rFont
, nPara
, nIndex
, NULL
, NULL
,
1790 NULL
, NULL
, rOverlineColor
, rTextLineColor
, nRightToLeft
, true, nWidth
, bEndOfLine
, bEndOfParagraph
, false);
1792 aDrawPortionHdl
.Call( &aInfo
);
1796 long Outliner::RemovingPagesHdl( OutlinerView
* pView
)
1798 DBG_CHKTHIS(Outliner
,0);
1799 return aRemovingPagesHdl
.IsSet() ? aRemovingPagesHdl
.Call( pView
) : sal_True
;
1802 sal_Bool
Outliner::ImpCanDeleteSelectedPages( OutlinerView
* pCurView
, sal_uInt16 _nFirstPage
, sal_uInt16 nPages
)
1804 DBG_CHKTHIS(Outliner
,0);
1806 nDepthChangedHdlPrevDepth
= nPages
;
1807 mnFirstSelPage
= _nFirstPage
;
1809 return (sal_Bool
)RemovingPagesHdl( pCurView
);
1812 SfxItemSet
Outliner::GetParaAttribs( sal_uInt16 nPara
)
1814 DBG_CHKTHIS(Outliner
,0);
1815 return pEditEngine
->GetParaAttribs( nPara
);
1818 IMPL_LINK( Outliner
, ParaVisibleStateChangedHdl
, Paragraph
*, pPara
)
1820 DBG_CHKTHIS(Outliner
,0);
1822 sal_uLong nPara
= pParaList
->GetAbsPos( pPara
);
1823 pEditEngine
->ShowParagraph( (sal_uInt16
)nPara
, pPara
->IsVisible() );
1828 IMPL_LINK_NOARG(Outliner
, BeginMovingParagraphsHdl
)
1830 DBG_CHKTHIS(Outliner
,0);
1833 GetBeginMovingHdl().Call( this );
1838 IMPL_LINK( Outliner
, BeginPasteOrDropHdl
, PasteOrDropInfos
*, pInfos
)
1840 UndoActionStart( EDITUNDO_DRAGANDDROP
);
1841 maBeginPasteOrDropHdl
.Call(pInfos
);
1845 IMPL_LINK( Outliner
, EndPasteOrDropHdl
, PasteOrDropInfos
*, pInfos
)
1847 bPasting
= sal_False
;
1848 ImpTextPasted( pInfos
->nStartPara
, pInfos
->nEndPara
- pInfos
->nStartPara
+ 1 );
1849 maEndPasteOrDropHdl
.Call( pInfos
);
1850 UndoActionEnd( EDITUNDO_DRAGANDDROP
);
1854 IMPL_LINK( Outliner
, EndMovingParagraphsHdl
, MoveParagraphsInfo
*, pInfos
)
1856 DBG_CHKTHIS(Outliner
,0);
1858 pParaList
->MoveParagraphs( pInfos
->nStartPara
, pInfos
->nDestPara
, pInfos
->nEndPara
- pInfos
->nStartPara
+ 1 );
1859 sal_uInt16 nChangesStart
= Min( pInfos
->nStartPara
, pInfos
->nDestPara
);
1860 sal_uInt16 nParas
= (sal_uInt16
)pParaList
->GetParagraphCount();
1861 for ( sal_uInt16 n
= nChangesStart
; n
< nParas
; n
++ )
1862 ImplCalcBulletText( n
, sal_False
, sal_False
);
1865 aEndMovingHdl
.Call( this );
1870 static bool isSameNumbering( const SvxNumberFormat
& rN1
, const SvxNumberFormat
& rN2
)
1872 if( rN1
.GetNumberingType() != rN2
.GetNumberingType() )
1875 if( rN1
.GetNumStr(1) != rN2
.GetNumStr(1) )
1878 if( (rN1
.GetPrefix() != rN2
.GetPrefix()) || (rN1
.GetSuffix() != rN2
.GetSuffix()) )
1884 sal_uInt16
Outliner::ImplGetNumbering( sal_uInt16 nPara
, const SvxNumberFormat
* pParaFmt
)
1886 sal_uInt16 nNumber
= pParaFmt
->GetStart() - 1;
1888 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1889 const sal_Int16 nParaDepth
= pPara
->GetDepth();
1893 pPara
= pParaList
->GetParagraph( nPara
);
1894 const sal_Int16 nDepth
= pPara
->GetDepth();
1896 // ignore paragraphs that are below our paragraph or have no numbering
1897 if( (nDepth
> nParaDepth
) || (nDepth
== -1) )
1900 // stop on paragraphs that are above our paragraph
1901 if( nDepth
< nParaDepth
)
1904 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1907 continue; // ignore paragraphs without bullets
1909 // check if numbering is the same
1910 if( !isSameNumbering( *pFmt
, *pParaFmt
) )
1913 const SfxBoolItem
& rBulletState
= (const SfxBoolItem
&) pEditEngine
->GetParaAttrib( nPara
, EE_PARA_BULLETSTATE
);
1915 if( rBulletState
.GetValue() )
1918 // same depth, same number format, check for restart
1919 const sal_Int16 nNumberingStartValue
= pPara
->GetNumberingStartValue();
1920 if( (nNumberingStartValue
!= -1) || pPara
->IsParaIsNumberingRestart() )
1922 if( nNumberingStartValue
!= -1 )
1923 nNumber
+= nNumberingStartValue
- 1;
1932 void Outliner::ImplCalcBulletText( sal_uInt16 nPara
, sal_Bool bRecalcLevel
, sal_Bool bRecalcChildren
)
1934 DBG_CHKTHIS(Outliner
,0);
1936 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
1937 sal_uInt16 nRelPos
= 0xFFFF;
1941 XubString aBulletText
;
1942 const SvxNumberFormat
* pFmt
= GetNumberFormat( nPara
);
1943 if( pFmt
&& ( pFmt
->GetNumberingType() != SVX_NUM_BITMAP
) )
1945 aBulletText
+= pFmt
->GetPrefix();
1946 if( pFmt
->GetNumberingType() == SVX_NUM_CHAR_SPECIAL
)
1948 aBulletText
+= pFmt
->GetBulletChar();
1950 else if( pFmt
->GetNumberingType() != SVX_NUM_NUMBER_NONE
)
1952 aBulletText
+= pFmt
->GetNumStr( ImplGetNumbering( nPara
, pFmt
) );
1954 aBulletText
+= pFmt
->GetSuffix();
1957 if( aBulletText
!= pPara
->GetText() )
1958 pPara
->SetText( aBulletText
);
1960 pPara
->nFlags
&= (~PARAFLAG_SETBULLETTEXT
);
1964 if ( nRelPos
!= 0xFFFF )
1967 sal_Int16 nDepth
= pPara
->GetDepth();
1968 pPara
= pParaList
->GetParagraph( ++nPara
);
1969 if ( !bRecalcChildren
)
1971 while ( pPara
&& ( pPara
->GetDepth() > nDepth
) )
1972 pPara
= pParaList
->GetParagraph( ++nPara
);
1975 if ( pPara
&& ( pPara
->GetDepth() < nDepth
) )
1985 void Outliner::Clear()
1987 DBG_CHKTHIS(Outliner
,0);
1989 if( !bFirstParaIsEmpty
)
1991 ImplBlockInsertionCallbacks( sal_True
);
1992 pEditEngine
->Clear();
1993 pParaList
->Clear( sal_True
);
1994 pParaList
->Append( new Paragraph( nMinDepth
));
1995 bFirstParaIsEmpty
= sal_True
;
1996 ImplBlockInsertionCallbacks( sal_False
);
2000 Paragraph
* pPara
= pParaList
->GetParagraph( 0 );
2002 pPara
->SetDepth( nMinDepth
);
2006 void Outliner::SetFlatMode( sal_Bool bFlat
)
2008 DBG_CHKTHIS(Outliner
,0);
2010 if( bFlat
!= pEditEngine
->IsFlatMode() )
2012 for ( sal_uInt16 nPara
= (sal_uInt16
)pParaList
->GetParagraphCount(); nPara
; )
2013 pParaList
->GetParagraph( --nPara
)->aBulSize
.Width() = -1;
2015 pEditEngine
->SetFlatMode( bFlat
);
2019 String
Outliner::ImplGetBulletText( sal_uInt16 nPara
)
2022 Paragraph
* pPara
= pParaList
->GetParagraph( nPara
);
2025 // Enable optimization again ...
2026 // if( pPara->nFlags & PARAFLAG_SETBULLETTEXT )
2027 ImplCalcBulletText( nPara
, sal_False
, sal_False
);
2028 aRes
= pPara
->GetText();
2033 // this is needed for StarOffice Api
2034 void Outliner::SetLevelDependendStyleSheet( sal_uInt16 nPara
)
2036 SfxItemSet
aOldAttrs( pEditEngine
->GetParaAttribs( nPara
) );
2037 ImplSetLevelDependendStyleSheet( nPara
);
2038 pEditEngine
->SetParaAttribs( nPara
, aOldAttrs
);
2041 void Outliner::ImplBlockInsertionCallbacks( sal_Bool b
)
2045 bBlockInsCallback
++;
2049 DBG_ASSERT( bBlockInsCallback
, "ImplBlockInsertionCallbacks ?!" );
2050 bBlockInsCallback
--;
2051 if ( !bBlockInsCallback
)
2053 // Call blocked notify events...
2054 while(!pEditEngine
->aNotifyCache
.empty())
2056 EENotify
aNotify(pEditEngine
->aNotifyCache
.front());
2057 // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
2058 pEditEngine
->aNotifyCache
.erase(pEditEngine
->aNotifyCache
.begin());
2059 pEditEngine
->aOutlinerNotifyHdl
.Call( &aNotify
);
2065 IMPL_LINK( Outliner
, EditEngineNotifyHdl
, EENotify
*, pNotify
)
2067 if ( !bBlockInsCallback
)
2068 pEditEngine
->aOutlinerNotifyHdl
.Call( pNotify
);
2070 pEditEngine
->aNotifyCache
.push_back(*pNotify
);
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 /** sets a link that is called at the end of a drag operation at an edit view */
2082 void Outliner::SetEndDropHdl( const Link
& rLink
)
2084 pEditEngine
->SetEndDropHdl( rLink
);
2087 /** sets a link that is called before a drop or paste operation. */
2088 void Outliner::SetBeginPasteOrDropHdl( const Link
& rLink
)
2090 maBeginPasteOrDropHdl
= rLink
;
2093 /** sets a link that is called after a drop or paste operation. */
2094 void Outliner::SetEndPasteOrDropHdl( const Link
& rLink
)
2096 maEndPasteOrDropHdl
= rLink
;
2099 void Outliner::SetParaFlag( Paragraph
* pPara
, sal_uInt16 nFlag
)
2101 if( pPara
&& !pPara
->HasFlag( nFlag
) )
2103 if( IsUndoEnabled() && !IsInUndo() )
2104 InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16
)GetAbsPos( pPara
), pPara
->nFlags
, pPara
->nFlags
|nFlag
) );
2106 pPara
->SetFlag( nFlag
);
2110 bool Outliner::HasParaFlag( const Paragraph
* pPara
, sal_uInt16 nFlag
) const
2112 return pPara
&& pPara
->HasFlag( nFlag
);
2116 sal_Bool
DrawPortionInfo::IsRTL() const
2118 if(0xFF == mnBiDiLevel
)
2120 // Use Bidi functions from icu 2.0 to calculate if this portion
2122 UErrorCode
nError(U_ZERO_ERROR
);
2123 UBiDi
* pBidi
= ubidi_openSized(mrText
.Len(), 0, &nError
);
2124 nError
= U_ZERO_ERROR
;
2126 // I do not have this info here. Is it necessary? I'll have to ask MT.
2127 const sal_uInt8 nDefaultDir
= UBIDI_LTR
; //IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
2129 ubidi_setPara(pBidi
, reinterpret_cast<const UChar
*>(mrText
.GetBuffer()), mrText
.Len(), nDefaultDir
, NULL
, &nError
); // UChar != sal_Unicode in MinGW
2130 nError
= U_ZERO_ERROR
;
2134 UBiDiLevel nCurrDir
;
2136 ubidi_getLogicalRun(pBidi
, nStart
, &nEnd
, &nCurrDir
);
2140 // remember on-demand calculated state
2141 ((DrawPortionInfo
*)this)->mnBiDiLevel
= nCurrDir
;
2144 return (1 == (mnBiDiLevel
% 2));
2149 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */