Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <comphelper/string.hxx>
21 : #include <svl/intitem.hxx>
22 : #include <editeng/editeng.hxx>
23 : #include <editeng/editview.hxx>
24 : #include <editeng/editdata.hxx>
25 : #include <editeng/eerdll.hxx>
26 : #include <editeng/lrspitem.hxx>
27 : #include <editeng/fhgtitem.hxx>
28 :
29 : #include <math.h>
30 : #include <svl/style.hxx>
31 : #include <vcl/wrkwin.hxx>
32 : #define _OUTLINER_CXX
33 : #include <editeng/outliner.hxx>
34 : #include <paralist.hxx>
35 : #include <editeng/outlobj.hxx>
36 : #include <outleeng.hxx>
37 : #include <outlundo.hxx>
38 : #include <editeng/eeitem.hxx>
39 : #include <editeng/editstat.hxx>
40 : #include <editeng/scripttypeitem.hxx>
41 : #include <editeng/editobj.hxx>
42 : #include <svl/itemset.hxx>
43 : #include <svl/whiter.hxx>
44 : #include <vcl/metric.hxx>
45 : #include <editeng/numitem.hxx>
46 : #include <editeng/adjitem.hxx>
47 : #include <vcl/graph.hxx>
48 : #include <vcl/gdimtf.hxx>
49 : #include <vcl/metaact.hxx>
50 : #include <svtools/grfmgr.hxx>
51 : #include <editeng/svxfont.hxx>
52 : #include <editeng/brshitem.hxx>
53 : #include <svl/itempool.hxx>
54 :
55 : // calculate if it's RTL or not
56 : #include <unicode/ubidi.h>
57 : #include <cassert>
58 : using ::std::advance;
59 :
60 : static const sal_uInt16 nDefStyles = 3; // Special treatment for the first 3 levels
61 : static const sal_uInt16 nDefBulletIndent = 800;
62 : static const sal_uInt16 nDefBulletWidth = 700;
63 : static const sal_uInt16 pDefBulletIndents[nDefStyles]= { 1400, 800, 800 };
64 : static const sal_uInt16 pDefBulletWidths[nDefStyles] = { 1000, 850, 700 };
65 :
66 : // ----------------------------------------------------------------------
67 : // Outliner
68 : // ----------------------------------------------------------------------
69 : DBG_NAME(Outliner);
70 :
71 13850 : void Outliner::ImplCheckDepth( sal_Int16& rnDepth ) const
72 : {
73 13850 : if( rnDepth < nMinDepth )
74 0 : rnDepth = nMinDepth;
75 13850 : else if( rnDepth > nMaxDepth )
76 0 : rnDepth = nMaxDepth;
77 13850 : }
78 :
79 779 : Paragraph* Outliner::Insert(const XubString& rText, sal_uLong nAbsPos, sal_Int16 nDepth)
80 : {
81 : DBG_CHKTHIS(Outliner,0);
82 : DBG_ASSERT(pParaList->GetParagraphCount(),"Insert:No Paras");
83 :
84 : Paragraph* pPara;
85 :
86 779 : ImplCheckDepth( nDepth );
87 :
88 779 : sal_uLong nParagraphCount = pParaList->GetParagraphCount();
89 779 : if( nAbsPos > nParagraphCount )
90 4 : nAbsPos = nParagraphCount;
91 :
92 779 : if( bFirstParaIsEmpty )
93 : {
94 592 : pPara = pParaList->GetParagraph( 0 );
95 592 : if( pPara->GetDepth() != nDepth )
96 : {
97 592 : nDepthChangedHdlPrevDepth = pPara->GetDepth();
98 592 : mnDepthChangeHdlPrevFlags = pPara->nFlags;
99 592 : pPara->SetDepth( nDepth );
100 592 : pHdlParagraph = pPara;
101 592 : DepthChangedHdl();
102 : }
103 592 : pPara->nFlags |= PARAFLAG_HOLDDEPTH;
104 592 : SetText( rText, pPara );
105 : }
106 : else
107 : {
108 187 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
109 187 : pEditEngine->SetUpdateMode( sal_False );
110 187 : ImplBlockInsertionCallbacks( sal_True );
111 187 : pPara = new Paragraph( nDepth );
112 187 : pParaList->Insert( pPara, nAbsPos );
113 187 : pEditEngine->InsertParagraph( (sal_uInt16)nAbsPos, String() );
114 : DBG_ASSERT(pPara==pParaList->GetParagraph(nAbsPos),"Insert:Failed");
115 187 : ImplInitDepth( (sal_uInt16)nAbsPos, nDepth, sal_False );
116 187 : pHdlParagraph = pPara;
117 187 : ParagraphInsertedHdl();
118 187 : pPara->nFlags |= PARAFLAG_HOLDDEPTH;
119 187 : SetText( rText, pPara );
120 187 : ImplBlockInsertionCallbacks( sal_False );
121 187 : pEditEngine->SetUpdateMode( bUpdate );
122 : }
123 779 : bFirstParaIsEmpty = sal_False;
124 : DBG_ASSERT(pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(),"SetText failed");
125 779 : return pPara;
126 : }
127 :
128 :
129 26776 : void Outliner::ParagraphInserted( sal_uInt16 nPara )
130 : {
131 : DBG_CHKTHIS(Outliner,0);
132 :
133 26776 : if ( bBlockInsCallback )
134 53412 : return;
135 :
136 140 : if( bPasting || pEditEngine->IsInUndo() )
137 : {
138 0 : Paragraph* pPara = new Paragraph( -1 );
139 0 : pParaList->Insert( pPara, nPara );
140 0 : if( pEditEngine->IsInUndo() )
141 : {
142 0 : pPara->nFlags = PARAFLAG_SETBULLETTEXT;
143 0 : pPara->bVisible = sal_True;
144 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
145 0 : pPara->SetDepth( rLevel.GetValue() );
146 : }
147 : }
148 : else
149 : {
150 140 : sal_Int16 nDepth = -1;
151 140 : Paragraph* pParaBefore = pParaList->GetParagraph( nPara-1 );
152 140 : if ( pParaBefore )
153 140 : nDepth = pParaBefore->GetDepth();
154 :
155 140 : Paragraph* pPara = new Paragraph( nDepth );
156 140 : pParaList->Insert( pPara, nPara );
157 :
158 140 : if( !pEditEngine->IsInUndo() )
159 : {
160 140 : ImplCalcBulletText( nPara, sal_True, sal_False );
161 140 : pHdlParagraph = pPara;
162 140 : ParagraphInsertedHdl();
163 : }
164 : }
165 : }
166 :
167 25905 : void Outliner::ParagraphDeleted( sal_uInt16 nPara )
168 : {
169 : DBG_CHKTHIS(Outliner,0);
170 :
171 25905 : if ( bBlockInsCallback || ( nPara == EE_PARA_ALL ) )
172 25801 : return;
173 :
174 104 : Paragraph* pPara = pParaList->GetParagraph( nPara );
175 104 : if (!pPara)
176 0 : return;
177 :
178 104 : sal_Int16 nDepth = pPara->GetDepth();
179 :
180 104 : if( !pEditEngine->IsInUndo() )
181 : {
182 104 : pHdlParagraph = pPara;
183 104 : ParagraphRemovingHdl();
184 : }
185 :
186 104 : pParaList->Remove( nPara );
187 104 : delete pPara;
188 :
189 104 : if( !pEditEngine->IsInUndo() && !bPasting )
190 : {
191 104 : pPara = pParaList->GetParagraph( nPara );
192 104 : if ( pPara && ( pPara->GetDepth() > nDepth ) )
193 : {
194 0 : ImplCalcBulletText( nPara, sal_True, sal_False );
195 : // Search for next on the this level ...
196 0 : while ( pPara && pPara->GetDepth() > nDepth )
197 0 : pPara = pParaList->GetParagraph( ++nPara );
198 : }
199 :
200 104 : if ( pPara && ( pPara->GetDepth() == nDepth ) )
201 0 : ImplCalcBulletText( nPara, sal_True, sal_False );
202 : }
203 : }
204 :
205 41670 : void Outliner::Init( sal_uInt16 nMode )
206 : {
207 41670 : nOutlinerMode = nMode;
208 :
209 41670 : Clear();
210 :
211 41670 : sal_uLong nCtrl = pEditEngine->GetControlWord();
212 41670 : nCtrl &= ~(EE_CNTRL_OUTLINER|EE_CNTRL_OUTLINER2);
213 :
214 41670 : SetMaxDepth( 9 );
215 :
216 41670 : switch ( ImplGetOutlinerMode() )
217 : {
218 : case OUTLINERMODE_TEXTOBJECT:
219 : case OUTLINERMODE_TITLEOBJECT:
220 40203 : break;
221 :
222 : case OUTLINERMODE_OUTLINEOBJECT:
223 1467 : nCtrl |= EE_CNTRL_OUTLINER2;
224 1467 : break;
225 : case OUTLINERMODE_OUTLINEVIEW:
226 0 : nCtrl |= EE_CNTRL_OUTLINER;
227 0 : break;
228 :
229 : default: OSL_FAIL( "Outliner::Init - Invalid Mode!" );
230 : }
231 :
232 41670 : pEditEngine->SetControlWord( nCtrl );
233 :
234 41670 : ImplInitDepth( 0, GetMinDepth(), sal_False );
235 :
236 41670 : GetUndoManager().Clear();
237 41670 : }
238 :
239 41670 : void Outliner::SetMaxDepth( sal_Int16 nDepth, sal_Bool bCheckParagraphs )
240 : {
241 41670 : if( nMaxDepth != nDepth )
242 : {
243 0 : nMaxDepth = Min( nDepth, (sal_Int16)(SVX_MAX_NUM-1) );
244 :
245 0 : if( bCheckParagraphs )
246 : {
247 0 : sal_uInt16 nParagraphs = (sal_uInt16)pParaList->GetParagraphCount();
248 0 : for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
249 : {
250 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
251 0 : if( pPara && pPara->GetDepth() > nMaxDepth )
252 : {
253 0 : SetDepth( pPara, nMaxDepth );
254 : }
255 : }
256 : }
257 : }
258 41670 : }
259 :
260 189 : sal_Int16 Outliner::GetDepth( sal_uLong nPara ) const
261 : {
262 189 : Paragraph* pPara = pParaList->GetParagraph( nPara );
263 : DBG_ASSERT( pPara, "Outliner::GetDepth - Paragraph not found!" );
264 189 : return pPara ? pPara->GetDepth() : -1;
265 : }
266 :
267 74 : void Outliner::SetDepth( Paragraph* pPara, sal_Int16 nNewDepth )
268 : {
269 : DBG_CHKTHIS(Outliner,0);
270 :
271 74 : ImplCheckDepth( nNewDepth );
272 :
273 74 : if ( nNewDepth != pPara->GetDepth() )
274 : {
275 72 : nDepthChangedHdlPrevDepth = pPara->GetDepth();
276 72 : mnDepthChangeHdlPrevFlags = pPara->nFlags;
277 72 : pHdlParagraph = pPara;
278 :
279 72 : sal_uInt16 nPara = (sal_uInt16)GetAbsPos( pPara );
280 72 : ImplInitDepth( nPara, nNewDepth, sal_True );
281 72 : ImplCalcBulletText( nPara, sal_False, sal_False );
282 :
283 72 : if ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT )
284 32 : ImplSetLevelDependendStyleSheet( nPara );
285 :
286 72 : DepthChangedHdl();
287 : }
288 74 : }
289 :
290 0 : sal_Int16 Outliner::GetNumberingStartValue( sal_uInt16 nPara )
291 : {
292 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
293 : DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
294 0 : return pPara ? pPara->GetNumberingStartValue() : -1;
295 : }
296 :
297 774 : void Outliner::SetNumberingStartValue( sal_uInt16 nPara, sal_Int16 nNumberingStartValue )
298 : {
299 774 : Paragraph* pPara = pParaList->GetParagraph( nPara );
300 : DBG_ASSERT( pPara, "Outliner::GetNumberingStartValue - Paragraph not found!" );
301 774 : if( pPara && pPara->GetNumberingStartValue() != nNumberingStartValue )
302 : {
303 0 : if( IsUndoEnabled() && !IsInUndo() )
304 : InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
305 0 : pPara->GetNumberingStartValue(), nNumberingStartValue,
306 0 : pPara->IsParaIsNumberingRestart(), pPara->IsParaIsNumberingRestart() ) );
307 :
308 0 : pPara->SetNumberingStartValue( nNumberingStartValue );
309 : // #i100014#
310 : // It is not a good idea to substract 1 from a count and cast the result
311 : // to sal_uInt16 without check, if the count is 0.
312 0 : ImplCheckParagraphs( nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
313 0 : pEditEngine->SetModified();
314 : }
315 774 : }
316 :
317 0 : sal_Bool Outliner::IsParaIsNumberingRestart( sal_uInt16 nPara )
318 : {
319 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
320 : DBG_ASSERT( pPara, "Outliner::IsParaIsNumberingRestart - Paragraph not found!" );
321 0 : return pPara ? pPara->IsParaIsNumberingRestart() : sal_False;
322 : }
323 :
324 0 : void Outliner::SetParaIsNumberingRestart( sal_uInt16 nPara, sal_Bool bParaIsNumberingRestart )
325 : {
326 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
327 : DBG_ASSERT( pPara, "Outliner::SetParaIsNumberingRestart - Paragraph not found!" );
328 0 : if( pPara && (pPara->IsParaIsNumberingRestart() != bParaIsNumberingRestart) )
329 : {
330 0 : if( IsUndoEnabled() && !IsInUndo() )
331 : InsertUndo( new OutlinerUndoChangeParaNumberingRestart( this, nPara,
332 0 : pPara->GetNumberingStartValue(), pPara->GetNumberingStartValue(),
333 0 : pPara->IsParaIsNumberingRestart(), bParaIsNumberingRestart ) );
334 :
335 0 : pPara->SetParaIsNumberingRestart( bParaIsNumberingRestart );
336 : // #i100014#
337 : // It is not a good idea to substract 1 from a count and cast the result
338 : // to sal_uInt16 without check, if the count is 0.
339 0 : ImplCheckParagraphs( nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
340 0 : pEditEngine->SetModified();
341 : }
342 0 : }
343 :
344 9246 : OutlinerParaObject* Outliner::CreateParaObject( sal_uInt16 nStartPara, sal_uInt16 nCount ) const
345 : {
346 : DBG_CHKTHIS(Outliner,0);
347 :
348 18492 : if ( sal::static_int_cast< sal_uLong >( nStartPara + nCount ) >
349 9246 : pParaList->GetParagraphCount() )
350 : nCount = sal::static_int_cast< sal_uInt16 >(
351 3471 : pParaList->GetParagraphCount() - nStartPara );
352 :
353 : // When a new OutlinerParaObject is created because a paragraph is just beeing deleted,
354 : // it can happen that the ParaList is not updated yet...
355 9246 : if ( ( nStartPara + nCount ) > pEditEngine->GetParagraphCount() )
356 0 : nCount = pEditEngine->GetParagraphCount() - nStartPara;
357 :
358 9246 : if( !nCount )
359 0 : return NULL;
360 :
361 9246 : EditTextObject* pText = pEditEngine->CreateTextObject( nStartPara, nCount );
362 9246 : const bool bIsEditDoc(OUTLINERMODE_TEXTOBJECT == ImplGetOutlinerMode());
363 9246 : ParagraphDataVector aParagraphDataVector(nCount);
364 9246 : const sal_uInt16 nLastPara(nStartPara + nCount - 1);
365 :
366 18958 : for(sal_uInt16 nPara(nStartPara); nPara <= nLastPara; nPara++)
367 : {
368 9712 : aParagraphDataVector[nPara-nStartPara] = *GetParagraph(nPara);
369 : }
370 :
371 9246 : OutlinerParaObject* pPObj = new OutlinerParaObject(*pText, aParagraphDataVector, bIsEditDoc);
372 9246 : pPObj->SetOutlinerMode(GetMode());
373 9246 : delete pText;
374 :
375 9246 : return pPObj;
376 : }
377 :
378 2046 : void Outliner::SetText( const XubString& rText, Paragraph* pPara )
379 : {
380 : DBG_CHKTHIS(Outliner,0);
381 : DBG_ASSERT(pPara,"SetText:No Para");
382 :
383 2046 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
384 2046 : pEditEngine->SetUpdateMode( sal_False );
385 2046 : ImplBlockInsertionCallbacks( sal_True );
386 :
387 2046 : sal_uInt16 nPara = (sal_uInt16)pParaList->GetAbsPos( pPara );
388 :
389 2046 : if( !rText.Len() )
390 : {
391 1884 : pEditEngine->SetText( nPara, rText );
392 1884 : ImplInitDepth( nPara, pPara->GetDepth(), sal_False );
393 : }
394 : else
395 : {
396 162 : XubString aText(convertLineEnd(rText, LINEEND_LF));
397 :
398 162 : if( aText.GetChar( aText.Len()-1 ) == '\x0A' )
399 0 : aText.Erase( aText.Len()-1, 1 ); // Delete the last break
400 :
401 162 : sal_uInt16 nCount = comphelper::string::getTokenCount(aText, '\x0A');
402 162 : sal_uInt16 nPos = 0;
403 162 : sal_uInt16 nInsPos = nPara+1;
404 582 : while( nCount > nPos )
405 : {
406 258 : XubString aStr = aText.GetToken( nPos, '\x0A' );
407 :
408 : sal_Int16 nCurDepth;
409 258 : if( nPos )
410 : {
411 96 : pPara = new Paragraph( -1 );
412 96 : nCurDepth = -1;
413 : }
414 : else
415 162 : nCurDepth = pPara->GetDepth();
416 :
417 : // In the outliner mode, filter the tabs and set the indentation
418 : // about a LRSpaceItem. In EditEngine mode intend over old tabs
419 394 : if( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) ||
420 136 : ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ) )
421 : {
422 : // Extract Tabs
423 122 : sal_uInt16 nTabs = 0;
424 702 : while ( ( nTabs < aStr.Len() ) && ( aStr.GetChar( nTabs ) == '\t' ) )
425 458 : nTabs++;
426 122 : if ( nTabs )
427 122 : aStr.Erase( 0, nTabs );
428 :
429 : // Keep depth? (see Outliner::Insert)
430 122 : if( !(pPara->nFlags & PARAFLAG_HOLDDEPTH) )
431 : {
432 122 : nCurDepth = nTabs-1;
433 122 : ImplCheckDepth( nCurDepth );
434 122 : pPara->SetDepth( nCurDepth );
435 122 : pPara->nFlags &= (~PARAFLAG_HOLDDEPTH);
436 : }
437 : }
438 258 : if( nPos ) // not with the first paragraph
439 : {
440 96 : pParaList->Insert( pPara, nInsPos );
441 96 : pEditEngine->InsertParagraph( nInsPos, aStr );
442 96 : pHdlParagraph = pPara;
443 96 : ParagraphInsertedHdl();
444 : }
445 : else
446 : {
447 162 : nInsPos--;
448 162 : pEditEngine->SetText( nInsPos, aStr );
449 : }
450 258 : ImplInitDepth( nInsPos, nCurDepth, sal_False );
451 258 : nInsPos++;
452 258 : nPos++;
453 420 : }
454 : }
455 :
456 : DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"SetText failed!");
457 2046 : bFirstParaIsEmpty = sal_False;
458 2046 : ImplBlockInsertionCallbacks( sal_False );
459 2046 : pEditEngine->SetUpdateMode( bUpdate );
460 2046 : }
461 :
462 : // pView == 0 -> Ignore tabs
463 :
464 0 : bool Outliner::ImpConvertEdtToOut( sal_uInt32 nPara,EditView* pView)
465 : {
466 : DBG_CHKTHIS(Outliner,0);
467 :
468 0 : bool bConverted = false;
469 0 : sal_uInt16 nTabs = 0;
470 0 : ESelection aDelSel;
471 :
472 : // const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nPara );
473 : // bool bAlreadyOutliner = rAttrs.GetItemState( EE_PARA_OUTLLRSPACE ) == SFX_ITEM_ON ? true : false;
474 :
475 0 : XubString aName;
476 0 : XubString aHeading_US( RTL_CONSTASCII_USTRINGPARAM( "heading" ) );
477 0 : XubString aNumber_US( RTL_CONSTASCII_USTRINGPARAM( "Numbering" ) );
478 :
479 0 : XubString aStr( pEditEngine->GetText( (sal_uInt16)nPara ) );
480 0 : sal_Unicode* pPtr = (sal_Unicode*)aStr.GetBuffer();
481 :
482 0 : sal_uInt16 nHeadingNumberStart = 0;
483 0 : sal_uInt16 nNumberingNumberStart = 0;
484 0 : SfxStyleSheet* pStyle= pEditEngine->GetStyleSheet( (sal_uInt16)nPara );
485 0 : if( pStyle )
486 : {
487 0 : aName = pStyle->GetName();
488 : sal_uInt16 nSearch;
489 0 : if ( ( nSearch = aName.Search( aHeading_US ) ) != STRING_NOTFOUND )
490 0 : nHeadingNumberStart = nSearch + aHeading_US.Len();
491 0 : else if ( ( nSearch = aName.Search( aNumber_US ) ) != STRING_NOTFOUND )
492 0 : nNumberingNumberStart = nSearch + aNumber_US.Len();
493 : }
494 :
495 0 : if ( nHeadingNumberStart || nNumberingNumberStart )
496 : {
497 : // PowerPoint import ?
498 0 : if( nHeadingNumberStart && ( aStr.Len() >= 2 ) &&
499 0 : ( pPtr[0] != '\t' ) && ( pPtr[1] == '\t' ) )
500 : {
501 : // Extract Bullet and Tab
502 0 : aDelSel = ESelection( (sal_uInt16)nPara, 0, (sal_uInt16)nPara, 2 );
503 : }
504 :
505 0 : sal_uInt16 nPos = nHeadingNumberStart ? nHeadingNumberStart : nNumberingNumberStart;
506 0 : String aLevel = comphelper::string::stripStart(aName.Copy(nPos), ' ');
507 0 : nTabs = sal::static_int_cast< sal_uInt16 >(aLevel.ToInt32());
508 0 : if( nTabs )
509 0 : nTabs--; // Level 0 = "heading 1"
510 0 : bConverted = sal_True;
511 : }
512 : else
513 : {
514 : // filter leading tabs
515 0 : while( *pPtr == '\t' )
516 : {
517 0 : pPtr++;
518 0 : nTabs++;
519 : }
520 : // Remove tabs from the text
521 0 : if( nTabs )
522 0 : aDelSel = ESelection( (sal_uInt16)nPara, 0, (sal_uInt16)nPara, nTabs );
523 : }
524 :
525 0 : if ( aDelSel.HasRange() )
526 : {
527 0 : if ( pView )
528 : {
529 0 : pView->SetSelection( aDelSel );
530 0 : pView->DeleteSelected();
531 : }
532 : else
533 0 : pEditEngine->QuickDelete( aDelSel );
534 : }
535 :
536 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( sal::static_int_cast< sal_uInt16 >(nPara), EE_PARA_OUTLLEVEL );
537 0 : sal_Int16 nOutlLevel = rLevel.GetValue();
538 :
539 0 : ImplCheckDepth( nOutlLevel );
540 0 : ImplInitDepth( sal::static_int_cast< sal_uInt16 >(nPara), nOutlLevel, sal_False );
541 :
542 0 : return bConverted;
543 : }
544 :
545 12323 : void Outliner::SetText( const OutlinerParaObject& rPObj )
546 : {
547 : DBG_CHKTHIS(Outliner,0);
548 :
549 12323 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
550 12323 : pEditEngine->SetUpdateMode( sal_False );
551 :
552 12323 : sal_Bool bUndo = pEditEngine->IsUndoEnabled();
553 12323 : EnableUndo( sal_False );
554 :
555 12323 : Init( rPObj.GetOutlinerMode() );
556 :
557 12323 : ImplBlockInsertionCallbacks( sal_True );
558 12323 : pEditEngine->SetText(rPObj.GetTextObject());
559 :
560 12323 : bFirstParaIsEmpty = sal_False;
561 :
562 12323 : pParaList->Clear( sal_True );
563 25198 : for( sal_uInt16 nCurPara = 0; nCurPara < rPObj.Count(); nCurPara++ )
564 : {
565 12875 : Paragraph* pPara = new Paragraph( rPObj.GetParagraphData(nCurPara));
566 12875 : ImplCheckDepth( pPara->nDepth );
567 :
568 12875 : pParaList->Append(pPara);
569 12875 : ImplCheckNumBulletItem( nCurPara );
570 : }
571 :
572 : // #i100014#
573 : // It is not a good idea to substract 1 from a count and cast the result
574 : // to sal_uInt16 without check, if the count is 0.
575 12323 : ImplCheckParagraphs( 0, (sal_uInt16) (pParaList->GetParagraphCount()) );
576 :
577 12323 : EnableUndo( bUndo );
578 12323 : ImplBlockInsertionCallbacks( sal_False );
579 12323 : pEditEngine->SetUpdateMode( bUpdate );
580 :
581 : DBG_ASSERT( pParaList->GetParagraphCount()==rPObj.Count(),"SetText failed");
582 : DBG_ASSERT( pEditEngine->GetParagraphCount()==rPObj.Count(),"SetText failed");
583 12323 : }
584 :
585 0 : void Outliner::AddText( const OutlinerParaObject& rPObj )
586 : {
587 : DBG_CHKTHIS(Outliner,0);
588 : Paragraph* pPara;
589 :
590 0 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
591 0 : pEditEngine->SetUpdateMode( sal_False );
592 :
593 0 : ImplBlockInsertionCallbacks( sal_True );
594 : sal_uLong nPara;
595 0 : if( bFirstParaIsEmpty )
596 : {
597 0 : pParaList->Clear( sal_True );
598 0 : pEditEngine->SetText(rPObj.GetTextObject());
599 0 : nPara = 0;
600 : }
601 : else
602 : {
603 0 : nPara = pParaList->GetParagraphCount();
604 0 : pEditEngine->InsertParagraph( EE_PARA_APPEND, rPObj.GetTextObject() );
605 : }
606 0 : bFirstParaIsEmpty = sal_False;
607 :
608 0 : for( sal_uInt16 n = 0; n < rPObj.Count(); n++ )
609 : {
610 0 : pPara = new Paragraph( rPObj.GetParagraphData(n) );
611 0 : pParaList->Append(pPara);
612 0 : sal_uInt16 nP = sal::static_int_cast< sal_uInt16 >(nPara+n);
613 : DBG_ASSERT(pParaList->GetAbsPos(pPara)==nP,"AddText:Out of sync");
614 0 : ImplInitDepth( nP, pPara->GetDepth(), sal_False );
615 : }
616 : DBG_ASSERT( pEditEngine->GetParagraphCount()==pParaList->GetParagraphCount(), "SetText: OutOfSync" );
617 :
618 : // #i100014#
619 : // It is not a good idea to substract 1 from a count and cast the result
620 : // to sal_uInt16 without check, if the count is 0.
621 0 : ImplCheckParagraphs( (sal_uInt16)nPara, (sal_uInt16) (pParaList->GetParagraphCount()) );
622 :
623 0 : ImplBlockInsertionCallbacks( sal_False );
624 0 : pEditEngine->SetUpdateMode( bUpdate );
625 0 : }
626 :
627 0 : void Outliner::FieldClicked( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos )
628 : {
629 : DBG_CHKTHIS(Outliner,0);
630 :
631 0 : if ( aFieldClickedHdl.IsSet() )
632 : {
633 0 : EditFieldInfo aFldInfo( this, rField, nPara, nPos );
634 0 : aFldInfo.SetSimpleClick( sal_True );
635 0 : aFieldClickedHdl.Call( &aFldInfo );
636 : }
637 0 : }
638 :
639 :
640 0 : void Outliner::FieldSelected( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos )
641 : {
642 : DBG_CHKTHIS(Outliner,0);
643 0 : if ( !aFieldClickedHdl.IsSet() )
644 0 : return;
645 :
646 0 : EditFieldInfo aFldInfo( this, rField, nPara, nPos );
647 0 : aFldInfo.SetSimpleClick( sal_False );
648 0 : aFieldClickedHdl.Call( &aFldInfo );
649 : }
650 :
651 :
652 388 : XubString Outliner::CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rpTxtColor, Color*& rpFldColor )
653 : {
654 : DBG_CHKTHIS(Outliner,0);
655 388 : if ( !aCalcFieldValueHdl.IsSet() )
656 0 : return rtl::OUString( ' ' );
657 :
658 388 : EditFieldInfo aFldInfo( this, rField, nPara, nPos );
659 : // The FldColor is preset with COL_LIGHTGRAY.
660 388 : if ( rpFldColor )
661 0 : aFldInfo.SetFldColor( *rpFldColor );
662 :
663 388 : aCalcFieldValueHdl.Call( &aFldInfo );
664 388 : if ( aFldInfo.GetTxtColor() )
665 : {
666 0 : delete rpTxtColor;
667 0 : rpTxtColor = new Color( *aFldInfo.GetTxtColor() );
668 : }
669 :
670 388 : delete rpFldColor;
671 388 : rpFldColor = aFldInfo.GetFldColor() ? new Color( *aFldInfo.GetFldColor() ) : 0;
672 :
673 388 : return aFldInfo.GetRepresentation();
674 : }
675 :
676 4451 : void Outliner::SetStyleSheet( sal_uLong nPara, SfxStyleSheet* pStyle )
677 : {
678 : DBG_CHKTHIS(Outliner,0);
679 4451 : Paragraph* pPara = pParaList->GetParagraph( nPara );
680 4451 : if (pPara)
681 : {
682 4451 : pEditEngine->SetStyleSheet( (sal_uInt16)nPara, pStyle );
683 4451 : pPara->nFlags |= PARAFLAG_SETBULLETTEXT;
684 4451 : ImplCheckNumBulletItem( (sal_uInt16) nPara );
685 : }
686 4451 : }
687 :
688 112724 : void Outliner::ImplCheckNumBulletItem( sal_uInt16 nPara )
689 : {
690 112724 : Paragraph* pPara = pParaList->GetParagraph( nPara );
691 112724 : if (pPara)
692 112724 : pPara->aBulSize.Width() = -1;
693 112724 : }
694 :
695 66 : void Outliner::ImplSetLevelDependendStyleSheet( sal_uInt16 nPara, SfxStyleSheet* pLevelStyle )
696 : {
697 : DBG_CHKTHIS(Outliner,0);
698 :
699 : DBG_ASSERT( ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEOBJECT ) || ( ImplGetOutlinerMode() == OUTLINERMODE_OUTLINEVIEW ), "SetLevelDependendStyleSheet: Wrong Mode!" );
700 :
701 66 : SfxStyleSheet* pStyle = pLevelStyle;
702 66 : if ( !pStyle )
703 66 : pStyle = GetStyleSheet( nPara );
704 :
705 66 : if ( pStyle )
706 : {
707 66 : sal_Int16 nDepth = GetDepth( nPara );
708 66 : if( nDepth < 0 )
709 26 : nDepth = 0;
710 :
711 66 : String aNewStyleSheetName( pStyle->GetName() );
712 66 : aNewStyleSheetName.Erase( aNewStyleSheetName.Len()-1, 1 );
713 66 : aNewStyleSheetName += String::CreateFromInt32( nDepth+1 );
714 66 : SfxStyleSheet* pNewStyle = (SfxStyleSheet*)GetStyleSheetPool()->Find( aNewStyleSheetName, pStyle->GetFamily() );
715 : DBG_ASSERT( pNewStyle, "AutoStyleSheetName - Style not found!" );
716 66 : if ( pNewStyle && ( pNewStyle != GetStyleSheet( nPara ) ) )
717 : {
718 7 : SfxItemSet aOldAttrs( GetParaAttribs( nPara ) );
719 7 : SetStyleSheet( nPara, pNewStyle );
720 7 : if ( aOldAttrs.GetItemState( EE_PARA_NUMBULLET ) == SFX_ITEM_ON )
721 : {
722 6 : SfxItemSet aAttrs( GetParaAttribs( nPara ) );
723 6 : aAttrs.Put( aOldAttrs.Get( EE_PARA_NUMBULLET ) );
724 6 : SetParaAttribs( nPara, aAttrs );
725 7 : }
726 66 : }
727 : }
728 66 : }
729 :
730 44071 : void Outliner::ImplInitDepth( sal_uInt16 nPara, sal_Int16 nDepth, sal_Bool bCreateUndo, sal_Bool bUndoAction )
731 : {
732 : DBG_CHKTHIS(Outliner,0);
733 :
734 : DBG_ASSERT( ( nDepth >= nMinDepth ) && ( nDepth <= nMaxDepth ), "ImplInitDepth - Depth is invalid!" );
735 :
736 44071 : Paragraph* pPara = pParaList->GetParagraph( nPara );
737 44071 : if (!pPara)
738 44071 : return;
739 44071 : sal_Int16 nOldDepth = pPara->GetDepth();
740 44071 : pPara->SetDepth( nDepth );
741 :
742 : // For IsInUndo attributes and style do not have to be set, there
743 : // the old values are restored by the EditEngine.
744 44071 : if( !IsInUndo() )
745 : {
746 44071 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
747 44071 : pEditEngine->SetUpdateMode( sal_False );
748 :
749 44071 : sal_Bool bUndo = bCreateUndo && IsUndoEnabled();
750 44071 : if ( bUndo && bUndoAction )
751 0 : UndoActionStart( OLUNDO_DEPTH );
752 :
753 44071 : SfxItemSet aAttrs( pEditEngine->GetParaAttribs( nPara ) );
754 44071 : aAttrs.Put( SfxInt16Item( EE_PARA_OUTLLEVEL, nDepth ) );
755 44071 : pEditEngine->SetParaAttribs( nPara, aAttrs );
756 44071 : ImplCheckNumBulletItem( nPara );
757 44071 : ImplCalcBulletText( nPara, sal_False, sal_False );
758 :
759 44071 : if ( bUndo )
760 : {
761 0 : InsertUndo( new OutlinerUndoChangeDepth( this, nPara, nOldDepth, nDepth ) );
762 0 : if ( bUndoAction )
763 0 : UndoActionEnd( OLUNDO_DEPTH );
764 : }
765 :
766 44071 : pEditEngine->SetUpdateMode( bUpdate );
767 : }
768 : }
769 :
770 7208 : void Outliner::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rSet )
771 : {
772 : DBG_CHKTHIS(Outliner,0);
773 :
774 7208 : pEditEngine->SetParaAttribs( nPara, rSet );
775 7208 : }
776 :
777 0 : sal_Bool Outliner::Expand( Paragraph* pPara )
778 : {
779 : DBG_CHKTHIS(Outliner,0);
780 :
781 0 : if ( pParaList->HasHiddenChildren( pPara ) )
782 : {
783 0 : OLUndoExpand* pUndo = 0;
784 0 : sal_Bool bUndo = IsUndoEnabled() && !IsInUndo();
785 0 : if( bUndo )
786 : {
787 0 : UndoActionStart( OLUNDO_EXPAND );
788 0 : pUndo = new OLUndoExpand( this, OLUNDO_EXPAND );
789 0 : pUndo->pParas = 0;
790 0 : pUndo->nCount = (sal_uInt16)pParaList->GetAbsPos( pPara );
791 : }
792 0 : pHdlParagraph = pPara;
793 0 : bIsExpanding = sal_True;
794 0 : pParaList->Expand( pPara );
795 0 : ExpandHdl();
796 0 : InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
797 0 : if( bUndo )
798 : {
799 0 : InsertUndo( pUndo );
800 0 : UndoActionEnd( OLUNDO_EXPAND );
801 : }
802 0 : return sal_True;
803 : }
804 0 : return sal_False;
805 : }
806 :
807 :
808 0 : sal_Bool Outliner::Collapse( Paragraph* pPara )
809 : {
810 : DBG_CHKTHIS(Outliner,0);
811 0 : if ( pParaList->HasVisibleChildren( pPara ) ) // expanded
812 : {
813 0 : OLUndoExpand* pUndo = 0;
814 0 : sal_Bool bUndo = sal_False;
815 :
816 0 : if( !IsInUndo() && IsUndoEnabled() )
817 0 : bUndo = sal_True;
818 0 : if( bUndo )
819 : {
820 0 : UndoActionStart( OLUNDO_COLLAPSE );
821 0 : pUndo = new OLUndoExpand( this, OLUNDO_COLLAPSE );
822 0 : pUndo->pParas = 0;
823 0 : pUndo->nCount = (sal_uInt16)pParaList->GetAbsPos( pPara );
824 : }
825 :
826 0 : pHdlParagraph = pPara;
827 0 : bIsExpanding = sal_False;
828 0 : pParaList->Collapse( pPara );
829 0 : ExpandHdl();
830 0 : InvalidateBullet( pPara, pParaList->GetAbsPos(pPara) );
831 0 : if( bUndo )
832 : {
833 0 : InsertUndo( pUndo );
834 0 : UndoActionEnd( OLUNDO_COLLAPSE );
835 : }
836 0 : return sal_True;
837 : }
838 0 : return sal_False;
839 : }
840 :
841 :
842 475 : Font Outliner::ImpCalcBulletFont( sal_uInt16 nPara ) const
843 : {
844 475 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
845 : DBG_ASSERT( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ), "ImpCalcBulletFont: Missing or BitmapBullet!" );
846 :
847 475 : Font aStdFont;
848 475 : if ( !pEditEngine->IsFlatMode() )
849 : {
850 475 : ESelection aSel( nPara, 0, nPara, 0 );
851 475 : aStdFont = EditEngine::CreateFontFromItemSet( pEditEngine->GetAttribs( aSel ), GetScriptType( aSel ) );
852 : }
853 : else
854 : {
855 0 : aStdFont = pEditEngine->GetStandardFont( nPara );
856 : }
857 :
858 475 : Font aBulletFont;
859 475 : if ( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
860 : {
861 475 : aBulletFont = *pFmt->GetBulletFont();
862 : }
863 : else
864 : {
865 0 : aBulletFont = aStdFont;
866 0 : aBulletFont.SetUnderline( UNDERLINE_NONE );
867 0 : aBulletFont.SetOverline( UNDERLINE_NONE );
868 0 : aBulletFont.SetStrikeout( STRIKEOUT_NONE );
869 0 : aBulletFont.SetEmphasisMark( EMPHASISMARK_NONE );
870 0 : aBulletFont.SetRelief( RELIEF_NONE );
871 : }
872 :
873 : // Use original scale...
874 : sal_uInt16 nStretchX, nStretchY;
875 475 : const_cast<Outliner*>(this)->GetGlobalCharStretching(nStretchX, nStretchY);
876 :
877 475 : sal_uInt16 nScale = pFmt->GetBulletRelSize() * nStretchY / 100;
878 475 : sal_uLong nScaledLineHeight = aStdFont.GetSize().Height();
879 475 : nScaledLineHeight *= nScale*10;
880 475 : nScaledLineHeight /= 1000;
881 :
882 475 : aBulletFont.SetAlign( ALIGN_BOTTOM );
883 475 : aBulletFont.SetSize( Size( 0, nScaledLineHeight ) );
884 475 : sal_Bool bVertical = IsVertical();
885 475 : aBulletFont.SetVertical( bVertical );
886 475 : aBulletFont.SetOrientation( bVertical ? 2700 : 0 );
887 :
888 475 : Color aColor( COL_AUTO );
889 475 : if( !pEditEngine->IsFlatMode() && !( pEditEngine->GetControlWord() & EE_CNTRL_NOCOLORS ) )
890 : {
891 475 : aColor = pFmt->GetBulletColor();
892 : }
893 :
894 475 : if ( ( aColor == COL_AUTO ) || ( IsForceAutoColor() ) )
895 279 : aColor = pEditEngine->GetAutoColor();
896 :
897 475 : aBulletFont.SetColor( aColor );
898 475 : return aBulletFont;
899 : }
900 :
901 155 : void Outliner::PaintBullet( sal_uInt16 nPara, const Point& rStartPos,
902 : const Point& rOrigin, short nOrientation, OutputDevice* pOutDev )
903 : {
904 : DBG_CHKTHIS(Outliner,0);
905 :
906 155 : bool bDrawBullet = false;
907 155 : if (pEditEngine)
908 : {
909 155 : const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
910 155 : bDrawBullet = rBulletState.GetValue() ? true : false;
911 : }
912 :
913 155 : if ( ImplHasBullet( nPara ) && bDrawBullet)
914 : {
915 28 : sal_Bool bVertical = IsVertical();
916 :
917 28 : sal_Bool bRightToLeftPara = pEditEngine->IsRightToLeft( nPara );
918 :
919 28 : Rectangle aBulletArea( ImpCalcBulletArea( nPara, sal_True, sal_False ) );
920 : sal_uInt16 nStretchX, nStretchY;
921 28 : GetGlobalCharStretching(nStretchX, nStretchY);
922 28 : aBulletArea = Rectangle( Point(aBulletArea.Left()*nStretchX/100,
923 28 : aBulletArea.Top()),
924 28 : Size(aBulletArea.GetWidth()*nStretchX/100,
925 112 : aBulletArea.GetHeight()) );
926 :
927 28 : Paragraph* pPara = pParaList->GetParagraph( nPara );
928 28 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
929 28 : if ( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) )
930 : {
931 28 : if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
932 : {
933 28 : Font aBulletFont( ImpCalcBulletFont( nPara ) );
934 : // Use baseline
935 28 : sal_Bool bSymbol = pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL;
936 28 : aBulletFont.SetAlign( bSymbol ? ALIGN_BOTTOM : ALIGN_BASELINE );
937 28 : Font aOldFont = pOutDev->GetFont();
938 28 : pOutDev->SetFont( aBulletFont );
939 :
940 28 : ParagraphInfos aParaInfos = pEditEngine->GetParagraphInfos( nPara );
941 28 : Point aTextPos;
942 28 : if ( !bVertical )
943 : {
944 : // aTextPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
945 28 : aTextPos.Y() = rStartPos.Y() + ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
946 28 : if ( !bRightToLeftPara )
947 28 : aTextPos.X() = rStartPos.X() + aBulletArea.Left();
948 : else
949 0 : aTextPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
950 : }
951 : else
952 : {
953 : // aTextPos.X() = rStartPos.X() - aBulletArea.Bottom();
954 0 : aTextPos.X() = rStartPos.X() - ( bSymbol ? aBulletArea.Bottom() : aParaInfos.nFirstLineMaxAscent );
955 0 : aTextPos.Y() = rStartPos.Y() + aBulletArea.Left();
956 : }
957 :
958 28 : if ( nOrientation )
959 : {
960 : // Both TopLeft and bottom left is not quite correct,
961 : // since in EditEngine baseline ...
962 0 : double nRealOrientation = nOrientation*F_PI1800;
963 0 : double nCos = cos( nRealOrientation );
964 0 : double nSin = sin( nRealOrientation );
965 0 : Point aRotatedPos;
966 : // Translation...
967 0 : aTextPos -= rOrigin;
968 : // Rotation...
969 0 : aRotatedPos.X()=(long) (nCos*aTextPos.X() + nSin*aTextPos.Y());
970 0 : aRotatedPos.Y()=(long) - (nSin*aTextPos.X() - nCos*aTextPos.Y());
971 0 : aTextPos = aRotatedPos;
972 : // Translation...
973 0 : aTextPos += rOrigin;
974 0 : Font aRotatedFont( aBulletFont );
975 0 : aRotatedFont.SetOrientation( nOrientation );
976 0 : pOutDev->SetFont( aRotatedFont );
977 : }
978 :
979 : // VCL will take care of brackets and so on...
980 28 : sal_uLong nLayoutMode = pOutDev->GetLayoutMode();
981 28 : nLayoutMode &= ~(TEXT_LAYOUT_BIDI_RTL|TEXT_LAYOUT_COMPLEX_DISABLED|TEXT_LAYOUT_BIDI_STRONG);
982 28 : if ( bRightToLeftPara )
983 0 : nLayoutMode |= TEXT_LAYOUT_BIDI_RTL;
984 28 : pOutDev->SetLayoutMode( nLayoutMode );
985 :
986 28 : if(bStrippingPortions)
987 : {
988 28 : const Font aSvxFont(pOutDev->GetFont());
989 28 : sal_Int32* pBuf = new sal_Int32[ pPara->GetText().getLength() ];
990 28 : pOutDev->GetTextArray( pPara->GetText(), pBuf );
991 :
992 28 : if(bSymbol)
993 : {
994 : // aTextPos is Bottom, go to Baseline
995 28 : FontMetric aMetric(pOutDev->GetFontMetric());
996 28 : aTextPos.Y() -= aMetric.GetDescent();
997 : }
998 :
999 56 : DrawingText(aTextPos, pPara->GetText(), 0, pPara->GetText().getLength(), pBuf,
1000 84 : aSvxFont, nPara, 0xFFFF, 0xFF, 0, 0, false, false, true, 0, Color(), Color());
1001 :
1002 28 : delete[] pBuf;
1003 : }
1004 : else
1005 : {
1006 0 : pOutDev->DrawText( aTextPos, pPara->GetText() );
1007 : }
1008 :
1009 28 : pOutDev->SetFont( aOldFont );
1010 : }
1011 : else
1012 : {
1013 0 : if ( pFmt->GetBrush()->GetGraphicObject() )
1014 : {
1015 0 : Point aBulletPos;
1016 0 : if ( !bVertical )
1017 : {
1018 0 : aBulletPos.Y() = rStartPos.Y() + aBulletArea.Top();
1019 0 : if ( !bRightToLeftPara )
1020 0 : aBulletPos.X() = rStartPos.X() + aBulletArea.Left();
1021 : else
1022 0 : aBulletPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Right();
1023 : }
1024 : else
1025 : {
1026 0 : aBulletPos.X() = rStartPos.X() - aBulletArea.Bottom();
1027 0 : aBulletPos.Y() = rStartPos.Y() + aBulletArea.Left();
1028 : }
1029 :
1030 0 : if(bStrippingPortions)
1031 : {
1032 0 : if(aDrawBulletHdl.IsSet())
1033 : {
1034 : // call something analog to aDrawPortionHdl (if set) and feed it something
1035 : // analog to DrawPortionInfo...
1036 : // created aDrawBulletHdl, Set/GetDrawBulletHdl.
1037 : // created DrawBulletInfo and added handling to sdrtextdecomposition.cxx
1038 : DrawBulletInfo aDrawBulletInfo(
1039 0 : *pFmt->GetBrush()->GetGraphicObject(),
1040 : aBulletPos,
1041 0 : pPara->aBulSize);
1042 :
1043 0 : aDrawBulletHdl.Call(&aDrawBulletInfo);
1044 : }
1045 : }
1046 : else
1047 : {
1048 : // Remove CAST when KA made the Draw-Method const
1049 0 : ((GraphicObject*)pFmt->GetBrush()->GetGraphicObject())->Draw( pOutDev, aBulletPos, pPara->aBulSize );
1050 : }
1051 : }
1052 : }
1053 : }
1054 :
1055 : // In case of collapsed subparagraphs paint a line before the text.
1056 28 : if( pParaList->HasChildren(pPara) && !pParaList->HasVisibleChildren(pPara) &&
1057 0 : !bStrippingPortions && !nOrientation )
1058 : {
1059 0 : long nWidth = pOutDev->PixelToLogic( Size( 10, 0 ) ).Width();
1060 :
1061 0 : Point aStartPos, aEndPos;
1062 0 : if ( !bVertical )
1063 : {
1064 0 : aStartPos.Y() = rStartPos.Y() + aBulletArea.Bottom();
1065 0 : if ( !bRightToLeftPara )
1066 0 : aStartPos.X() = rStartPos.X() + aBulletArea.Right();
1067 : else
1068 0 : aStartPos.X() = rStartPos.X() + GetPaperSize().Width() - aBulletArea.Left();
1069 0 : aEndPos = aStartPos;
1070 0 : aEndPos.X() += nWidth;
1071 : }
1072 : else
1073 : {
1074 0 : aStartPos.X() = rStartPos.X() - aBulletArea.Bottom();
1075 0 : aStartPos.Y() = rStartPos.Y() + aBulletArea.Right();
1076 0 : aEndPos = aStartPos;
1077 0 : aEndPos.Y() += nWidth;
1078 : }
1079 :
1080 0 : const Color& rOldLineColor = pOutDev->GetLineColor();
1081 0 : pOutDev->SetLineColor( Color( COL_BLACK ) );
1082 0 : pOutDev->DrawLine( aStartPos, aEndPos );
1083 0 : pOutDev->SetLineColor( rOldLineColor );
1084 : }
1085 : }
1086 155 : }
1087 :
1088 0 : void Outliner::InvalidateBullet( Paragraph* /*pPara*/, sal_uLong nPara )
1089 : {
1090 : DBG_CHKTHIS(Outliner,0);
1091 :
1092 0 : long nLineHeight = (long)pEditEngine->GetLineHeight((sal_uInt16)nPara );
1093 0 : for ( size_t i = 0, n = aViewList.size(); i < n; ++i )
1094 : {
1095 0 : OutlinerView* pView = aViewList[ i ];
1096 0 : Point aPos( pView->pEditView->GetWindowPosTopLeft((sal_uInt16)nPara ) );
1097 0 : Rectangle aRect( pView->GetOutputArea() );
1098 0 : aRect.Right() = aPos.X();
1099 0 : aRect.Top() = aPos.Y();
1100 0 : aRect.Bottom() = aPos.Y();
1101 0 : aRect.Bottom() += nLineHeight;
1102 :
1103 0 : pView->GetWindow()->Invalidate( aRect );
1104 : }
1105 0 : }
1106 :
1107 0 : sal_uLong Outliner::Read( SvStream& rInput, const String& rBaseURL, sal_uInt16 eFormat, SvKeyValueIterator* pHTTPHeaderAttrs )
1108 : {
1109 : DBG_CHKTHIS(Outliner,0);
1110 :
1111 0 : sal_Bool bOldUndo = pEditEngine->IsUndoEnabled();
1112 0 : EnableUndo( sal_False );
1113 :
1114 0 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1115 0 : pEditEngine->SetUpdateMode( sal_False );
1116 :
1117 0 : Clear();
1118 :
1119 0 : ImplBlockInsertionCallbacks( sal_True );
1120 0 : sal_uLong nRet = pEditEngine->Read( rInput, rBaseURL, (EETextFormat)eFormat, pHTTPHeaderAttrs );
1121 :
1122 0 : bFirstParaIsEmpty = sal_False;
1123 :
1124 0 : sal_uInt16 nParas = pEditEngine->GetParagraphCount();
1125 0 : pParaList->Clear( sal_True );
1126 : sal_uInt16 n;
1127 0 : for ( n = 0; n < nParas; n++ )
1128 : {
1129 0 : Paragraph* pPara = new Paragraph( 0 );
1130 0 : pParaList->Append(pPara);
1131 :
1132 0 : if ( eFormat == EE_FORMAT_BIN )
1133 : {
1134 0 : const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( n );
1135 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
1136 0 : sal_Int16 nDepth = rLevel.GetValue();
1137 0 : ImplInitDepth( n, nDepth, sal_False );
1138 : }
1139 : }
1140 :
1141 0 : if ( eFormat != EE_FORMAT_BIN )
1142 : {
1143 0 : ImpFilterIndents( 0, nParas-1 );
1144 : }
1145 :
1146 0 : ImplBlockInsertionCallbacks( sal_False );
1147 0 : pEditEngine->SetUpdateMode( bUpdate );
1148 0 : EnableUndo( bOldUndo );
1149 :
1150 0 : return nRet;
1151 : }
1152 :
1153 :
1154 0 : void Outliner::ImpFilterIndents( sal_uLong nFirstPara, sal_uLong nLastPara )
1155 : {
1156 : DBG_CHKTHIS(Outliner,0);
1157 :
1158 0 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1159 0 : pEditEngine->SetUpdateMode( sal_False );
1160 :
1161 0 : Paragraph* pLastConverted = NULL;
1162 0 : for( sal_uLong nPara = nFirstPara; nPara <= nLastPara; nPara++ )
1163 : {
1164 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1165 0 : if (pPara)
1166 : {
1167 0 : if( ImpConvertEdtToOut( nPara ) )
1168 : {
1169 0 : pLastConverted = pPara;
1170 : }
1171 0 : else if ( pLastConverted )
1172 : {
1173 : // Arrange normal paragraphs below the heading ...
1174 0 : pPara->SetDepth( pLastConverted->GetDepth() );
1175 : }
1176 :
1177 0 : ImplInitDepth( (sal_uInt16)nPara, pPara->GetDepth(), sal_False );
1178 : }
1179 : }
1180 :
1181 0 : pEditEngine->SetUpdateMode( bUpdate );
1182 0 : }
1183 :
1184 41676 : ::svl::IUndoManager& Outliner::GetUndoManager()
1185 : {
1186 : DBG_CHKTHIS(Outliner,0);
1187 41676 : return pEditEngine->GetUndoManager();
1188 : }
1189 :
1190 0 : void Outliner::ImpTextPasted( sal_uLong nStartPara, sal_uInt16 nCount )
1191 : {
1192 : DBG_CHKTHIS(Outliner,0);
1193 :
1194 0 : sal_Bool bUpdate = pEditEngine->GetUpdateMode();
1195 0 : pEditEngine->SetUpdateMode( sal_False );
1196 :
1197 0 : const sal_uLong nStart = nStartPara;
1198 :
1199 0 : Paragraph* pPara = pParaList->GetParagraph( nStartPara );
1200 :
1201 0 : while( nCount && pPara )
1202 : {
1203 0 : if( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT )
1204 : {
1205 0 : nDepthChangedHdlPrevDepth = pPara->GetDepth();
1206 0 : mnDepthChangeHdlPrevFlags = pPara->nFlags;
1207 :
1208 0 : ImpConvertEdtToOut( nStartPara );
1209 :
1210 0 : pHdlParagraph = pPara;
1211 :
1212 0 : if( nStartPara == nStart )
1213 : {
1214 : // the existing paragraph has changed depth or flags
1215 0 : if( (pPara->GetDepth() != nDepthChangedHdlPrevDepth) || (pPara->nFlags != mnDepthChangeHdlPrevFlags) )
1216 0 : DepthChangedHdl();
1217 : }
1218 : }
1219 : else // EditEngine mode
1220 : {
1221 0 : sal_Int16 nDepth = -1;
1222 0 : const SfxItemSet& rAttrs = pEditEngine->GetParaAttribs( (sal_uInt16)nStartPara );
1223 0 : if ( rAttrs.GetItemState( EE_PARA_OUTLLEVEL ) == SFX_ITEM_ON )
1224 : {
1225 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) rAttrs.Get( EE_PARA_OUTLLEVEL );
1226 0 : nDepth = rLevel.GetValue();
1227 : }
1228 0 : if ( nDepth != GetDepth( nStartPara ) )
1229 0 : ImplInitDepth( (sal_uInt16)nStartPara, nDepth, sal_False );
1230 : }
1231 :
1232 0 : nCount--;
1233 0 : nStartPara++;
1234 0 : pPara = pParaList->GetParagraph( nStartPara );
1235 : }
1236 :
1237 0 : pEditEngine->SetUpdateMode( bUpdate );
1238 :
1239 : DBG_ASSERT(pParaList->GetParagraphCount()==pEditEngine->GetParagraphCount(),"ImpTextPasted failed");
1240 0 : }
1241 :
1242 0 : long Outliner::IndentingPagesHdl( OutlinerView* pView )
1243 : {
1244 : DBG_CHKTHIS(Outliner,0);
1245 0 : if( !aIndentingPagesHdl.IsSet() )
1246 0 : return 1;
1247 0 : return aIndentingPagesHdl.Call( pView );
1248 : }
1249 :
1250 0 : sal_Bool Outliner::ImpCanIndentSelectedPages( OutlinerView* pCurView )
1251 : {
1252 : DBG_CHKTHIS(Outliner,0);
1253 : // The selected pages must already be set in advance through
1254 : // ImpCalcSelectedPages
1255 :
1256 : // If the first paragraph is on level 0 it can not indented in any case,
1257 : // possible there might be indentations in the following on the 0 level.
1258 0 : if ( ( mnFirstSelPage == 0 ) && ( ImplGetOutlinerMode() != OUTLINERMODE_TEXTOBJECT ) )
1259 : {
1260 0 : if ( nDepthChangedHdlPrevDepth == 1 ) // is the only page
1261 0 : return sal_False;
1262 : else
1263 0 : pCurView->ImpCalcSelectedPages( sal_False ); // without the first
1264 : }
1265 0 : return (sal_Bool)IndentingPagesHdl( pCurView );
1266 : }
1267 :
1268 :
1269 0 : sal_Bool Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView )
1270 : {
1271 : DBG_CHKTHIS(Outliner,0);
1272 : // The selected pages must already be set in advance through
1273 : // ImpCalcSelectedPages
1274 0 : return (sal_Bool)RemovingPagesHdl( pCurView );
1275 : }
1276 :
1277 3250 : Outliner::Outliner( SfxItemPool* pPool, sal_uInt16 nMode )
1278 3250 : : nMinDepth( -1 )
1279 : {
1280 : DBG_CTOR( Outliner, 0 );
1281 :
1282 3250 : bStrippingPortions = sal_False;
1283 3250 : bPasting = sal_False;
1284 :
1285 3250 : nFirstPage = 1;
1286 3250 : bBlockInsCallback = sal_False;
1287 :
1288 3250 : nMaxDepth = 9;
1289 :
1290 3250 : pParaList = new ParagraphList;
1291 3250 : pParaList->SetVisibleStateChangedHdl( LINK( this, Outliner, ParaVisibleStateChangedHdl ) );
1292 3250 : Paragraph* pPara = new Paragraph( 0 );
1293 3250 : pParaList->Append(pPara);
1294 3250 : bFirstParaIsEmpty = sal_True;
1295 :
1296 3250 : pEditEngine = new OutlinerEditEng( this, pPool );
1297 3250 : pEditEngine->SetBeginMovingParagraphsHdl( LINK( this, Outliner, BeginMovingParagraphsHdl ) );
1298 3250 : pEditEngine->SetEndMovingParagraphsHdl( LINK( this, Outliner, EndMovingParagraphsHdl ) );
1299 3250 : pEditEngine->SetBeginPasteOrDropHdl( LINK( this, Outliner, BeginPasteOrDropHdl ) );
1300 3250 : pEditEngine->SetEndPasteOrDropHdl( LINK( this, Outliner, EndPasteOrDropHdl ) );
1301 :
1302 3250 : Init( nMode );
1303 3250 : }
1304 :
1305 5735 : Outliner::~Outliner()
1306 : {
1307 : DBG_DTOR(Outliner,0);
1308 :
1309 2857 : pParaList->Clear( sal_True );
1310 2857 : delete pParaList;
1311 2857 : delete pEditEngine;
1312 2878 : }
1313 :
1314 6 : size_t Outliner::InsertView( OutlinerView* pView, size_t nIndex )
1315 : {
1316 : DBG_CHKTHIS(Outliner,0);
1317 : size_t ActualIndex;
1318 :
1319 6 : if ( nIndex >= aViewList.size() )
1320 : {
1321 6 : aViewList.push_back( pView );
1322 6 : ActualIndex = aViewList.size() - 1;
1323 : }
1324 : else
1325 : {
1326 0 : ViewList::iterator it = aViewList.begin();
1327 0 : advance( it, nIndex );
1328 0 : ActualIndex = nIndex;
1329 : }
1330 6 : pEditEngine->InsertView( pView->pEditView, (sal_uInt16)nIndex );
1331 6 : return ActualIndex;
1332 : }
1333 :
1334 0 : OutlinerView* Outliner::RemoveView( OutlinerView* pView )
1335 : {
1336 : DBG_CHKTHIS(Outliner,0);
1337 :
1338 0 : for ( ViewList::iterator it = aViewList.begin(); it != aViewList.end(); ++it )
1339 : {
1340 0 : if ( *it == pView )
1341 : {
1342 0 : pView->pEditView->HideCursor(); // HACK
1343 0 : pEditEngine->RemoveView( pView->pEditView );
1344 0 : aViewList.erase( it );
1345 0 : break;
1346 : }
1347 : }
1348 0 : return NULL; // return superfluous
1349 : }
1350 :
1351 0 : OutlinerView* Outliner::RemoveView( size_t nIndex )
1352 : {
1353 : DBG_CHKTHIS(Outliner,0);
1354 :
1355 0 : EditView* pEditView = pEditEngine->GetView( (sal_uInt16)nIndex );
1356 0 : pEditView->HideCursor(); // HACK
1357 :
1358 0 : pEditEngine->RemoveView( (sal_uInt16)nIndex );
1359 :
1360 : {
1361 0 : ViewList::iterator it = aViewList.begin();
1362 0 : advance( it, nIndex );
1363 0 : aViewList.erase( it );
1364 : }
1365 :
1366 0 : return NULL; // return superfluous
1367 : }
1368 :
1369 :
1370 0 : OutlinerView* Outliner::GetView( size_t nIndex ) const
1371 : {
1372 : DBG_CHKTHIS(Outliner,0);
1373 0 : return ( nIndex >= aViewList.size() ) ? NULL : aViewList[ nIndex ];
1374 : }
1375 :
1376 0 : size_t Outliner::GetViewCount() const
1377 : {
1378 : DBG_CHKTHIS(Outliner,0);
1379 0 : return aViewList.size();
1380 : }
1381 :
1382 423 : void Outliner::ParagraphInsertedHdl()
1383 : {
1384 : DBG_CHKTHIS(Outliner,0);
1385 423 : if( !IsInUndo() )
1386 423 : aParaInsertedHdl.Call( this );
1387 423 : }
1388 :
1389 :
1390 104 : void Outliner::ParagraphRemovingHdl()
1391 : {
1392 : DBG_CHKTHIS(Outliner,0);
1393 104 : if( !IsInUndo() )
1394 104 : aParaRemovingHdl.Call( this );
1395 104 : }
1396 :
1397 :
1398 664 : void Outliner::DepthChangedHdl()
1399 : {
1400 : DBG_CHKTHIS(Outliner,0);
1401 664 : if( !IsInUndo() )
1402 664 : aDepthChangedHdl.Call( this );
1403 664 : }
1404 :
1405 :
1406 72 : sal_uLong Outliner::GetAbsPos( Paragraph* pPara )
1407 : {
1408 : DBG_CHKTHIS(Outliner,0);
1409 : DBG_ASSERT(pPara,"GetAbsPos:No Para");
1410 72 : return pParaList->GetAbsPos( pPara );
1411 : }
1412 :
1413 22843 : sal_uLong Outliner::GetParagraphCount() const
1414 : {
1415 : DBG_CHKTHIS(Outliner,0);
1416 22843 : return pParaList->GetParagraphCount();
1417 : }
1418 :
1419 12195 : Paragraph* Outliner::GetParagraph( sal_uLong nAbsPos ) const
1420 : {
1421 : DBG_CHKTHIS(Outliner,0);
1422 12195 : return pParaList->GetParagraph( nAbsPos );
1423 : }
1424 :
1425 0 : sal_Bool Outliner::HasChildren( Paragraph* pParagraph ) const
1426 : {
1427 : DBG_CHKTHIS(Outliner,0);
1428 0 : return pParaList->HasChildren( pParagraph );
1429 : }
1430 :
1431 22988 : sal_Bool Outliner::ImplHasBullet( sal_uInt16 nPara ) const
1432 : {
1433 22988 : return GetNumberFormat(nPara) != 0;
1434 : }
1435 :
1436 163501 : const SvxNumberFormat* Outliner::GetNumberFormat( sal_uInt16 nPara ) const
1437 : {
1438 163501 : const SvxNumberFormat* pFmt = NULL;
1439 :
1440 163501 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1441 163501 : if (pPara == NULL)
1442 0 : return NULL;
1443 :
1444 163501 : sal_Int16 nDepth = pPara? pPara->GetDepth() : -1;
1445 :
1446 163501 : if( nDepth >= 0 )
1447 : {
1448 21431 : const SvxNumBulletItem& rNumBullet = (const SvxNumBulletItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_NUMBULLET );
1449 21431 : if ( rNumBullet.GetNumRule()->GetLevelCount() > nDepth )
1450 21364 : pFmt = rNumBullet.GetNumRule()->Get( nDepth );
1451 : }
1452 :
1453 163501 : return pFmt;
1454 : }
1455 :
1456 2709 : Size Outliner::ImplGetBulletSize( sal_uInt16 nPara )
1457 : {
1458 2709 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1459 2709 : if (!pPara)
1460 0 : return Size();
1461 :
1462 2709 : if( pPara->aBulSize.Width() == -1 )
1463 : {
1464 2690 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1465 : DBG_ASSERT( pFmt, "ImplGetBulletSize - no Bullet!" );
1466 :
1467 2690 : if ( pFmt->GetNumberingType() == SVX_NUM_NUMBER_NONE )
1468 : {
1469 2243 : pPara->aBulSize = Size( 0, 0 );
1470 : }
1471 447 : else if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1472 : {
1473 447 : String aBulletText = ImplGetBulletText( nPara );
1474 447 : OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1475 447 : Font aBulletFont( ImpCalcBulletFont( nPara ) );
1476 447 : Font aRefFont( pRefDev->GetFont());
1477 447 : pRefDev->SetFont( aBulletFont );
1478 447 : pPara->aBulSize.Width() = pRefDev->GetTextWidth( aBulletText );
1479 447 : pPara->aBulSize.Height() = pRefDev->GetTextHeight();
1480 447 : pRefDev->SetFont( aRefFont );
1481 : }
1482 : else
1483 : {
1484 0 : pPara->aBulSize = OutputDevice::LogicToLogic( pFmt->GetGraphicSize(), MAP_100TH_MM, pEditEngine->GetRefDevice()->GetMapMode() );
1485 : }
1486 : }
1487 :
1488 2709 : return pPara->aBulSize;
1489 : }
1490 :
1491 63636 : void Outliner::ImplCheckParagraphs( sal_uInt16 nStart, sal_uInt16 nEnd )
1492 : {
1493 : DBG_CHKTHIS( Outliner, 0 );
1494 :
1495 : // i100014#
1496 : // assure that the following for-loop does not loop forever
1497 128121 : for ( sal_uInt16 n = nStart; n < nEnd; n++ )
1498 : {
1499 64485 : Paragraph* pPara = pParaList->GetParagraph( n );
1500 64485 : if (pPara)
1501 : {
1502 64485 : pPara->Invalidate();
1503 64485 : ImplCalcBulletText( n, sal_False, sal_False );
1504 : }
1505 : }
1506 63636 : }
1507 :
1508 3230 : void Outliner::SetRefDevice( OutputDevice* pRefDev )
1509 : {
1510 : DBG_CHKTHIS(Outliner,0);
1511 3230 : pEditEngine->SetRefDevice( pRefDev );
1512 9690 : for ( sal_uInt16 n = (sal_uInt16) pParaList->GetParagraphCount(); n; )
1513 : {
1514 3230 : Paragraph* pPara = pParaList->GetParagraph( --n );
1515 3230 : pPara->Invalidate();
1516 : }
1517 3230 : }
1518 :
1519 42106 : void Outliner::ParaAttribsChanged( sal_uInt16 nPara )
1520 : {
1521 : DBG_CHKTHIS(Outliner,0);
1522 :
1523 : // The Outliner does not have an undo of its own, when paragraphs are
1524 : // separated/merged. When ParagraphInserted the attribute EE_PARA_OUTLLEVEL
1525 : // may not be set, this is however needed when the depth of the paragraph
1526 : // is to be determined.
1527 42106 : if( pEditEngine->IsInUndo() )
1528 : {
1529 0 : if ( pParaList->GetParagraphCount() == pEditEngine->GetParagraphCount() )
1530 : {
1531 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1532 0 : const SfxInt16Item& rLevel = (const SfxInt16Item&) pEditEngine->GetParaAttrib( nPara, EE_PARA_OUTLLEVEL );
1533 0 : if ( pPara && pPara->GetDepth() != rLevel.GetValue() )
1534 : {
1535 0 : pPara->SetDepth( rLevel.GetValue() );
1536 0 : ImplCalcBulletText( nPara, sal_True, sal_True );
1537 : }
1538 : }
1539 : }
1540 42106 : }
1541 :
1542 0 : void Outliner::StyleSheetChanged( SfxStyleSheet* pStyle )
1543 : {
1544 : DBG_CHKTHIS(Outliner,0);
1545 :
1546 : // The EditEngine calls StyleSheetChanged also for derived styles.
1547 : // Here all the paragraphs, which had the said template, used to be
1548 : // hunted by a ImpRecalcParaAttribs, why?
1549 : // => only the Bullet-representation can really change...
1550 0 : sal_uInt16 nParas = (sal_uInt16)pParaList->GetParagraphCount();
1551 0 : for( sal_uInt16 nPara = 0; nPara < nParas; nPara++ )
1552 : {
1553 0 : if ( pEditEngine->GetStyleSheet( nPara ) == pStyle )
1554 : {
1555 0 : ImplCheckNumBulletItem( nPara );
1556 0 : ImplCalcBulletText( nPara, sal_False, sal_False );
1557 : // EditEngine formats changed paragraphs before calling this method,
1558 : // so they are not reformatted now and use wrong bullet indent
1559 0 : pEditEngine->QuickMarkInvalid( ESelection( nPara, 0, nPara, 0 ) );
1560 : }
1561 : }
1562 0 : }
1563 :
1564 2709 : Rectangle Outliner::ImpCalcBulletArea( sal_uInt16 nPara, sal_Bool bAdjust, sal_Bool bReturnPaperPos )
1565 : {
1566 : // Bullet area within the paragraph ...
1567 2709 : Rectangle aBulletArea;
1568 :
1569 2709 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1570 2709 : if ( pFmt )
1571 : {
1572 2709 : Point aTopLeft;
1573 2709 : Size aBulletSize( ImplGetBulletSize( nPara ) );
1574 :
1575 2709 : sal_Bool bOutlineMode = ( pEditEngine->GetControlWord() & EE_CNTRL_OUTLINER ) != 0;
1576 :
1577 : // the ODF attribut text:space-before which holds the spacing to add to the left of the label
1578 2709 : const short nSpaceBefore = pFmt->GetAbsLSpace() + pFmt->GetFirstLineOffset();
1579 :
1580 2709 : const SvxLRSpaceItem& rLR = (const SvxLRSpaceItem&) pEditEngine->GetParaAttrib( nPara, bOutlineMode ? EE_PARA_OUTLLRSPACE : EE_PARA_LRSPACE );
1581 2709 : aTopLeft.X() = rLR.GetTxtLeft() + rLR.GetTxtFirstLineOfst() + nSpaceBefore;
1582 :
1583 2709 : long nBulletWidth = Max( (long) -rLR.GetTxtFirstLineOfst(), (long) ((-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance()) );
1584 2709 : if ( nBulletWidth < aBulletSize.Width() ) // The Bullet creates its space
1585 29 : nBulletWidth = aBulletSize.Width();
1586 :
1587 2709 : if ( bAdjust && !bOutlineMode )
1588 : {
1589 : // Adjust when centered or align right
1590 28 : const SvxAdjustItem& rItem = (const SvxAdjustItem&)pEditEngine->GetParaAttrib( nPara, EE_PARA_JUST );
1591 56 : if ( ( !pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_LEFT ) ) ||
1592 28 : ( pEditEngine->IsRightToLeft( nPara ) && ( rItem.GetAdjust() != SVX_ADJUST_RIGHT ) ) )
1593 : {
1594 0 : aTopLeft.X() = pEditEngine->GetFirstLineStartX( nPara ) - nBulletWidth;
1595 : }
1596 : }
1597 :
1598 : // Vertical:
1599 2709 : ParagraphInfos aInfos = pEditEngine->GetParagraphInfos( nPara );
1600 2709 : if ( aInfos.bValid )
1601 : {
1602 33 : aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ // nFirstLineOffset is already added to the StartPos (PaintBullet) from the EditEngine
1603 : aInfos.nFirstLineHeight - aInfos.nFirstLineTextHeight
1604 : + aInfos.nFirstLineTextHeight / 2
1605 33 : - aBulletSize.Height() / 2;
1606 : // may prefer to print out on the baseline ...
1607 33 : if( ( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE ) && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) && ( pFmt->GetNumberingType() != SVX_NUM_CHAR_SPECIAL ) )
1608 : {
1609 0 : Font aBulletFont( ImpCalcBulletFont( nPara ) );
1610 0 : if ( aBulletFont.GetCharSet() != RTL_TEXTENCODING_SYMBOL )
1611 : {
1612 0 : OutputDevice* pRefDev = pEditEngine->GetRefDevice();
1613 0 : Font aOldFont = pRefDev->GetFont();
1614 0 : pRefDev->SetFont( aBulletFont );
1615 0 : FontMetric aMetric( pRefDev->GetFontMetric() );
1616 : // Leading on the first line ...
1617 0 : aTopLeft.Y() = /* aInfos.nFirstLineOffset + */ aInfos.nFirstLineMaxAscent;
1618 0 : aTopLeft.Y() -= aMetric.GetAscent();
1619 0 : pRefDev->SetFont( aOldFont );
1620 0 : }
1621 : }
1622 : }
1623 :
1624 : // Horizontal:
1625 2709 : if( pFmt->GetNumAdjust() == SVX_ADJUST_RIGHT )
1626 : {
1627 0 : aTopLeft.X() += nBulletWidth - aBulletSize.Width();
1628 : }
1629 2709 : else if( pFmt->GetNumAdjust() == SVX_ADJUST_CENTER )
1630 : {
1631 0 : aTopLeft.X() += ( nBulletWidth - aBulletSize.Width() ) / 2;
1632 : }
1633 :
1634 2709 : if ( aTopLeft.X() < 0 ) // then push
1635 0 : aTopLeft.X() = 0;
1636 :
1637 2709 : aBulletArea = Rectangle( aTopLeft, aBulletSize );
1638 : }
1639 2709 : if ( bReturnPaperPos )
1640 : {
1641 0 : Size aBulletSize( aBulletArea.GetSize() );
1642 0 : Point aBulletDocPos( aBulletArea.TopLeft() );
1643 0 : aBulletDocPos.Y() += pEditEngine->GetDocPosTopLeft( nPara ).Y();
1644 0 : Point aBulletPos( aBulletDocPos );
1645 :
1646 0 : if ( IsVertical() )
1647 : {
1648 0 : aBulletPos.Y() = aBulletDocPos.X();
1649 0 : aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.Y();
1650 : // Rotate:
1651 0 : aBulletPos.X() -= aBulletSize.Height();
1652 0 : Size aSz( aBulletSize );
1653 0 : aBulletSize.Width() = aSz.Height();
1654 0 : aBulletSize.Height() = aSz.Width();
1655 : }
1656 0 : else if ( pEditEngine->IsRightToLeft( nPara ) )
1657 : {
1658 0 : aBulletPos.X() = GetPaperSize().Width() - aBulletDocPos.X() - aBulletSize.Width();
1659 : }
1660 :
1661 0 : aBulletArea = Rectangle( aBulletPos, aBulletSize );
1662 : }
1663 2709 : return aBulletArea;
1664 : }
1665 :
1666 0 : void Outliner::ExpandHdl()
1667 : {
1668 : DBG_CHKTHIS(Outliner,0);
1669 0 : aExpandHdl.Call( this );
1670 0 : }
1671 :
1672 0 : EBulletInfo Outliner::GetBulletInfo( sal_uInt16 nPara )
1673 : {
1674 0 : EBulletInfo aInfo;
1675 :
1676 0 : aInfo.nParagraph = nPara;
1677 0 : aInfo.bVisible = ImplHasBullet( nPara );
1678 :
1679 0 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1680 0 : aInfo.nType = pFmt ? pFmt->GetNumberingType() : 0;
1681 :
1682 0 : if( pFmt )
1683 : {
1684 0 : if( pFmt->GetNumberingType() != SVX_NUM_BITMAP )
1685 : {
1686 0 : aInfo.aText = ImplGetBulletText( nPara );
1687 :
1688 0 : if( pFmt->GetBulletFont() )
1689 0 : aInfo.aFont = *pFmt->GetBulletFont();
1690 : }
1691 0 : else if ( pFmt->GetBrush()->GetGraphicObject() )
1692 : {
1693 0 : aInfo.aGraphic = pFmt->GetBrush()->GetGraphicObject()->GetGraphic();
1694 : }
1695 : }
1696 :
1697 0 : if ( aInfo.bVisible )
1698 : {
1699 0 : aInfo.aBounds = ImpCalcBulletArea( nPara, sal_True, sal_True );
1700 : }
1701 :
1702 0 : return aInfo;
1703 : }
1704 :
1705 1134 : XubString Outliner::GetText( Paragraph* pParagraph, sal_uLong nCount ) const
1706 : {
1707 : DBG_CHKTHIS(Outliner,0);
1708 :
1709 1134 : XubString aText;
1710 1134 : sal_uInt16 nStartPara = (sal_uInt16) pParaList->GetAbsPos( pParagraph );
1711 2268 : for ( sal_uInt16 n = 0; n < nCount; n++ )
1712 : {
1713 1134 : aText += pEditEngine->GetText( nStartPara + n );
1714 1134 : if ( (n+1) < (sal_uInt16)nCount )
1715 0 : aText += '\n';
1716 : }
1717 1134 : return aText;
1718 : }
1719 :
1720 0 : void Outliner::Remove( Paragraph* pPara, sal_uLong nParaCount )
1721 : {
1722 : DBG_CHKTHIS(Outliner,0);
1723 :
1724 0 : sal_uLong nPos = pParaList->GetAbsPos( pPara );
1725 0 : if( !nPos && ( nParaCount >= pParaList->GetParagraphCount() ) )
1726 : {
1727 0 : Clear();
1728 : }
1729 : else
1730 : {
1731 0 : for( sal_uInt16 n = 0; n < (sal_uInt16)nParaCount; n++ )
1732 0 : pEditEngine->RemoveParagraph( (sal_uInt16) nPos );
1733 : }
1734 0 : }
1735 :
1736 109 : void Outliner::StripPortions()
1737 : {
1738 : DBG_CHKTHIS(Outliner,0);
1739 109 : bStrippingPortions = sal_True;
1740 109 : pEditEngine->StripPortions();
1741 109 : bStrippingPortions = sal_False;
1742 109 : }
1743 :
1744 322 : void Outliner::DrawingText( const Point& rStartPos, const XubString& rText, sal_uInt16 nTextStart, sal_uInt16 nTextLen, const sal_Int32* pDXArray,const SvxFont& rFont,
1745 : sal_uInt16 nPara, sal_uInt16 nIndex, sal_uInt8 nRightToLeft,
1746 : const EEngineData::WrongSpellVector* pWrongSpellVector,
1747 : const SvxFieldData* pFieldData,
1748 : bool bEndOfLine,
1749 : bool bEndOfParagraph,
1750 : bool bEndOfBullet,
1751 : const ::com::sun::star::lang::Locale* pLocale,
1752 : const Color& rOverlineColor,
1753 : const Color& rTextLineColor)
1754 : {
1755 : DBG_CHKTHIS(Outliner,0);
1756 :
1757 322 : if(aDrawPortionHdl.IsSet())
1758 : {
1759 : DrawPortionInfo aInfo( rStartPos, rText, nTextStart, nTextLen, rFont, nPara, nIndex, pDXArray, pWrongSpellVector,
1760 322 : pFieldData, pLocale, rOverlineColor, rTextLineColor, nRightToLeft, false, 0, bEndOfLine, bEndOfParagraph, bEndOfBullet);
1761 :
1762 322 : aDrawPortionHdl.Call( &aInfo );
1763 : }
1764 322 : }
1765 :
1766 0 : void Outliner::DrawingTab( const Point& rStartPos, long nWidth, const String& rChar, const SvxFont& rFont,
1767 : sal_uInt16 nPara, xub_StrLen nIndex, sal_uInt8 nRightToLeft, bool bEndOfLine, bool bEndOfParagraph,
1768 : const Color& rOverlineColor, const Color& rTextLineColor)
1769 : {
1770 0 : if(aDrawPortionHdl.IsSet())
1771 : {
1772 0 : DrawPortionInfo aInfo( rStartPos, rChar, 0, rChar.Len(), rFont, nPara, nIndex, NULL, NULL,
1773 0 : NULL, NULL, rOverlineColor, rTextLineColor, nRightToLeft, true, nWidth, bEndOfLine, bEndOfParagraph, false);
1774 :
1775 0 : aDrawPortionHdl.Call( &aInfo );
1776 : }
1777 0 : }
1778 :
1779 0 : long Outliner::RemovingPagesHdl( OutlinerView* pView )
1780 : {
1781 : DBG_CHKTHIS(Outliner,0);
1782 0 : return aRemovingPagesHdl.IsSet() ? aRemovingPagesHdl.Call( pView ) : sal_True;
1783 : }
1784 :
1785 0 : sal_Bool Outliner::ImpCanDeleteSelectedPages( OutlinerView* pCurView, sal_uInt16 _nFirstPage, sal_uInt16 nPages )
1786 : {
1787 : DBG_CHKTHIS(Outliner,0);
1788 :
1789 0 : nDepthChangedHdlPrevDepth = nPages;
1790 0 : mnFirstSelPage = _nFirstPage;
1791 0 : pHdlParagraph = 0;
1792 0 : return (sal_Bool)RemovingPagesHdl( pCurView );
1793 : }
1794 :
1795 11441 : SfxItemSet Outliner::GetParaAttribs( sal_uInt16 nPara )
1796 : {
1797 : DBG_CHKTHIS(Outliner,0);
1798 11441 : return pEditEngine->GetParaAttribs( nPara );
1799 : }
1800 :
1801 0 : IMPL_LINK( Outliner, ParaVisibleStateChangedHdl, Paragraph*, pPara )
1802 : {
1803 : DBG_CHKTHIS(Outliner,0);
1804 :
1805 0 : sal_uLong nPara = pParaList->GetAbsPos( pPara );
1806 0 : pEditEngine->ShowParagraph( (sal_uInt16)nPara, pPara->IsVisible() );
1807 :
1808 0 : return 0;
1809 : }
1810 :
1811 0 : IMPL_LINK_NOARG(Outliner, BeginMovingParagraphsHdl)
1812 : {
1813 : DBG_CHKTHIS(Outliner,0);
1814 :
1815 0 : if( !IsInUndo() )
1816 0 : GetBeginMovingHdl().Call( this );
1817 :
1818 0 : return 0;
1819 : }
1820 :
1821 0 : IMPL_LINK( Outliner, BeginPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1822 : {
1823 0 : UndoActionStart( EDITUNDO_DRAGANDDROP );
1824 0 : maBeginPasteOrDropHdl.Call(pInfos);
1825 0 : return 0;
1826 : }
1827 :
1828 0 : IMPL_LINK( Outliner, EndPasteOrDropHdl, PasteOrDropInfos*, pInfos )
1829 : {
1830 0 : bPasting = sal_False;
1831 0 : ImpTextPasted( pInfos->nStartPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
1832 0 : maEndPasteOrDropHdl.Call( pInfos );
1833 0 : UndoActionEnd( EDITUNDO_DRAGANDDROP );
1834 0 : return 0;
1835 : }
1836 :
1837 0 : IMPL_LINK( Outliner, EndMovingParagraphsHdl, MoveParagraphsInfo*, pInfos )
1838 : {
1839 : DBG_CHKTHIS(Outliner,0);
1840 :
1841 0 : pParaList->MoveParagraphs( pInfos->nStartPara, pInfos->nDestPara, pInfos->nEndPara - pInfos->nStartPara + 1 );
1842 0 : sal_uInt16 nChangesStart = Min( pInfos->nStartPara, pInfos->nDestPara );
1843 0 : sal_uInt16 nParas = (sal_uInt16)pParaList->GetParagraphCount();
1844 0 : for ( sal_uInt16 n = nChangesStart; n < nParas; n++ )
1845 0 : ImplCalcBulletText( n, sal_False, sal_False );
1846 :
1847 0 : if( !IsInUndo() )
1848 0 : aEndMovingHdl.Call( this );
1849 :
1850 0 : return 0;
1851 : }
1852 :
1853 0 : static bool isSameNumbering( const SvxNumberFormat& rN1, const SvxNumberFormat& rN2 )
1854 : {
1855 0 : if( rN1.GetNumberingType() != rN2.GetNumberingType() )
1856 0 : return false;
1857 :
1858 0 : if( rN1.GetNumStr(1) != rN2.GetNumStr(1) )
1859 0 : return false;
1860 :
1861 0 : if( (rN1.GetPrefix() != rN2.GetPrefix()) || (rN1.GetSuffix() != rN2.GetSuffix()) )
1862 0 : return false;
1863 :
1864 0 : return true;
1865 : }
1866 :
1867 0 : sal_uInt16 Outliner::ImplGetNumbering( sal_uInt16 nPara, const SvxNumberFormat* pParaFmt )
1868 : {
1869 0 : sal_uInt16 nNumber = pParaFmt->GetStart() - 1;
1870 :
1871 0 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1872 0 : const sal_Int16 nParaDepth = pPara->GetDepth();
1873 :
1874 0 : do
1875 : {
1876 0 : pPara = pParaList->GetParagraph( nPara );
1877 0 : const sal_Int16 nDepth = pPara->GetDepth();
1878 :
1879 : // ignore paragraphs that are below our paragraph or have no numbering
1880 0 : if( (nDepth > nParaDepth) || (nDepth == -1) )
1881 0 : continue;
1882 :
1883 : // stop on paragraphs that are above our paragraph
1884 0 : if( nDepth < nParaDepth )
1885 0 : break;
1886 :
1887 0 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1888 :
1889 0 : if( pFmt == 0 )
1890 0 : continue; // ignore paragraphs without bullets
1891 :
1892 : // check if numbering is the same
1893 0 : if( !isSameNumbering( *pFmt, *pParaFmt ) )
1894 0 : break;
1895 :
1896 0 : const SfxBoolItem& rBulletState = (const SfxBoolItem&) pEditEngine->GetParaAttrib( nPara, EE_PARA_BULLETSTATE );
1897 :
1898 0 : if( rBulletState.GetValue() )
1899 0 : nNumber += 1;
1900 :
1901 : // same depth, same number format, check for restart
1902 0 : const sal_Int16 nNumberingStartValue = pPara->GetNumberingStartValue();
1903 0 : if( (nNumberingStartValue != -1) || pPara->IsParaIsNumberingRestart() )
1904 : {
1905 0 : if( nNumberingStartValue != -1 )
1906 0 : nNumber += nNumberingStartValue - 1;
1907 0 : break;
1908 : }
1909 : }
1910 : while( nPara-- );
1911 :
1912 0 : return nNumber;
1913 : }
1914 :
1915 109229 : void Outliner::ImplCalcBulletText( sal_uInt16 nPara, sal_Bool bRecalcLevel, sal_Bool bRecalcChildren )
1916 : {
1917 : DBG_CHKTHIS(Outliner,0);
1918 :
1919 109229 : Paragraph* pPara = pParaList->GetParagraph( nPara );
1920 109229 : sal_uInt16 nRelPos = 0xFFFF;
1921 :
1922 327687 : while ( pPara )
1923 : {
1924 109229 : XubString aBulletText;
1925 109229 : const SvxNumberFormat* pFmt = GetNumberFormat( nPara );
1926 109229 : if( pFmt && ( pFmt->GetNumberingType() != SVX_NUM_BITMAP ) )
1927 : {
1928 9964 : aBulletText += pFmt->GetPrefix();
1929 9964 : if( pFmt->GetNumberingType() == SVX_NUM_CHAR_SPECIAL )
1930 : {
1931 2480 : aBulletText += pFmt->GetBulletChar();
1932 : }
1933 7484 : else if( pFmt->GetNumberingType() != SVX_NUM_NUMBER_NONE )
1934 : {
1935 0 : aBulletText += pFmt->GetNumStr( ImplGetNumbering( nPara, pFmt ) );
1936 : }
1937 9964 : aBulletText += pFmt->GetSuffix();
1938 : }
1939 :
1940 109229 : if (!pPara->GetText().equals(aBulletText))
1941 966 : pPara->SetText( aBulletText );
1942 :
1943 109229 : pPara->nFlags &= (~PARAFLAG_SETBULLETTEXT);
1944 :
1945 109229 : if ( bRecalcLevel )
1946 : {
1947 140 : if ( nRelPos != 0xFFFF )
1948 0 : nRelPos++;
1949 :
1950 140 : sal_Int16 nDepth = pPara->GetDepth();
1951 140 : pPara = pParaList->GetParagraph( ++nPara );
1952 140 : if ( !bRecalcChildren )
1953 : {
1954 280 : while ( pPara && ( pPara->GetDepth() > nDepth ) )
1955 0 : pPara = pParaList->GetParagraph( ++nPara );
1956 : }
1957 :
1958 140 : if ( pPara && ( pPara->GetDepth() < nDepth ) )
1959 0 : pPara = NULL;
1960 : }
1961 : else
1962 : {
1963 109089 : pPara = NULL;
1964 : }
1965 109229 : }
1966 109229 : }
1967 :
1968 57264 : void Outliner::Clear()
1969 : {
1970 : DBG_CHKTHIS(Outliner,0);
1971 :
1972 57264 : if( !bFirstParaIsEmpty )
1973 : {
1974 13478 : ImplBlockInsertionCallbacks( sal_True );
1975 13478 : pEditEngine->Clear();
1976 13478 : pParaList->Clear( sal_True );
1977 13478 : pParaList->Append( new Paragraph( nMinDepth ));
1978 13478 : bFirstParaIsEmpty = sal_True;
1979 13478 : ImplBlockInsertionCallbacks( sal_False );
1980 : }
1981 : else
1982 : {
1983 43786 : Paragraph* pPara = pParaList->GetParagraph( 0 );
1984 43786 : if(pPara)
1985 43786 : pPara->SetDepth( nMinDepth );
1986 : }
1987 57264 : }
1988 :
1989 0 : void Outliner::SetFlatMode( sal_Bool bFlat )
1990 : {
1991 : DBG_CHKTHIS(Outliner,0);
1992 :
1993 0 : if( bFlat != pEditEngine->IsFlatMode() )
1994 : {
1995 0 : for ( sal_uInt16 nPara = (sal_uInt16)pParaList->GetParagraphCount(); nPara; )
1996 0 : pParaList->GetParagraph( --nPara )->aBulSize.Width() = -1;
1997 :
1998 0 : pEditEngine->SetFlatMode( bFlat );
1999 : }
2000 0 : }
2001 :
2002 447 : String Outliner::ImplGetBulletText( sal_uInt16 nPara )
2003 : {
2004 447 : String aRes;
2005 447 : Paragraph* pPara = pParaList->GetParagraph( nPara );
2006 447 : if (pPara)
2007 : {
2008 : // Enable optimization again ...
2009 : // if( pPara->nFlags & PARAFLAG_SETBULLETTEXT )
2010 447 : ImplCalcBulletText( nPara, sal_False, sal_False );
2011 447 : aRes = pPara->GetText();
2012 : }
2013 447 : return aRes;
2014 : }
2015 :
2016 : // this is needed for StarOffice Api
2017 34 : void Outliner::SetLevelDependendStyleSheet( sal_uInt16 nPara )
2018 : {
2019 34 : SfxItemSet aOldAttrs( pEditEngine->GetParaAttribs( nPara ) );
2020 34 : ImplSetLevelDependendStyleSheet( nPara );
2021 34 : pEditEngine->SetParaAttribs( nPara, aOldAttrs );
2022 34 : }
2023 :
2024 56068 : void Outliner::ImplBlockInsertionCallbacks( sal_Bool b )
2025 : {
2026 56068 : if ( b )
2027 : {
2028 28034 : bBlockInsCallback++;
2029 : }
2030 : else
2031 : {
2032 : DBG_ASSERT( bBlockInsCallback, "ImplBlockInsertionCallbacks ?!" );
2033 28034 : bBlockInsCallback--;
2034 28034 : if ( !bBlockInsCallback )
2035 : {
2036 : // Call blocked notify events...
2037 55694 : while(!pEditEngine->aNotifyCache.empty())
2038 : {
2039 0 : EENotify aNotify(pEditEngine->aNotifyCache.front());
2040 : // Remove from list before calling, maybe we enter LeaveBlockNotifications while calling the handler...
2041 0 : pEditEngine->aNotifyCache.erase(pEditEngine->aNotifyCache.begin());
2042 0 : pEditEngine->aOutlinerNotifyHdl.Call( &aNotify );
2043 : }
2044 : }
2045 : }
2046 56068 : }
2047 :
2048 0 : IMPL_LINK( Outliner, EditEngineNotifyHdl, EENotify*, pNotify )
2049 : {
2050 0 : if ( !bBlockInsCallback )
2051 0 : pEditEngine->aOutlinerNotifyHdl.Call( pNotify );
2052 : else
2053 0 : pEditEngine->aNotifyCache.push_back(*pNotify);
2054 :
2055 0 : return 0;
2056 : }
2057 :
2058 : /** sets a link that is called at the beginning of a drag operation at an edit view */
2059 0 : void Outliner::SetBeginDropHdl( const Link& rLink )
2060 : {
2061 0 : pEditEngine->SetBeginDropHdl( rLink );
2062 0 : }
2063 :
2064 : /** sets a link that is called at the end of a drag operation at an edit view */
2065 0 : void Outliner::SetEndDropHdl( const Link& rLink )
2066 : {
2067 0 : pEditEngine->SetEndDropHdl( rLink );
2068 0 : }
2069 :
2070 : /** sets a link that is called before a drop or paste operation. */
2071 0 : void Outliner::SetBeginPasteOrDropHdl( const Link& rLink )
2072 : {
2073 0 : maBeginPasteOrDropHdl = rLink;
2074 0 : }
2075 :
2076 : /** sets a link that is called after a drop or paste operation. */
2077 0 : void Outliner::SetEndPasteOrDropHdl( const Link& rLink )
2078 : {
2079 0 : maEndPasteOrDropHdl = rLink;
2080 0 : }
2081 :
2082 0 : void Outliner::SetParaFlag( Paragraph* pPara, sal_uInt16 nFlag )
2083 : {
2084 0 : if( pPara && !pPara->HasFlag( nFlag ) )
2085 : {
2086 0 : if( IsUndoEnabled() && !IsInUndo() )
2087 0 : InsertUndo( new OutlinerUndoChangeParaFlags( this, (sal_uInt16)GetAbsPos( pPara ), pPara->nFlags, pPara->nFlags|nFlag ) );
2088 :
2089 0 : pPara->SetFlag( nFlag );
2090 : }
2091 0 : }
2092 :
2093 7 : bool Outliner::HasParaFlag( const Paragraph* pPara, sal_uInt16 nFlag ) const
2094 : {
2095 7 : return pPara && pPara->HasFlag( nFlag );
2096 : }
2097 :
2098 :
2099 242 : sal_Bool DrawPortionInfo::IsRTL() const
2100 : {
2101 242 : if(0xFF == mnBiDiLevel)
2102 : {
2103 : // Use Bidi functions from icu 2.0 to calculate if this portion
2104 : // is RTL or not.
2105 28 : UErrorCode nError(U_ZERO_ERROR);
2106 28 : UBiDi* pBidi = ubidi_openSized(mrText.Len(), 0, &nError);
2107 28 : nError = U_ZERO_ERROR;
2108 :
2109 : // I do not have this info here. Is it necessary? I'll have to ask MT.
2110 28 : const sal_uInt8 nDefaultDir = UBIDI_LTR; //IsRightToLeft( nPara ) ? UBIDI_RTL : UBIDI_LTR;
2111 :
2112 28 : ubidi_setPara(pBidi, reinterpret_cast<const UChar *>(mrText.GetBuffer()), mrText.Len(), nDefaultDir, NULL, &nError); // UChar != sal_Unicode in MinGW
2113 28 : nError = U_ZERO_ERROR;
2114 :
2115 28 : int32_t nStart(0);
2116 : int32_t nEnd;
2117 : UBiDiLevel nCurrDir;
2118 :
2119 28 : ubidi_getLogicalRun(pBidi, nStart, &nEnd, &nCurrDir);
2120 :
2121 28 : ubidi_close(pBidi);
2122 :
2123 : // remember on-demand calculated state
2124 28 : ((DrawPortionInfo*)this)->mnBiDiLevel = nCurrDir;
2125 : }
2126 :
2127 242 : return (1 == (mnBiDiLevel % 2));
2128 : }
2129 :
2130 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|