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