LCOV - code coverage report
Current view: top level - libreoffice/editeng/source/outliner - outliner.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 532 1055 50.4 %
Date: 2012-12-27 Functions: 49 97 50.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10