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