LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/editeng/source/editeng - editobj.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 367 647 56.7 %
Date: 2013-07-09 Functions: 62 90 68.9 %
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 <rtl/strbuf.hxx>
      22             : #include <vcl/wrkwin.hxx>
      23             : #include <vcl/dialog.hxx>
      24             : #include <vcl/msgbox.hxx>
      25             : #include <vcl/svapp.hxx>
      26             : 
      27             : #include <tools/stream.hxx>
      28             : 
      29             : #include "editeng/fieldupdater.hxx"
      30             : #include "editeng/macros.hxx"
      31             : #include <editobj2.hxx>
      32             : #include <editeng/editdata.hxx>
      33             : #include <editattr.hxx>
      34             : #include <editeng/editeng.hxx>
      35             : #include <editeng/fontitem.hxx>
      36             : #include <editeng/charsetcoloritem.hxx>
      37             : #include <editeng/flditem.hxx>
      38             : #include <editeng/lrspitem.hxx>
      39             : #include <editeng/tstpitem.hxx>
      40             : #include <editeng/bulletitem.hxx>
      41             : #include <editeng/numitem.hxx>
      42             : #include <editeng/brushitem.hxx>
      43             : 
      44             : #include <vcl/graph.hxx>
      45             : #include <svl/intitem.hxx>
      46             : #include <unotools/fontcvt.hxx>
      47             : #include <tools/tenccvt.hxx>
      48             : 
      49             : #if DEBUG_EDIT_ENGINE
      50             : #include <iostream>
      51             : using std::cout;
      52             : using std::endl;
      53             : #endif
      54             : 
      55             : using namespace com::sun::star;
      56             : 
      57             : DBG_NAME( EE_EditTextObject )
      58             : DBG_NAME( XEditAttribute )
      59             : 
      60             : //--------------------------------------------------------------
      61             : 
      62      139963 : XEditAttribute* MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
      63             : {
      64             :     // Create thw new attribute in the pool
      65      139963 :     const SfxPoolItem& rNew = rPool.Put( rItem );
      66             : 
      67      139963 :     XEditAttribute* pNew = new XEditAttribute( rNew, nStart, nEnd );
      68      139963 :     return pNew;
      69             : }
      70             : 
      71      139963 : XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, sal_uInt16 nS, sal_uInt16 nE )
      72             : {
      73             :     DBG_CTOR( XEditAttribute, 0 );
      74      139963 :     pItem = &rAttr;
      75      139963 :     nStart = nS;
      76      139963 :     nEnd = nE;
      77      139963 : }
      78             : 
      79      139327 : XEditAttribute::~XEditAttribute()
      80             : {
      81             :     DBG_DTOR( XEditAttribute, 0 );
      82      139327 :     pItem = 0;  // belongs to the Pool.
      83      139327 : }
      84             : 
      85           0 : bool XEditAttribute::IsFeature() const
      86             : {
      87           0 :     sal_uInt16 nWhich = pItem->Which();
      88           0 :     return  ((nWhich >= EE_FEATURE_START) && (nWhich <=  EE_FEATURE_END));
      89             : }
      90             : 
      91           0 : void XEditAttribute::SetItem(const SfxPoolItem& rNew)
      92             : {
      93           0 :     pItem = &rNew;
      94           0 : }
      95             : 
      96           0 : XParaPortionList::XParaPortionList(
      97             :     OutputDevice* pRefDev, sal_uLong nPW, sal_uInt16 _nStretchX, sal_uInt16 _nStretchY) :
      98           0 :     aRefMapMode(pRefDev->GetMapMode()), nStretchX(_nStretchX), nStretchY(_nStretchY)
      99             : {
     100           0 :     nRefDevPtr = (sal_uIntPtr)pRefDev; nPaperWidth = nPW;
     101           0 :     eRefDevType = pRefDev->GetOutDevType();
     102           0 : }
     103             : 
     104           0 : void XParaPortionList::push_back(XParaPortion* p)
     105             : {
     106           0 :     maList.push_back(p);
     107           0 : }
     108             : 
     109           0 : const XParaPortion& XParaPortionList::operator [](size_t i) const
     110             : {
     111           0 :     return maList[i];
     112             : }
     113             : 
     114       46248 : ContentInfo::ContentInfo( SfxItemPool& rPool ) : aParaAttribs( rPool, EE_PARA_START, EE_CHAR_END )
     115             : {
     116       46248 :     eFamily = SFX_STYLE_FAMILY_PARA;
     117       46248 :     pWrongs = NULL;
     118       46248 : }
     119             : 
     120             : // the real Copy constructor is nonsens, since I have to work with another Pool!
     121       51714 : ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse )
     122             :     : aParaAttribs( rPoolToUse, EE_PARA_START, EE_CHAR_END )
     123       51714 :     , pWrongs(0)
     124             : {
     125             :     // this should ensure that the Items end up in the correct Pool!
     126       51714 :     aParaAttribs.Set( rCopyFrom.GetParaAttribs() );
     127       51714 :     aText = rCopyFrom.GetText();
     128       51714 :     aStyle = rCopyFrom.GetStyle();
     129       51714 :     eFamily = rCopyFrom.GetFamily();
     130             : 
     131      126581 :     for (size_t i = 0; i < rCopyFrom.aAttribs.size(); ++i)
     132             :     {
     133       74867 :         const XEditAttribute& rAttr = rCopyFrom.aAttribs[i];
     134             :         XEditAttribute* pMyAttr = MakeXEditAttribute(
     135       74867 :             rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd());
     136       74867 :         aAttribs.push_back(pMyAttr);
     137             :     }
     138             : 
     139       51714 :     if ( rCopyFrom.GetWrongList() )
     140        8219 :         pWrongs = rCopyFrom.GetWrongList()->Clone();
     141       51714 : }
     142             : 
     143      195406 : ContentInfo::~ContentInfo()
     144             : {
     145       97703 :     XEditAttributesType::iterator it = aAttribs.begin(), itEnd = aAttribs.end();
     146      237030 :     for (; it != itEnd; ++it)
     147      139327 :         aParaAttribs.GetPool()->Remove(*it->GetItem());
     148       97703 :     aAttribs.clear();
     149             : 
     150       97703 :     delete pWrongs;
     151       97703 : }
     152             : 
     153             : // #i102062#
     154        1007 : bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
     155             : {
     156        1007 :     if(GetWrongList() == rCompare.GetWrongList())
     157        1007 :         return true;
     158             : 
     159           0 :     if(!GetWrongList() || !rCompare.GetWrongList())
     160           0 :         return false;
     161             : 
     162           0 :     return (*GetWrongList() == *rCompare.GetWrongList());
     163             : }
     164             : 
     165             : #if DEBUG_EDIT_ENGINE
     166             : void ContentInfo::Dump() const
     167             : {
     168             :     cout << "--" << endl;
     169             :     cout << "text: '" << aText << "'" << endl;
     170             :     cout << "style: '" << aStyle << "'" << endl;
     171             : 
     172             :     XEditAttributesType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
     173             :     for (; it != itEnd; ++it)
     174             :     {
     175             :         const XEditAttribute& rAttr = *it;
     176             :         cout << "attribute: " << endl;
     177             :         cout << "  span: [begin=" << rAttr.GetStart() << ", end=" << rAttr.GetEnd() << "]" << endl;
     178             :         cout << "  feature: " << (rAttr.IsFeature() ? "yes":"no") << endl;
     179             :     }
     180             : }
     181             : #endif
     182             : 
     183        1989 : bool ContentInfo::operator==( const ContentInfo& rCompare ) const
     184             : {
     185        5947 :     if( (aText == rCompare.aText) &&
     186        3762 :             (aStyle == rCompare.aStyle ) &&
     187        3478 :             (aAttribs.size() == rCompare.aAttribs.size()) &&
     188        5359 :             (eFamily == rCompare.eFamily ) &&
     189        1685 :             (aParaAttribs == rCompare.aParaAttribs ) )
     190             :     {
     191       14512 :         for (size_t i = 0, n = aAttribs.size(); i < n; ++i)
     192             :         {
     193       13255 :             if (aAttribs[i] != rCompare.aAttribs[i])
     194          56 :                 return false;
     195             :         }
     196             : 
     197        1257 :         return true;
     198             :     }
     199             : 
     200         676 :     return false;
     201             : }
     202             : 
     203        1989 : bool ContentInfo::operator!=(const ContentInfo& rCompare) const
     204             : {
     205        1989 :     return !operator==(rCompare);
     206             : }
     207             : 
     208       42369 : EditTextObject::EditTextObject( SfxItemPool* pPool ) :
     209       42369 :     mpImpl(new EditTextObjectImpl(this, pPool))
     210             : {
     211       42369 : }
     212             : 
     213       47805 : EditTextObject::EditTextObject( const EditTextObject& r ) :
     214             :     SfxItemPoolUser(),
     215       47805 :     mpImpl(new EditTextObjectImpl(this, *r.mpImpl))
     216             : {
     217       47805 : }
     218             : 
     219      269853 : EditTextObject::~EditTextObject()
     220             : {
     221       89951 :     delete mpImpl;
     222      179902 : }
     223             : 
     224       18370 : sal_Int32 EditTextObject::GetParagraphCount() const
     225             : {
     226       18370 :     return mpImpl->GetParagraphCount();
     227             : }
     228             : 
     229       14989 : String EditTextObject::GetText(sal_Int32 nPara) const
     230             : {
     231       14989 :     return mpImpl->GetText(nPara);
     232             : }
     233             : 
     234           1 : void EditTextObject::ClearPortionInfo()
     235             : {
     236           1 :     mpImpl->ClearPortionInfo();
     237           1 : }
     238             : 
     239           3 : bool EditTextObject::HasOnlineSpellErrors() const
     240             : {
     241           3 :     return mpImpl->HasOnlineSpellErrors();
     242             : }
     243             : 
     244           6 : void EditTextObject::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
     245             : {
     246           6 :     mpImpl->GetCharAttribs(nPara, rLst);
     247           6 : }
     248             : 
     249           0 : bool EditTextObject::IsFieldObject() const
     250             : {
     251           0 :     return mpImpl->IsFieldObject();
     252             : }
     253             : 
     254           0 : const SvxFieldItem* EditTextObject::GetField() const
     255             : {
     256           0 :     return mpImpl->GetField();
     257             : }
     258             : 
     259           1 : const SvxFieldData* EditTextObject::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
     260             : {
     261           1 :     return mpImpl->GetFieldData(nPara, nPos, nType);
     262             : }
     263             : 
     264      154540 : bool EditTextObject::HasField( sal_Int32 nType ) const
     265             : {
     266      154540 :     return mpImpl->HasField(nType);
     267             : }
     268             : 
     269           3 : const SfxItemSet& EditTextObject::GetParaAttribs(sal_Int32 nPara) const
     270             : {
     271           3 :     return mpImpl->GetParaAttribs(nPara);
     272             : }
     273             : 
     274           0 : bool EditTextObject::RemoveCharAttribs( sal_uInt16 nWhich )
     275             : {
     276           0 :     return mpImpl->RemoveCharAttribs(nWhich);
     277             : }
     278             : 
     279        5339 : void EditTextObject::GetStyleSheet(sal_Int32 nPara, String& rName, SfxStyleFamily& eFamily) const
     280             : {
     281        5339 :     mpImpl->GetStyleSheet(nPara, rName, eFamily);
     282        5339 : }
     283             : 
     284           0 : void EditTextObject::SetStyleSheet(sal_Int32 nPara, const String& rName, const SfxStyleFamily& eFamily)
     285             : {
     286           0 :     mpImpl->SetStyleSheet(nPara, rName, eFamily);
     287           0 : }
     288             : 
     289        1638 : bool EditTextObject::ChangeStyleSheets(
     290             :     const XubString& rOldName, SfxStyleFamily eOldFamily, const XubString& rNewName, SfxStyleFamily eNewFamily )
     291             : {
     292        1638 :     return mpImpl->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily);
     293             : }
     294             : 
     295           0 : void EditTextObject::ChangeStyleSheetName(
     296             :     SfxStyleFamily eFamily, const XubString& rOldName, const XubString& rNewName )
     297             : {
     298           0 :     mpImpl->ChangeStyleSheetName(eFamily, rOldName, rNewName);
     299           0 : }
     300             : 
     301           0 : editeng::FieldUpdater EditTextObject::GetFieldUpdater()
     302             : {
     303           0 :     return mpImpl->GetFieldUpdater();
     304             : }
     305             : 
     306           0 : const SfxItemPool* EditTextObject::GetPool() const
     307             : {
     308           0 :     return mpImpl->GetPool();
     309             : }
     310             : 
     311      241868 : sal_uInt16 EditTextObject::GetUserType() const
     312             : {
     313      241868 :     return mpImpl->GetUserType();
     314             : }
     315             : 
     316       35423 : void EditTextObject::SetUserType( sal_uInt16 n )
     317             : {
     318       35423 :     mpImpl->SetUserType(n);
     319       35423 : }
     320             : 
     321      289810 : bool EditTextObject::IsVertical() const
     322             : {
     323      289810 :     return mpImpl->IsVertical();
     324             : }
     325             : 
     326       42471 : void EditTextObject::SetVertical( bool bVertical )
     327             : {
     328       42471 :     return mpImpl->SetVertical(bVertical);
     329             : }
     330             : 
     331           0 : sal_uInt16 EditTextObject::GetScriptType() const
     332             : {
     333           0 :     return mpImpl->GetScriptType();
     334             : }
     335             : 
     336             : 
     337        2480 : bool EditTextObject::Store( SvStream& rOStream ) const
     338             : {
     339        2480 :     if ( rOStream.GetError() )
     340           0 :         return false;
     341             : 
     342        2480 :     sal_Size nStartPos = rOStream.Tell();
     343             : 
     344        2480 :     sal_uInt16 nWhich = static_cast<sal_uInt16>(EE_FORMAT_BIN);
     345        2480 :     rOStream << nWhich;
     346             : 
     347        2480 :     sal_uInt32 nStructSz = 0;
     348        2480 :     rOStream << nStructSz;
     349             : 
     350        2480 :     StoreData( rOStream );
     351             : 
     352        2480 :     sal_Size nEndPos = rOStream.Tell();
     353        2480 :     nStructSz = nEndPos - nStartPos - sizeof( nWhich ) - sizeof( nStructSz );
     354        2480 :     rOStream.Seek( nStartPos + sizeof( nWhich ) );
     355        2480 :     rOStream << nStructSz;
     356        2480 :     rOStream.Seek( nEndPos );
     357             : 
     358        2480 :     return rOStream.GetError() ? false : true;
     359             : }
     360             : 
     361           0 : EditTextObject* EditTextObject::Create( SvStream& rIStream, SfxItemPool* pGlobalTextObjectPool )
     362             : {
     363           0 :     sal_uLong nStartPos = rIStream.Tell();
     364             : 
     365             :     // First check what type of Object...
     366             :     sal_uInt16 nWhich;
     367           0 :     rIStream >> nWhich;
     368             : 
     369             :     sal_uInt32 nStructSz;
     370           0 :     rIStream >> nStructSz;
     371             : 
     372           0 :     if (nWhich != EE_FORMAT_BIN)
     373             :     {
     374             :         // Unknown object we no longer support.
     375           0 :         rIStream.SetError(EE_READWRITE_WRONGFORMAT);
     376           0 :         return NULL;
     377             :     }
     378             : 
     379           0 :     if ( rIStream.GetError() )
     380           0 :         return NULL;
     381             : 
     382           0 :     EditTextObject* pTxtObj = new EditTextObject(pGlobalTextObjectPool);;
     383           0 :     pTxtObj->CreateData(rIStream);
     384             : 
     385             :     // Make sure that the stream is left at the correct place.
     386           0 :     sal_Size nFullSz = sizeof( nWhich ) + sizeof( nStructSz ) + nStructSz;
     387           0 :     rIStream.Seek( nStartPos + nFullSz );
     388           0 :     return pTxtObj;
     389             : }
     390             : 
     391        2480 : void EditTextObject::StoreData( SvStream& rStrm ) const
     392             : {
     393        2480 :     mpImpl->StoreData(rStrm);
     394        2480 : }
     395             : 
     396           0 : void EditTextObject::CreateData( SvStream& rStrm )
     397             : {
     398           0 :     mpImpl->CreateData(rStrm);
     399           0 : }
     400             : 
     401       47805 : EditTextObject* EditTextObject::Clone() const
     402             : {
     403       47805 :     return new EditTextObject(*this);
     404             : }
     405             : 
     406        1431 : bool EditTextObject::operator==( const EditTextObject& rCompare ) const
     407             : {
     408        1431 :     return mpImpl->operator==(*rCompare.mpImpl);
     409             : }
     410             : 
     411             : // #i102062#
     412         665 : bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
     413             : {
     414         665 :     return mpImpl->isWrongListEqual(*rCompare.mpImpl);
     415             : }
     416             : 
     417         896 : void EditTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
     418             : {
     419         896 :     mpImpl->ObjectInDestruction(rSfxItemPool);
     420         896 : }
     421             : 
     422             : #if DEBUG_EDIT_ENGINE
     423             : void EditTextObject::Dump() const
     424             : {
     425             :     mpImpl->Dump();
     426             : }
     427             : #endif
     428             : 
     429             : // from SfxItemPoolUser
     430         896 : void EditTextObjectImpl::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
     431             : {
     432         896 :     if(!bOwnerOfPool && pPool && pPool == &rSfxItemPool)
     433             :     {
     434             :         // The pool we are based on gets destructed; get owner of pool by creating own one.
     435             :         // No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor
     436             :         // Base new pool on EditEnginePool; it would also be possible to clone the used
     437             :         // pool if needed, but only text attributes should be used.
     438         896 :         SfxItemPool* pNewPool = EditEngine::CreatePool();
     439             : 
     440         896 :         if(pPool)
     441             :         {
     442         896 :             pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC));
     443             :         }
     444             : 
     445         896 :         ContentInfosType aReplaced;
     446         896 :         aReplaced.reserve(aContents.size());
     447         896 :         ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     448        1792 :         for (; it != itEnd; ++it)
     449         896 :             aReplaced.push_back(new ContentInfo(*it, *pNewPool));
     450         896 :         aReplaced.swap(aContents);
     451             : 
     452             :         // set local variables
     453         896 :         pPool = pNewPool;
     454         896 :         bOwnerOfPool = true;
     455             :     }
     456         896 : }
     457             : 
     458             : #if DEBUG_EDIT_ENGINE
     459             : void EditTextObjectImpl::Dump() const
     460             : {
     461             :     ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     462             :     for (; it != itEnd; ++it)
     463             :         it->Dump();
     464             : }
     465             : #endif
     466             : 
     467       42369 : EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
     468             : {
     469       42369 :     EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
     470             : 
     471      120456 :     while(!pRetval && pPool && pPool->GetSecondaryPool())
     472             :     {
     473       35718 :         pPool = pPool->GetSecondaryPool();
     474             : 
     475       35718 :         if(pPool)
     476             :         {
     477       35718 :             pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
     478             :         }
     479             :     }
     480             : 
     481       42369 :     return pRetval;
     482             : }
     483             : 
     484       42369 : EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, SfxItemPool* pP ) :
     485       42369 :     mpFront(pFront)
     486             : {
     487       42369 :     nVersion = 0;
     488       42369 :     nMetric = 0xFFFF;
     489       42369 :     nUserType = 0;
     490       42369 :     nObjSettings = 0;
     491       42369 :     pPortionInfo = 0;
     492             : 
     493             :     // #i101239# ensure target is a EditEngineItemPool, else
     494             :     // fallback to pool ownership. This is needed to ensure that at
     495             :     // pool destruction time of an alien pool, the pool is still alive.
     496             :     // When registering would happen at an alien pool which just uses an
     497             :     // EditEngineItemPool as some sub-pool, that pool could already
     498             :     // be decoupled and deleted which would lead to crashes.
     499       42369 :     pPool = getEditEngineItemPool(pP);
     500             : 
     501       42369 :     if ( pPool )
     502             :     {
     503       35826 :         bOwnerOfPool = false;
     504             :     }
     505             :     else
     506             :     {
     507        6543 :         pPool = EditEngine::CreatePool();
     508        6543 :         bOwnerOfPool =  true;
     509             :     }
     510             : 
     511       42369 :     if(!bOwnerOfPool && pPool)
     512             :     {
     513             :         // it is sure now that the pool is an EditEngineItemPool
     514       35826 :         pPool->AddSfxItemPoolUser(*mpFront);
     515             :     }
     516             : 
     517       42369 :     bVertical = false;
     518       42369 :     bStoreUnicodeStrings = false;
     519       42369 :     nScriptType = 0;
     520       42369 : }
     521             : 
     522       47805 : EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, const EditTextObjectImpl& r ) :
     523       47805 :     mpFront(pFront)
     524             : {
     525       47805 :     nVersion = r.nVersion;
     526       47805 :     nMetric = r.nMetric;
     527       47805 :     nUserType = r.nUserType;
     528       47805 :     nObjSettings = r.nObjSettings;
     529       47805 :     bVertical = r.bVertical;
     530       47805 :     nScriptType = r.nScriptType;
     531       47805 :     pPortionInfo = NULL;    // Do not copy PortionInfo
     532       47805 :     bStoreUnicodeStrings = false;
     533             : 
     534       47805 :     if ( !r.bOwnerOfPool )
     535             :     {
     536             :         // reuse alien pool; this must be a EditEngineItemPool
     537             :         // since there is no other way to construct a BinTextObject
     538             :         // than it's regular constructor where that is ensured
     539       36269 :         pPool = r.pPool;
     540       36269 :         bOwnerOfPool = false;
     541             :     }
     542             :     else
     543             :     {
     544       11536 :         pPool = EditEngine::CreatePool();
     545       11536 :         bOwnerOfPool =  true;
     546             : 
     547             :     }
     548             : 
     549       47805 :     if(!bOwnerOfPool && pPool)
     550             :     {
     551             :         // it is sure now that the pool is an EditEngineItemPool
     552       36269 :         pPool->AddSfxItemPoolUser(*mpFront);
     553             :     }
     554             : 
     555       47805 :     if ( bOwnerOfPool && pPool && r.pPool )
     556       11536 :         pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) );
     557             : 
     558       47805 :     aContents.reserve(r.aContents.size());
     559       47805 :     ContentInfosType::const_iterator it = r.aContents.begin(), itEnd = r.aContents.end();
     560       98623 :     for (; it != itEnd; ++it)
     561       50818 :         aContents.push_back(new ContentInfo(*it, *pPool));
     562       47805 : }
     563             : 
     564      179902 : EditTextObjectImpl::~EditTextObjectImpl()
     565             : {
     566       89951 :     if(!bOwnerOfPool && pPool)
     567             :     {
     568       71150 :         pPool->RemoveSfxItemPoolUser(*mpFront);
     569             :     }
     570             : 
     571       89951 :     ClearPortionInfo();
     572             : 
     573             :     // Remove contents before deleting the pool instance since each content
     574             :     // has to access the pool instance in its destructor.
     575       89951 :     aContents.clear();
     576       89951 :     if ( bOwnerOfPool )
     577             :     {
     578       18801 :         SfxItemPool::Free(pPool);
     579             :     }
     580       89951 : }
     581             : 
     582      241868 : sal_uInt16 EditTextObjectImpl::GetUserType() const
     583             : {
     584      241868 :     return nUserType;
     585             : }
     586             : 
     587       35423 : void EditTextObjectImpl::SetUserType( sal_uInt16 n )
     588             : {
     589       35423 :     nUserType = n;
     590       35423 : }
     591             : 
     592      289810 : bool EditTextObjectImpl::IsVertical() const
     593             : {
     594      289810 :     return bVertical;
     595             : }
     596             : 
     597       42471 : void EditTextObjectImpl::SetVertical( bool b )
     598             : {
     599       42471 :     if ( b != bVertical )
     600             :     {
     601           0 :         bVertical = b;
     602           0 :         ClearPortionInfo();
     603             :     }
     604       42471 : }
     605             : 
     606           0 : sal_uInt16 EditTextObjectImpl::GetScriptType() const
     607             : {
     608           0 :     return nScriptType;
     609             : }
     610             : 
     611       42369 : void EditTextObjectImpl::SetScriptType( sal_uInt16 nType )
     612             : {
     613       42369 :     nScriptType = nType;
     614       42369 : }
     615             : 
     616       65096 : XEditAttribute* EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
     617             : {
     618       65096 :     return MakeXEditAttribute( *pPool, rItem, nStart, nEnd );
     619             : }
     620             : 
     621           0 : void EditTextObjectImpl::DestroyAttrib( XEditAttribute* pAttr )
     622             : {
     623           0 :     pPool->Remove( *pAttr->GetItem() );
     624           0 :     delete pAttr;
     625           0 : }
     626             : 
     627      427483 : EditTextObjectImpl::ContentInfosType& EditTextObjectImpl::GetContents()
     628             : {
     629      427483 :     return aContents;
     630             : }
     631             : 
     632           0 : const EditTextObjectImpl::ContentInfosType& EditTextObjectImpl::GetContents() const
     633             : {
     634           0 :     return aContents;
     635             : }
     636             : 
     637       46248 : ContentInfo* EditTextObjectImpl::CreateAndInsertContent()
     638             : {
     639       46248 :     aContents.push_back(new ContentInfo(*pPool));
     640       46248 :     return &aContents.back();
     641             : }
     642             : 
     643       18370 : sal_Int32 EditTextObjectImpl::GetParagraphCount() const
     644             : {
     645       18370 :     size_t nSize = aContents.size();
     646       18370 :     if (nSize > EE_PARA_MAX_COUNT)
     647             :     {
     648             :         SAL_WARN( "editeng", "EditTextObjectImpl::GetParagraphCount - overflow " << nSize);
     649           0 :         return EE_PARA_MAX_COUNT;
     650             :     }
     651       18370 :     return static_cast<sal_Int32>(nSize);
     652             : }
     653             : 
     654       14989 : String EditTextObjectImpl::GetText(sal_Int32 nPara) const
     655             : {
     656       14989 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     657           0 :         return String();
     658             : 
     659       14989 :     return aContents[nPara].GetText();
     660             : }
     661             : 
     662       90043 : void EditTextObjectImpl::ClearPortionInfo()
     663             : {
     664       90043 :     if ( pPortionInfo )
     665             :     {
     666           0 :         delete pPortionInfo;
     667           0 :         pPortionInfo = NULL;
     668             :     }
     669       90043 : }
     670             : 
     671           3 : bool EditTextObjectImpl::HasOnlineSpellErrors() const
     672             : {
     673           3 :     ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     674          15 :     for (; it != itEnd; ++it)
     675             :     {
     676          13 :         if ( it->GetWrongList() && !it->GetWrongList()->empty() )
     677           1 :             return true;
     678             :     }
     679           2 :     return false;
     680             : }
     681             : 
     682           6 : void EditTextObjectImpl::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
     683             : {
     684           6 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     685           6 :         return;
     686             : 
     687           6 :     rLst.clear();
     688           6 :     const ContentInfo& rC = aContents[nPara];
     689          38 :     for (size_t nAttr = 0; nAttr < rC.aAttribs.size(); ++nAttr)
     690             :     {
     691          32 :         const XEditAttribute& rAttr = rC.aAttribs[nAttr];
     692             :         EECharAttrib aEEAttr;
     693          32 :         aEEAttr.pAttr = rAttr.GetItem();
     694          32 :         aEEAttr.nPara = nPara;
     695          32 :         aEEAttr.nStart = rAttr.GetStart();
     696          32 :         aEEAttr.nEnd = rAttr.GetEnd();
     697          32 :         rLst.push_back(aEEAttr);
     698             :     }
     699             : }
     700             : 
     701           0 : bool EditTextObjectImpl::IsFieldObject() const
     702             : {
     703           0 :     return GetField() ? true : false;
     704             : }
     705             : 
     706           0 : const SvxFieldItem* EditTextObjectImpl::GetField() const
     707             : {
     708           0 :     if (aContents.size() == 1)
     709             :     {
     710           0 :         const ContentInfo& rC = aContents[0];
     711           0 :         if (rC.GetText().Len() == 1)
     712             :         {
     713           0 :             size_t nAttribs = rC.aAttribs.size();
     714           0 :             for (size_t nAttr = nAttribs; nAttr; )
     715             :             {
     716           0 :                 const XEditAttribute& rX = rC.aAttribs[--nAttr];
     717           0 :                 if (rX.GetItem()->Which() == EE_FEATURE_FIELD)
     718           0 :                     return static_cast<const SvxFieldItem*>(rX.GetItem());
     719             :             }
     720             :         }
     721             :     }
     722           0 :     return 0;
     723             : }
     724             : 
     725           1 : const SvxFieldData* EditTextObjectImpl::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
     726             : {
     727           1 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     728           0 :         return NULL;
     729             : 
     730           1 :     const ContentInfo& rC = aContents[nPara];
     731           1 :     if (nPos >= rC.aAttribs.size())
     732             :         // URL position is out-of-bound.
     733           0 :         return NULL;
     734             : 
     735           1 :     ContentInfo::XEditAttributesType::const_iterator it = rC.aAttribs.begin(), itEnd = rC.aAttribs.end();
     736           1 :     size_t nCurPos = 0;
     737           1 :     for (; it != itEnd; ++it)
     738             :     {
     739           1 :         const XEditAttribute& rAttr = *it;
     740           1 :         if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
     741             :             // Skip attributes that are not fields.
     742           0 :             continue;
     743             : 
     744           1 :         const SvxFieldItem* pField = static_cast<const SvxFieldItem*>(rAttr.GetItem());
     745           1 :         const SvxFieldData* pFldData = pField->GetField();
     746           1 :         if (nType != text::textfield::Type::UNSPECIFIED && nType != pFldData->GetClassId())
     747             :             // Field type doesn't match. Skip it.  UNSPECIFIED matches all field types.
     748           0 :             continue;
     749             : 
     750           1 :         if (nCurPos == nPos)
     751             :             // Found it!
     752           1 :             return pFldData;
     753             : 
     754           0 :         ++nCurPos;
     755             :     }
     756             : 
     757           0 :     return NULL; // field not found.
     758             : }
     759             : 
     760      154540 : bool EditTextObjectImpl::HasField( sal_Int32 nType ) const
     761             : {
     762      154540 :     size_t nParagraphs = aContents.size();
     763      323715 :     for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
     764             :     {
     765      170724 :         const ContentInfo& rC = aContents[nPara];
     766      170724 :         size_t nAttrs = rC.aAttribs.size();
     767      321169 :         for (size_t nAttr = 0; nAttr < nAttrs; ++nAttr)
     768             :         {
     769      151994 :             const XEditAttribute& rAttr = rC.aAttribs[nAttr];
     770      151994 :             if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
     771      147045 :                 continue;
     772             : 
     773        4949 :             if (nType == text::textfield::Type::UNSPECIFIED)
     774             :                 // Match any field type.
     775           0 :                 return true;
     776             : 
     777        4949 :             const SvxFieldData* pFldData = static_cast<const SvxFieldItem*>(rAttr.GetItem())->GetField();
     778        4949 :             if (pFldData && pFldData->GetClassId() == nType)
     779        1549 :                 return true;
     780             :         }
     781             :     }
     782      152991 :     return false;
     783             : }
     784             : 
     785           3 : const SfxItemSet& EditTextObjectImpl::GetParaAttribs(sal_Int32 nPara) const
     786             : {
     787           3 :     const ContentInfo& rC = aContents[nPara];
     788           3 :     return rC.GetParaAttribs();
     789             : }
     790             : 
     791           0 : void EditTextObjectImpl::SetParaAttribs(sal_Int32 nPara, const SfxItemSet& rAttribs)
     792             : {
     793           0 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     794           0 :         return;
     795             : 
     796           0 :     ContentInfo& rC = aContents[nPara];
     797           0 :     rC.GetParaAttribs().Set(rAttribs);
     798           0 :     ClearPortionInfo();
     799             : }
     800             : 
     801           0 : bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 _nWhich )
     802             : {
     803           0 :     bool bChanged = false;
     804             : 
     805           0 :     for ( size_t nPara = aContents.size(); nPara; )
     806             :     {
     807           0 :         ContentInfo& rC = aContents[--nPara];
     808             : 
     809           0 :         for (size_t nAttr = rC.aAttribs.size(); nAttr; )
     810             :         {
     811           0 :             XEditAttribute& rAttr = rC.aAttribs[--nAttr];
     812           0 :             if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) )
     813             :             {
     814           0 :                 pPool->Remove(*rAttr.GetItem());
     815           0 :                 rC.aAttribs.erase(rC.aAttribs.begin()+nAttr);
     816           0 :                 bChanged = true;
     817             :             }
     818             :         }
     819             :     }
     820             : 
     821           0 :     if ( bChanged )
     822           0 :         ClearPortionInfo();
     823             : 
     824           0 :     return bChanged;
     825             : }
     826             : 
     827        5339 : void EditTextObjectImpl::GetStyleSheet(sal_Int32 nPara, String& rName, SfxStyleFamily& rFamily) const
     828             : {
     829        5339 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     830        5339 :         return;
     831             : 
     832        5339 :     const ContentInfo& rC = aContents[nPara];
     833        5339 :     rName = rC.GetStyle();
     834        5339 :     rFamily = rC.GetFamily();
     835             : }
     836             : 
     837           0 : void EditTextObjectImpl::SetStyleSheet(sal_Int32 nPara, const String& rName, const SfxStyleFamily& rFamily)
     838             : {
     839           0 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     840           0 :         return;
     841             : 
     842           0 :     ContentInfo& rC = aContents[nPara];
     843           0 :     rC.GetStyle() = rName;
     844           0 :     rC.GetFamily() = rFamily;
     845             : }
     846             : 
     847        1638 : bool EditTextObjectImpl::ImpChangeStyleSheets(
     848             :                     const XubString& rOldName, SfxStyleFamily eOldFamily,
     849             :                     const XubString& rNewName, SfxStyleFamily eNewFamily )
     850             : {
     851        1638 :     const size_t nParagraphs = aContents.size();
     852        1638 :     bool bChanges = false;
     853             : 
     854        3360 :     for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
     855             :     {
     856        1722 :         ContentInfo& rC = aContents[nPara];
     857        1722 :         if ( rC.GetFamily() == eOldFamily )
     858             :         {
     859        1274 :             if ( rC.GetStyle() == rOldName )
     860             :             {
     861          91 :                 rC.GetStyle() = rNewName;
     862          91 :                 rC.GetFamily() = eNewFamily;
     863          91 :                 bChanges = true;
     864             :             }
     865             :         }
     866             :     }
     867        1638 :     return bChanges;
     868             : }
     869             : 
     870        1638 : bool EditTextObjectImpl::ChangeStyleSheets(
     871             :                     const XubString& rOldName, SfxStyleFamily eOldFamily,
     872             :                     const XubString& rNewName, SfxStyleFamily eNewFamily )
     873             : {
     874        1638 :     sal_Bool bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
     875        1638 :     if ( bChanges )
     876          91 :         ClearPortionInfo();
     877             : 
     878        1638 :     return bChanges;
     879             : }
     880             : 
     881           0 : void EditTextObjectImpl::ChangeStyleSheetName( SfxStyleFamily eFamily,
     882             :                 const XubString& rOldName, const XubString& rNewName )
     883             : {
     884           0 :     ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
     885           0 : }
     886             : 
     887           0 : editeng::FieldUpdater EditTextObjectImpl::GetFieldUpdater()
     888             : {
     889           0 :     return editeng::FieldUpdater(*mpFront);
     890             : }
     891             : 
     892             : namespace {
     893             : 
     894             : class FindAttribByChar : public std::unary_function<XEditAttribute, bool>
     895             : {
     896             :     sal_uInt16 mnWhich;
     897             :     sal_uInt16 mnChar;
     898             : public:
     899           0 :     FindAttribByChar(sal_uInt16 nWhich, sal_uInt16 nChar) : mnWhich(nWhich), mnChar(nChar) {}
     900           0 :     bool operator() (const XEditAttribute& rAttr) const
     901             :     {
     902           0 :         return (rAttr.GetItem()->Which() == mnWhich) && (rAttr.GetStart() <= mnChar) && (rAttr.GetEnd() > mnChar);
     903             :     }
     904             : };
     905             : 
     906             : }
     907             : 
     908        2480 : void EditTextObjectImpl::StoreData( SvStream& rOStream ) const
     909             : {
     910        2480 :     sal_uInt16 nVer = 602;
     911        2480 :     rOStream << nVer;
     912             : 
     913        2480 :     rOStream << static_cast<sal_Bool>(bOwnerOfPool);
     914             : 
     915             :     // First store the pool, later only the Surregate
     916        2480 :     if ( bOwnerOfPool )
     917             :     {
     918        2456 :         GetPool()->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 );
     919        2456 :         GetPool()->Store( rOStream );
     920             :     }
     921             : 
     922             :     // Store Current text encoding ...
     923        2480 :     rtl_TextEncoding eEncoding = GetSOStoreTextEncoding( osl_getThreadTextEncoding() );
     924        2480 :     rOStream << (sal_uInt16) eEncoding;
     925             : 
     926             :     // The number of paragraphs ...
     927        2480 :     size_t nParagraphs = aContents.size();
     928             :     // FIXME: this truncates, check usage of stream and if it can be changed,
     929             :     // i.e. is not persistent, adapt this and reader.
     930        2480 :     sal_uInt16 nParagraphs_Stream = static_cast<sal_uInt16>(nParagraphs);
     931        2480 :     rOStream << nParagraphs_Stream;
     932             : 
     933        2480 :     sal_Unicode nUniChar = CH_FEATURE;
     934        2480 :     char cFeatureConverted = OString(&nUniChar, 1, eEncoding).toChar();
     935             : 
     936             :     // The individual paragraphs ...
     937        4960 :     for (size_t nPara = 0; nPara < nParagraphs_Stream; ++nPara)
     938             :     {
     939        2480 :         const ContentInfo& rC = aContents[nPara];
     940             : 
     941             :         // Text...
     942        2480 :         OStringBuffer aBuffer(OUStringToOString(rC.GetText(), eEncoding));
     943             : 
     944             :         // Symbols?
     945        2480 :         bool bSymbolPara = false;
     946        2480 :         if (rC.GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON)
     947             :         {
     948         186 :             const SvxFontItem& rFontItem = (const SvxFontItem&)rC.GetParaAttribs().Get(EE_CHAR_FONTINFO);
     949         186 :             if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
     950             :             {
     951           0 :                 aBuffer = OStringBuffer(OUStringToOString(rC.GetText(), RTL_TEXTENCODING_SYMBOL));
     952           0 :                 bSymbolPara = true;
     953             :             }
     954             :         }
     955        5620 :         for (size_t nA = 0; nA < rC.aAttribs.size(); ++nA)
     956             :         {
     957        3140 :             const XEditAttribute& rAttr = rC.aAttribs[nA];
     958             : 
     959        3140 :             if (rAttr.GetItem()->Which() == EE_CHAR_FONTINFO)
     960             :             {
     961         180 :                 const SvxFontItem& rFontItem = (const SvxFontItem&)*rAttr.GetItem();
     962         540 :                 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
     963         360 :                       || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
     964             :                 {
     965             :                     // Not correctly converted
     966           0 :                     String aPart( rC.GetText(), rAttr.GetStart(), rAttr.GetEnd() - rAttr.GetStart() );
     967           0 :                     OString aNew(OUStringToOString(aPart, rFontItem.GetCharSet()));
     968           0 :                     aBuffer.remove(rAttr.GetStart(), rAttr.GetEnd() - rAttr.GetStart());
     969           0 :                     aBuffer.insert(rAttr.GetStart(), aNew);
     970             :                 }
     971             : 
     972             :                 // Convert StarSymbol back to StarBats
     973         180 :                 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
     974         180 :                 if ( hConv )
     975             :                 {
     976             :                     // Don't create a new Attrib with StarBats font, MBR changed the
     977             :                     // SvxFontItem::Store() to store StarBats instead of StarSymbol!
     978           0 :                     for (sal_uInt16 nChar = rAttr.GetStart(); nChar < rAttr.GetEnd(); ++nChar)
     979             :                     {
     980           0 :                         sal_Unicode cOld = rC.GetText().GetChar( nChar );
     981           0 :                         char cConv = OUStringToOString(OUString(ConvertFontToSubsFontChar(hConv, cOld)), RTL_TEXTENCODING_SYMBOL).toChar();
     982           0 :                         if ( cConv )
     983           0 :                             aBuffer[nChar] = cConv;
     984             :                     }
     985             : 
     986           0 :                     DestroyFontToSubsFontConverter( hConv );
     987             :                 }
     988             :             }
     989             :         }
     990             : 
     991             :         // Convert StarSymbol back to StarBats
     992             :         // StarSymbol as paragraph attribute or in StyleSheet?
     993             : 
     994        2480 :         FontToSubsFontConverter hConv = NULL;
     995        2480 :         if (rC.GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON)
     996             :         {
     997         186 :             hConv = CreateFontToSubsFontConverter( ((const SvxFontItem&)rC.GetParaAttribs().Get( EE_CHAR_FONTINFO )).GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
     998             :         }
     999        2480 :         if ( hConv )
    1000             :         {
    1001           0 :             for ( sal_uInt16 nChar = 0; nChar < rC.GetText().Len(); nChar++ )
    1002             :             {
    1003           0 :                 const ContentInfo::XEditAttributesType& rAttribs = rC.aAttribs;
    1004             :                 ContentInfo::XEditAttributesType::const_iterator it =
    1005             :                     std::find_if(rAttribs.begin(), rAttribs.end(),
    1006           0 :                                  FindAttribByChar(EE_CHAR_FONTINFO, nChar));
    1007             : 
    1008           0 :                 if (it == rAttribs.end())
    1009             :                 {
    1010           0 :                     sal_Unicode cOld = rC.GetText().GetChar( nChar );
    1011           0 :                     char cConv = OUStringToOString(OUString(ConvertFontToSubsFontChar(hConv, cOld)), RTL_TEXTENCODING_SYMBOL).toChar();
    1012           0 :                     if ( cConv )
    1013           0 :                         aBuffer[nChar] = cConv;
    1014             :                 }
    1015             :             }
    1016             : 
    1017           0 :             DestroyFontToSubsFontConverter( hConv );
    1018             : 
    1019             :         }
    1020             : 
    1021             : 
    1022             :         // Convert CH_FEATURE to CH_FEATURE_OLD
    1023        4960 :         OString aText = aBuffer.makeStringAndClear().replace(cFeatureConverted, CH_FEATURE_OLD);
    1024        2480 :         write_lenPrefixed_uInt8s_FromOString<sal_uInt16>(rOStream, aText);
    1025             : 
    1026             :         // StyleName and Family...
    1027        2480 :         write_lenPrefixed_uInt8s_FromOUString<sal_uInt16>(rOStream, rC.GetStyle(), eEncoding);
    1028        2480 :         rOStream << static_cast<sal_uInt16>(rC.GetFamily());
    1029             : 
    1030             :         // Paragraph attributes ...
    1031        2480 :         rC.GetParaAttribs().Store( rOStream );
    1032             : 
    1033             :         // The number of attributes ...
    1034        2480 :         size_t nAttribs = rC.aAttribs.size();
    1035        2480 :         rOStream << static_cast<sal_uInt16>(nAttribs);
    1036             : 
    1037             :         // And the individual attributes
    1038             :         // Items as Surregate => always 8 bytes per Attribute
    1039             :         // Which = 2; Surregat = 2; Start = 2; End = 2;
    1040        5620 :         for (size_t nAttr = 0; nAttr < nAttribs; ++nAttr)
    1041             :         {
    1042        3140 :             const XEditAttribute& rX = rC.aAttribs[nAttr];
    1043             : 
    1044        3140 :             rOStream << rX.GetItem()->Which();
    1045        3140 :             GetPool()->StoreSurrogate(rOStream, rX.GetItem());
    1046        3140 :             rOStream << rX.GetStart();
    1047        3140 :             rOStream << rX.GetEnd();
    1048             :         }
    1049        2480 :     }
    1050             : 
    1051        2480 :     rOStream << nMetric;
    1052             : 
    1053        2480 :     rOStream << nUserType;
    1054        2480 :     rOStream << nObjSettings;
    1055             : 
    1056        2480 :     rOStream << static_cast<sal_Bool>(bVertical);
    1057        2480 :     rOStream << nScriptType;
    1058             : 
    1059        2480 :     rOStream << static_cast<sal_Bool>(bStoreUnicodeStrings);
    1060        2480 :     if ( bStoreUnicodeStrings )
    1061             :     {
    1062           0 :         for ( size_t nPara = 0; nPara < nParagraphs_Stream; nPara++ )
    1063             :         {
    1064           0 :             const ContentInfo& rC = aContents[nPara];
    1065           0 :             sal_uInt16 nL = rC.GetText().Len();
    1066           0 :             rOStream << nL;
    1067           0 :             rOStream.Write(rC.GetText().GetBuffer(), nL*sizeof(sal_Unicode));
    1068             : 
    1069             :             // StyleSheetName must be Unicode too!
    1070             :             // Copy/Paste from EA3 to BETA or from BETA to EA3 not possible, not needed...
    1071             :             // If needed, change nL back to sal_uLong and increase version...
    1072           0 :             nL = rC.GetStyle().Len();
    1073           0 :             rOStream << nL;
    1074           0 :             rOStream.Write(rC.GetStyle().GetBuffer(), nL*sizeof(sal_Unicode));
    1075             :         }
    1076             :     }
    1077        2480 : }
    1078             : 
    1079           0 : void EditTextObjectImpl::CreateData( SvStream& rIStream )
    1080             : {
    1081           0 :     rIStream >> nVersion;
    1082             : 
    1083             :     // The text object was first created with the current setting of
    1084             :     // pTextObjectPool.
    1085           0 :     sal_Bool bOwnerOfCurrent = bOwnerOfPool;
    1086             :     sal_Bool b;
    1087           0 :     rIStream >> b;
    1088           0 :     bOwnerOfPool = b;
    1089             : 
    1090           0 :     if ( bOwnerOfCurrent && !bOwnerOfPool )
    1091             :     {
    1092             :         // A global Pool was used, but not handed over to me, but I need it!
    1093             :         OSL_FAIL( "Give me the global TextObjectPool!" );
    1094           0 :         return;
    1095             :     }
    1096           0 :     else if ( !bOwnerOfCurrent && bOwnerOfPool )
    1097             :     {
    1098             :         // A global Pool should be used, but this Textobject has its own.
    1099           0 :         pPool = EditEngine::CreatePool();
    1100             :     }
    1101             : 
    1102           0 :     if ( bOwnerOfPool )
    1103           0 :         GetPool()->Load( rIStream );
    1104             : 
    1105             :     // CharSet, in which it was saved:
    1106             :     sal_uInt16 nCharSet;
    1107           0 :     rIStream >> nCharSet;
    1108             : 
    1109           0 :     rtl_TextEncoding eSrcEncoding = GetSOLoadTextEncoding( (rtl_TextEncoding)nCharSet );
    1110             : 
    1111             :     // The number of paragraphs ...
    1112             :     sal_uInt16 nParagraphs;
    1113           0 :     rIStream >> nParagraphs;
    1114             : 
    1115             :     // The individual paragraphs ...
    1116           0 :     for ( sal_uLong nPara = 0; nPara < nParagraphs; nPara++ )
    1117             :     {
    1118           0 :         ContentInfo* pC = CreateAndInsertContent();
    1119             : 
    1120             :         // The Text...
    1121           0 :         OString aByteString = read_lenPrefixed_uInt8s_ToOString<sal_uInt16>(rIStream);
    1122           0 :         pC->GetText() = OStringToOUString(aByteString, eSrcEncoding);
    1123             : 
    1124             :         // StyleName and Family...
    1125           0 :         pC->GetStyle() = rIStream.ReadUniOrByteString(eSrcEncoding);
    1126             :         sal_uInt16 nStyleFamily;
    1127           0 :         rIStream >> nStyleFamily;
    1128           0 :         pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
    1129             : 
    1130             :         // Paragraph attributes ...
    1131           0 :         pC->GetParaAttribs().Load( rIStream );
    1132             : 
    1133             :         // The number of attributes ...
    1134             :         sal_uInt16 nTmp16;
    1135           0 :         rIStream >> nTmp16;
    1136           0 :         size_t nAttribs = nTmp16;
    1137             : 
    1138             :         // And the individual attributes
    1139             :         // Items as Surregate => always 8 bytes per Attributes
    1140             :         // Which = 2; Surregat = 2; Start = 2; End = 2;
    1141             :         size_t nAttr;
    1142           0 :         for (nAttr = 0; nAttr < nAttribs; ++nAttr)
    1143             :         {
    1144             :             sal_uInt16 _nWhich, nStart, nEnd;
    1145             :             const SfxPoolItem* pItem;
    1146             : 
    1147           0 :             rIStream >> _nWhich;
    1148           0 :             _nWhich = pPool->GetNewWhich( _nWhich );
    1149           0 :             pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
    1150           0 :             rIStream >> nStart;
    1151           0 :             rIStream >> nEnd;
    1152           0 :             if ( pItem )
    1153             :             {
    1154           0 :                 if ( pItem->Which() == EE_FEATURE_NOTCONV )
    1155             :                 {
    1156           0 :                     sal_Char cEncodedChar = aByteString[nStart];
    1157             :                     sal_Unicode cChar = OUString(&cEncodedChar, 1,
    1158           0 :                         ((SvxCharSetColorItem*)pItem)->GetCharSet()).toChar();
    1159           0 :                     pC->GetText().SetChar(nStart, cChar);
    1160             :                 }
    1161             :                 else
    1162             :                 {
    1163           0 :                     XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
    1164           0 :                     pC->aAttribs.push_back(pAttr);
    1165             : 
    1166           0 :                     if ( ( _nWhich >= EE_FEATURE_START ) && ( _nWhich <= EE_FEATURE_END ) )
    1167             :                     {
    1168             :                         // Convert CH_FEATURE to CH_FEATURE_OLD
    1169             :                         DBG_ASSERT( (sal_uInt8) aByteString[nStart] == CH_FEATURE_OLD, "CreateData: CH_FEATURE expected!" );
    1170           0 :                         if ( (sal_uInt8) aByteString[nStart] == CH_FEATURE_OLD )
    1171           0 :                             pC->GetText().SetChar( nStart, CH_FEATURE );
    1172             :                     }
    1173             :                 }
    1174             :             }
    1175             :         }
    1176             : 
    1177             :         // But check for paragraph and character symbol attribs here,
    1178             :         // FinishLoad will not be called in OpenOffice Calc, no StyleSheets...
    1179             : 
    1180           0 :         sal_Bool bSymbolPara = false;
    1181           0 :         if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
    1182             :         {
    1183           0 :             const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
    1184           0 :             if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
    1185             :             {
    1186           0 :                 pC->GetText() = OStringToOUString(aByteString, RTL_TEXTENCODING_SYMBOL);
    1187           0 :                 bSymbolPara = true;
    1188             :             }
    1189             :         }
    1190             : 
    1191           0 :         for (nAttr = pC->aAttribs.size(); nAttr; )
    1192             :         {
    1193           0 :             const XEditAttribute& rAttr = pC->aAttribs[--nAttr];
    1194           0 :             if ( rAttr.GetItem()->Which() == EE_CHAR_FONTINFO )
    1195             :             {
    1196           0 :                 const SvxFontItem& rFontItem = (const SvxFontItem&)*rAttr.GetItem();
    1197           0 :                 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
    1198           0 :                       || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
    1199             :                 {
    1200             :                     // Not correctly converted
    1201           0 :                     OString aPart(aByteString.copy(rAttr.GetStart(), rAttr.GetEnd()-rAttr.GetStart()));
    1202           0 :                     OUString aNew(OStringToOUString(aPart, rFontItem.GetCharSet()));
    1203           0 :                     pC->GetText().Erase( rAttr.GetStart(), rAttr.GetEnd()-rAttr.GetStart() );
    1204           0 :                     pC->GetText().Insert( aNew, rAttr.GetStart() );
    1205             :                 }
    1206             : 
    1207             :                 // Convert StarMath and StarBats to StarSymbol
    1208           0 :                 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
    1209           0 :                 if ( hConv )
    1210             :                 {
    1211           0 :                     SvxFontItem aNewFontItem( rFontItem );
    1212           0 :                     aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
    1213             : 
    1214             :                     // Replace the existing attribute with a new one.
    1215           0 :                     XEditAttribute* pNewAttr = CreateAttrib(aNewFontItem, rAttr.GetStart(), rAttr.GetEnd());
    1216             : 
    1217           0 :                     pPool->Remove(*rAttr.GetItem());
    1218           0 :                     pC->aAttribs.erase(pC->aAttribs.begin()+nAttr);
    1219           0 :                     pC->aAttribs.insert(pC->aAttribs.begin()+nAttr, pNewAttr);
    1220             : 
    1221           0 :                     for ( sal_uInt16 nChar = pNewAttr->GetStart(); nChar < pNewAttr->GetEnd(); nChar++ )
    1222             :                     {
    1223           0 :                         sal_Unicode cOld = pC->GetText().GetChar( nChar );
    1224             :                         DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
    1225           0 :                         sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
    1226           0 :                         if ( cConv )
    1227           0 :                             pC->GetText().SetChar( nChar, cConv );
    1228             :                     }
    1229             : 
    1230           0 :                     DestroyFontToSubsFontConverter( hConv );
    1231             :                 }
    1232             :             }
    1233             :         }
    1234             : 
    1235             : 
    1236             :         // Convert StarMath and StarBats to StarSymbol
    1237             :         // Maybe old symbol font as paragraph attribute?
    1238           0 :         if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
    1239             :         {
    1240           0 :             const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
    1241           0 :             FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
    1242           0 :             if ( hConv )
    1243             :             {
    1244           0 :                 SvxFontItem aNewFontItem( rFontItem );
    1245           0 :                 aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
    1246           0 :                 pC->GetParaAttribs().Put( aNewFontItem );
    1247             : 
    1248           0 :                 for ( sal_uInt16 nChar = 0; nChar < pC->GetText().Len(); nChar++ )
    1249             :                 {
    1250           0 :                     const ContentInfo::XEditAttributesType& rAttribs = pC->aAttribs;
    1251             :                     ContentInfo::XEditAttributesType::const_iterator it =
    1252             :                         std::find_if(rAttribs.begin(), rAttribs.end(),
    1253           0 :                                      FindAttribByChar(EE_CHAR_FONTINFO, nChar));
    1254             : 
    1255           0 :                     if (it == rAttribs.end())
    1256             :                     {
    1257           0 :                         sal_Unicode cOld = pC->GetText().GetChar( nChar );
    1258             :                         DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
    1259           0 :                         sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
    1260           0 :                         if ( cConv )
    1261           0 :                             pC->GetText().SetChar( nChar, cConv );
    1262             :                     }
    1263             :                 }
    1264             : 
    1265           0 :                 DestroyFontToSubsFontConverter( hConv );
    1266             :             }
    1267             :         }
    1268           0 :     }
    1269             : 
    1270             :     // From 400 also the DefMetric:
    1271           0 :     if ( nVersion >= 400 )
    1272             :     {
    1273             :         sal_uInt16 nTmpMetric;
    1274           0 :         rIStream >> nTmpMetric;
    1275           0 :         if ( nVersion >= 401 )
    1276             :         {
    1277             :             // In the 400 there was a bug in text objects with the own Pool,
    1278             :             // therefore evaluate only from 401
    1279           0 :             nMetric = nTmpMetric;
    1280           0 :             if ( bOwnerOfPool && pPool && ( nMetric != 0xFFFF ) )
    1281           0 :                 pPool->SetDefaultMetric( (SfxMapUnit)nMetric );
    1282             :         }
    1283             :     }
    1284             : 
    1285           0 :     if ( nVersion >= 600 )
    1286             :     {
    1287           0 :         rIStream >> nUserType;
    1288           0 :         rIStream >> nObjSettings;
    1289             :     }
    1290             : 
    1291           0 :     if ( nVersion >= 601 )
    1292             :     {
    1293             :         sal_Bool bTmp;
    1294           0 :         rIStream >> bTmp;
    1295           0 :         bVertical = bTmp;
    1296             :     }
    1297             : 
    1298           0 :     if ( nVersion >= 602 )
    1299             :     {
    1300           0 :         rIStream >> nScriptType;
    1301             : 
    1302             :         sal_Bool bUnicodeStrings;
    1303           0 :         rIStream >> bUnicodeStrings;
    1304           0 :         if ( bUnicodeStrings )
    1305             :         {
    1306           0 :             for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
    1307             :             {
    1308           0 :                 ContentInfo& rC = aContents[nPara];
    1309             :                 sal_uInt16 nL;
    1310             : 
    1311             :                 // Text
    1312           0 :                 rIStream >> nL;
    1313           0 :                 if ( nL )
    1314             :                 {
    1315           0 :                     rtl_uString *pStr = rtl_uString_alloc(nL);
    1316           0 :                     rIStream.Read(pStr->buffer, nL*sizeof(sal_Unicode));
    1317           0 :                     rC.GetText() = OUString(pStr, SAL_NO_ACQUIRE);
    1318             :                 }
    1319             : 
    1320             :                 // StyleSheetName
    1321           0 :                 rIStream >> nL;
    1322           0 :                 if ( nL )
    1323             :                 {
    1324           0 :                     rtl_uString *pStr = rtl_uString_alloc(nL);
    1325           0 :                     rIStream.Read(pStr->buffer, nL*sizeof(sal_Unicode) );
    1326           0 :                     rC.GetStyle() = OUString(pStr, SAL_NO_ACQUIRE);
    1327             :                 }
    1328             :             }
    1329             :         }
    1330             :     }
    1331             : 
    1332             : 
    1333             :     // from 500 the tabs are interpreted differently: TabPos + LI, previously only TabPos.
    1334             :     // Works only if tab positions are set, not when DefTab.
    1335           0 :     if ( nVersion < 500 )
    1336             :     {
    1337           0 :         for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1338             :         {
    1339           0 :             ContentInfo& rC = aContents[i];
    1340           0 :             const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(rC.GetParaAttribs().Get(EE_PARA_LRSPACE));
    1341           0 :             if ( rLRSpace.GetTxtLeft() && ( rC.GetParaAttribs().GetItemState( EE_PARA_TABS ) == SFX_ITEM_ON ) )
    1342             :             {
    1343           0 :                 const SvxTabStopItem& rTabs = static_cast<const SvxTabStopItem&>(rC.GetParaAttribs().Get(EE_PARA_TABS));
    1344           0 :                 SvxTabStopItem aNewTabs( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
    1345           0 :                 for ( sal_uInt16 t = 0; t < rTabs.Count(); t++ )
    1346             :                 {
    1347           0 :                     const SvxTabStop& rT = rTabs[ t ];
    1348           0 :                     aNewTabs.Insert( SvxTabStop( rT.GetTabPos() - rLRSpace.GetTxtLeft(),
    1349           0 :                                 rT.GetAdjustment(), rT.GetDecimal(), rT.GetFill() ) );
    1350             :                 }
    1351           0 :                 rC.GetParaAttribs().Put( aNewTabs );
    1352             :             }
    1353             :         }
    1354             :     }
    1355             : }
    1356             : 
    1357        1431 : bool EditTextObjectImpl::operator==( const EditTextObjectImpl& rCompare ) const
    1358             : {
    1359        1431 :     if( this == &rCompare )
    1360           0 :         return true;
    1361             : 
    1362        4273 :     if( ( aContents.size() != rCompare.aContents.size() ) ||
    1363        2822 :             ( pPool != rCompare.pPool ) ||
    1364        2822 :             ( nMetric != rCompare.nMetric ) ||
    1365        2822 :             ( nUserType!= rCompare.nUserType ) ||
    1366        4253 :             ( nScriptType != rCompare.nScriptType ) ||
    1367        1411 :             ( bVertical != rCompare.bVertical ) )
    1368          20 :         return false;
    1369             : 
    1370        2668 :     for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1371             :     {
    1372        1989 :         if (aContents[i] != rCompare.aContents[i])
    1373         732 :             return false;
    1374             :     }
    1375             : 
    1376         679 :     return true;
    1377             : }
    1378             : 
    1379             : // #i102062#
    1380         665 : bool EditTextObjectImpl::isWrongListEqual(const EditTextObjectImpl& rCompare) const
    1381             : {
    1382         665 :     if (aContents.size() != rCompare.aContents.size())
    1383             :     {
    1384           0 :         return false;
    1385             :     }
    1386             : 
    1387        1672 :     for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1388             :     {
    1389        1007 :         const ContentInfo& rCandA = aContents[i];
    1390        1007 :         const ContentInfo& rCandB = rCompare.aContents[i];
    1391             : 
    1392        1007 :         if(!rCandA.isWrongListEqual(rCandB))
    1393             :         {
    1394           0 :             return false;
    1395             :         }
    1396             :     }
    1397             : 
    1398         665 :     return true;
    1399         267 : }
    1400             : 
    1401             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10