LCOV - code coverage report
Current view: top level - editeng/source/editeng - editobj.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 459 755 60.8 %
Date: 2015-06-13 12:38:46 Functions: 75 98 76.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 <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 "editeng/section.hxx"
      32             : #include <editobj2.hxx>
      33             : #include <editeng/editdata.hxx>
      34             : #include <editattr.hxx>
      35             : #include <editeng/editeng.hxx>
      36             : #include <editeng/fontitem.hxx>
      37             : #include <editeng/charsetcoloritem.hxx>
      38             : #include <editeng/flditem.hxx>
      39             : #include <editeng/lrspitem.hxx>
      40             : #include <editeng/tstpitem.hxx>
      41             : #include <editeng/bulletitem.hxx>
      42             : #include <editeng/numitem.hxx>
      43             : #include <editeng/brushitem.hxx>
      44             : 
      45             : #include <vcl/graph.hxx>
      46             : #include <svl/intitem.hxx>
      47             : #include "svl/sharedstringpool.hxx"
      48             : #include <unotools/fontcvt.hxx>
      49             : #include <tools/tenccvt.hxx>
      50             : 
      51             : #include <libxml/xmlwriter.h>
      52             : #include <algorithm>
      53             : 
      54             : #if DEBUG_EDIT_ENGINE
      55             : #include <iostream>
      56             : using std::cout;
      57             : using std::endl;
      58             : #endif
      59             : 
      60             : using namespace com::sun::star;
      61             : 
      62             : 
      63             : 
      64             : 
      65      389240 : XEditAttribute* MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
      66             : {
      67             :     // Create thw new attribute in the pool
      68      389240 :     const SfxPoolItem& rNew = rPool.Put( rItem );
      69             : 
      70      389240 :     XEditAttribute* pNew = new XEditAttribute( rNew, nStart, nEnd );
      71      389240 :     return pNew;
      72             : }
      73             : 
      74      389240 : XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, sal_uInt16 nS, sal_uInt16 nE )
      75             : {
      76      389240 :     pItem = &rAttr;
      77      389240 :     nStart = nS;
      78      389240 :     nEnd = nE;
      79      389240 : }
      80             : 
      81      383845 : XEditAttribute::~XEditAttribute()
      82             : {
      83      383845 :     pItem = 0;  // belongs to the Pool.
      84      383845 : }
      85             : 
      86           0 : bool XEditAttribute::IsFeature() const
      87             : {
      88           0 :     sal_uInt16 nWhich = pItem->Which();
      89           0 :     return  ((nWhich >= EE_FEATURE_START) && (nWhich <=  EE_FEATURE_END));
      90             : }
      91             : 
      92           0 : void XEditAttribute::SetItem(const SfxPoolItem& rNew)
      93             : {
      94           0 :     pItem = &rNew;
      95           0 : }
      96             : 
      97           0 : XParaPortionList::XParaPortionList(
      98             :     OutputDevice* pRefDev, sal_uLong nPW, sal_uInt16 _nStretchX, sal_uInt16 _nStretchY) :
      99           0 :     aRefMapMode(pRefDev->GetMapMode()), nStretchX(_nStretchX), nStretchY(_nStretchY)
     100             : {
     101           0 :     nRefDevPtr = reinterpret_cast<sal_uIntPtr>(pRefDev);
     102           0 :     nPaperWidth = nPW;
     103           0 :     eRefDevType = pRefDev->GetOutDevType();
     104           0 : }
     105             : 
     106           0 : void XParaPortionList::push_back(XParaPortion* p)
     107             : {
     108           0 :     maList.push_back(p);
     109           0 : }
     110             : 
     111           0 : const XParaPortion& XParaPortionList::operator [](size_t i) const
     112             : {
     113           0 :     return maList[i];
     114             : }
     115             : 
     116      138714 : ContentInfo::ContentInfo( SfxItemPool& rPool ) :
     117             :     eFamily(SFX_STYLE_FAMILY_PARA),
     118      138714 :     aParaAttribs(rPool, EE_PARA_START, EE_CHAR_END)
     119             : {
     120      138714 : }
     121             : 
     122             : // the real Copy constructor is nonsens, since I have to work with another Pool!
     123      290669 : ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse ) :
     124             :     maText(rCopyFrom.maText),
     125             :     aStyle(rCopyFrom.aStyle),
     126             :     eFamily(rCopyFrom.eFamily),
     127      290669 :     aParaAttribs(rPoolToUse, EE_PARA_START, EE_CHAR_END)
     128             : {
     129             :     // this should ensure that the Items end up in the correct Pool!
     130      290669 :     aParaAttribs.Set( rCopyFrom.GetParaAttribs() );
     131             : 
     132      548844 :     for (size_t i = 0; i < rCopyFrom.aAttribs.size(); ++i)
     133             :     {
     134      258175 :         const XEditAttribute& rAttr = rCopyFrom.aAttribs[i];
     135             :         XEditAttribute* pMyAttr = MakeXEditAttribute(
     136      258175 :             rPoolToUse, *rAttr.GetItem(), rAttr.GetStart(), rAttr.GetEnd());
     137      258175 :         aAttribs.push_back(pMyAttr);
     138             :     }
     139             : 
     140      290669 :     if ( rCopyFrom.GetWrongList() )
     141       76460 :         mpWrongs.reset(rCopyFrom.GetWrongList()->Clone());
     142      290669 : }
     143             : 
     144      845414 : ContentInfo::~ContentInfo()
     145             : {
     146      422707 :     XEditAttributesType::iterator it = aAttribs.begin(), itEnd = aAttribs.end();
     147      806552 :     for (; it != itEnd; ++it)
     148      383845 :         aParaAttribs.GetPool()->Remove(*it->GetItem());
     149      422707 :     aAttribs.clear();
     150      422707 : }
     151             : 
     152         777 : void ContentInfo::NormalizeString( svl::SharedStringPool& rPool )
     153             : {
     154         777 :     maText = rPool.intern(OUString(maText.getData()));
     155         777 : }
     156             : 
     157             : 
     158      598888 : OUString ContentInfo::GetText() const
     159             : {
     160      598888 :     rtl_uString* p = const_cast<rtl_uString*>(maText.getData());
     161      598888 :     return OUString(p);
     162             : }
     163             : 
     164      138714 : void ContentInfo::SetText( const OUString& rStr )
     165             : {
     166      138714 :     maText = svl::SharedString(rStr.pData, NULL);
     167      138714 : }
     168             : 
     169      474409 : const WrongList* ContentInfo::GetWrongList() const
     170             : {
     171      474409 :     return mpWrongs.get();
     172             : }
     173             : 
     174       28108 : void ContentInfo::SetWrongList( WrongList* p )
     175             : {
     176       28108 :     mpWrongs.reset(p);
     177       28108 : }
     178             : 
     179             : // #i102062#
     180        1873 : bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
     181             : {
     182        1873 :     if(GetWrongList() == rCompare.GetWrongList())
     183        1821 :         return true;
     184             : 
     185          52 :     if(!GetWrongList() || !rCompare.GetWrongList())
     186          10 :         return false;
     187             : 
     188          42 :     return (*GetWrongList() == *rCompare.GetWrongList());
     189             : }
     190             : 
     191             : #if DEBUG_EDIT_ENGINE
     192             : void ContentInfo::Dump() const
     193             : {
     194             :     cout << "--" << endl;
     195             :     cout << "text: '" << OUString(const_cast<rtl_uString*>(maText.getData())) << "'" << endl;
     196             :     cout << "style: '" << aStyle << "'" << endl;
     197             : 
     198             :     XEditAttributesType::const_iterator it = aAttribs.begin(), itEnd = aAttribs.end();
     199             :     for (; it != itEnd; ++it)
     200             :     {
     201             :         const XEditAttribute& rAttr = *it;
     202             :         cout << "attribute: " << endl;
     203             :         cout << "  span: [begin=" << rAttr.GetStart() << ", end=" << rAttr.GetEnd() << "]" << endl;
     204             :         cout << "  feature: " << (rAttr.IsFeature() ? "yes":"no") << endl;
     205             :     }
     206             : }
     207             : #endif
     208             : 
     209        3874 : bool ContentInfo::operator==( const ContentInfo& rCompare ) const
     210             : {
     211       11441 :     if( (maText == rCompare.maText) &&
     212        6682 :             (aStyle == rCompare.aStyle ) &&
     213        5858 :             (aAttribs.size() == rCompare.aAttribs.size()) &&
     214        9612 :             (eFamily == rCompare.eFamily ) &&
     215        2869 :             (aParaAttribs == rCompare.aParaAttribs ) )
     216             :     {
     217       23805 :         for (size_t i = 0, n = aAttribs.size(); i < n; ++i)
     218             :         {
     219       21614 :             if (aAttribs[i] != rCompare.aAttribs[i])
     220          76 :                 return false;
     221             :         }
     222             : 
     223        2191 :         return true;
     224             :     }
     225             : 
     226        1607 :     return false;
     227             : }
     228             : 
     229        3874 : bool ContentInfo::operator!=(const ContentInfo& rCompare) const
     230             : {
     231        3874 :     return !operator==(rCompare);
     232             : }
     233             : 
     234      126335 : EditTextObject::EditTextObject( SfxItemPool* pPool ) :
     235      126335 :     mpImpl(new EditTextObjectImpl(this, pPool))
     236             : {
     237      126335 : }
     238             : 
     239      267425 : EditTextObject::EditTextObject( const EditTextObject& r ) :
     240             :     SfxItemPoolUser(),
     241      267425 :     mpImpl(new EditTextObjectImpl(this, *r.mpImpl))
     242             : {
     243      267425 : }
     244             : 
     245     1161462 : EditTextObject::~EditTextObject()
     246             : {
     247      387154 :     delete mpImpl;
     248      774308 : }
     249             : 
     250      156262 : sal_Int32 EditTextObject::GetParagraphCount() const
     251             : {
     252      156262 :     return mpImpl->GetParagraphCount();
     253             : }
     254             : 
     255      118460 : OUString EditTextObject::GetText(sal_Int32 nPara) const
     256             : {
     257      118460 :     return mpImpl->GetText(nPara);
     258             : }
     259             : 
     260          21 : void EditTextObject::ClearPortionInfo()
     261             : {
     262          21 :     mpImpl->ClearPortionInfo();
     263          21 : }
     264             : 
     265          10 : bool EditTextObject::HasOnlineSpellErrors() const
     266             : {
     267          10 :     return mpImpl->HasOnlineSpellErrors();
     268             : }
     269             : 
     270         342 : void EditTextObject::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
     271             : {
     272         342 :     mpImpl->GetCharAttribs(nPara, rLst);
     273         342 : }
     274             : 
     275           0 : bool EditTextObject::IsFieldObject() const
     276             : {
     277           0 :     return mpImpl->IsFieldObject();
     278             : }
     279             : 
     280           0 : const SvxFieldItem* EditTextObject::GetField() const
     281             : {
     282           0 :     return mpImpl->GetField();
     283             : }
     284             : 
     285           1 : const SvxFieldData* EditTextObject::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
     286             : {
     287           1 :     return mpImpl->GetFieldData(nPara, nPos, nType);
     288             : }
     289             : 
     290      479135 : bool EditTextObject::HasField( sal_Int32 nType ) const
     291             : {
     292      479135 :     return mpImpl->HasField(nType);
     293             : }
     294             : 
     295        1067 : const SfxItemSet& EditTextObject::GetParaAttribs(sal_Int32 nPara) const
     296             : {
     297        1067 :     return mpImpl->GetParaAttribs(nPara);
     298             : }
     299             : 
     300           0 : bool EditTextObject::RemoveCharAttribs( sal_uInt16 nWhich )
     301             : {
     302           0 :     return mpImpl->RemoveCharAttribs(nWhich);
     303             : }
     304             : 
     305          36 : void EditTextObject::GetAllSections( std::vector<editeng::Section>& rAttrs ) const
     306             : {
     307          36 :     mpImpl->GetAllSections(rAttrs);
     308          36 : }
     309             : 
     310       27522 : void EditTextObject::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& eFamily) const
     311             : {
     312       27522 :     mpImpl->GetStyleSheet(nPara, rName, eFamily);
     313       27522 : }
     314             : 
     315           0 : void EditTextObject::SetStyleSheet(sal_Int32 nPara, const OUString& rName, const SfxStyleFamily& eFamily)
     316             : {
     317           0 :     mpImpl->SetStyleSheet(nPara, rName, eFamily);
     318           0 : }
     319             : 
     320       19432 : bool EditTextObject::ChangeStyleSheets(
     321             :     const OUString& rOldName, SfxStyleFamily eOldFamily, const OUString& rNewName, SfxStyleFamily eNewFamily)
     322             : {
     323       19432 :     return mpImpl->ChangeStyleSheets(rOldName, eOldFamily, rNewName, eNewFamily);
     324             : }
     325             : 
     326           0 : void EditTextObject::ChangeStyleSheetName(
     327             :     SfxStyleFamily eFamily, const OUString& rOldName, const OUString& rNewName)
     328             : {
     329           0 :     mpImpl->ChangeStyleSheetName(eFamily, rOldName, rNewName);
     330           0 : }
     331             : 
     332          24 : editeng::FieldUpdater EditTextObject::GetFieldUpdater()
     333             : {
     334          24 :     return mpImpl->GetFieldUpdater();
     335             : }
     336             : 
     337         677 : void EditTextObject::NormalizeString( svl::SharedStringPool& rPool )
     338             : {
     339         677 :     mpImpl->NormalizeString(rPool);
     340         677 : }
     341             : 
     342           3 : std::vector<svl::SharedString> EditTextObject::GetSharedStrings() const
     343             : {
     344           3 :     return mpImpl->GetSharedStrings();
     345             : }
     346             : 
     347           1 : const SfxItemPool* EditTextObject::GetPool() const
     348             : {
     349           1 :     return mpImpl->GetPool();
     350             : }
     351             : 
     352      314334 : sal_uInt16 EditTextObject::GetUserType() const
     353             : {
     354      314334 :     return mpImpl->GetUserType();
     355             : }
     356             : 
     357      111196 : void EditTextObject::SetUserType( sal_uInt16 n )
     358             : {
     359      111196 :     mpImpl->SetUserType(n);
     360      111196 : }
     361             : 
     362      529504 : bool EditTextObject::IsVertical() const
     363             : {
     364      529504 :     return mpImpl->IsVertical();
     365             : }
     366             : 
     367      126501 : void EditTextObject::SetVertical( bool bVertical )
     368             : {
     369      126501 :     return mpImpl->SetVertical(bVertical);
     370             : }
     371             : 
     372           0 : SvtScriptType EditTextObject::GetScriptType() const
     373             : {
     374           0 :     return mpImpl->GetScriptType();
     375             : }
     376             : 
     377             : 
     378        6390 : bool EditTextObject::Store( SvStream& rOStream ) const
     379             : {
     380        6390 :     if ( rOStream.GetError() )
     381           0 :         return false;
     382             : 
     383        6390 :     sal_Size nStartPos = rOStream.Tell();
     384             : 
     385        6390 :     sal_uInt16 nWhich = static_cast<sal_uInt16>(EE_FORMAT_BIN);
     386        6390 :     rOStream.WriteUInt16( nWhich );
     387             : 
     388        6390 :     sal_uInt32 nStructSz = 0;
     389        6390 :     rOStream.WriteUInt32( nStructSz );
     390             : 
     391        6390 :     StoreData( rOStream );
     392             : 
     393        6390 :     sal_Size nEndPos = rOStream.Tell();
     394        6390 :     nStructSz = nEndPos - nStartPos - sizeof( nWhich ) - sizeof( nStructSz );
     395        6390 :     rOStream.Seek( nStartPos + sizeof( nWhich ) );
     396        6390 :     rOStream.WriteUInt32( nStructSz );
     397        6390 :     rOStream.Seek( nEndPos );
     398             : 
     399        6390 :     return rOStream.GetError() == 0;
     400             : }
     401             : 
     402           0 : EditTextObject* EditTextObject::Create( SvStream& rIStream, SfxItemPool* pGlobalTextObjectPool )
     403             : {
     404           0 :     sal_Size nStartPos = rIStream.Tell();
     405             : 
     406             :     // First check what type of Object...
     407             :     sal_uInt16 nWhich;
     408           0 :     rIStream.ReadUInt16( nWhich );
     409             : 
     410             :     sal_uInt32 nStructSz;
     411           0 :     rIStream.ReadUInt32( nStructSz );
     412             : 
     413           0 :     if (nWhich != EE_FORMAT_BIN)
     414             :     {
     415             :         // Unknown object we no longer support.
     416           0 :         rIStream.SetError(EE_READWRITE_WRONGFORMAT);
     417           0 :         return NULL;
     418             :     }
     419             : 
     420           0 :     if ( rIStream.GetError() )
     421           0 :         return NULL;
     422             : 
     423           0 :     EditTextObject* pTxtObj = new EditTextObject(pGlobalTextObjectPool);;
     424           0 :     pTxtObj->CreateData(rIStream);
     425             : 
     426             :     // Make sure that the stream is left at the correct place.
     427           0 :     sal_Size nFullSz = sizeof( nWhich ) + sizeof( nStructSz ) + nStructSz;
     428           0 :     rIStream.Seek( nStartPos + nFullSz );
     429           0 :     return pTxtObj;
     430             : }
     431             : 
     432        6390 : void EditTextObject::StoreData( SvStream& rStrm ) const
     433             : {
     434        6390 :     mpImpl->StoreData(rStrm);
     435        6390 : }
     436             : 
     437           0 : void EditTextObject::CreateData( SvStream& rStrm )
     438             : {
     439           0 :     mpImpl->CreateData(rStrm);
     440           0 : }
     441             : 
     442      267425 : EditTextObject* EditTextObject::Clone() const
     443             : {
     444      267425 :     return new EditTextObject(*this);
     445             : }
     446             : 
     447        3121 : bool EditTextObject::operator==( const EditTextObject& rCompare ) const
     448             : {
     449        3121 :     return mpImpl->operator==(*rCompare.mpImpl);
     450             : }
     451             : 
     452             : // #i102062#
     453        1352 : bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
     454             : {
     455        1352 :     return mpImpl->isWrongListEqual(*rCompare.mpImpl);
     456             : }
     457             : 
     458        1599 : void EditTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
     459             : {
     460        1599 :     mpImpl->ObjectInDestruction(rSfxItemPool);
     461        1599 : }
     462             : 
     463             : #if DEBUG_EDIT_ENGINE
     464             : void EditTextObject::Dump() const
     465             : {
     466             :     mpImpl->Dump();
     467             : }
     468             : #endif
     469             : 
     470           0 : void EditTextObject::dumpAsXml(xmlTextWriterPtr pWriter) const
     471             : {
     472           0 :     xmlTextWriterStartElement(pWriter, BAD_CAST("editTextObject"));
     473           0 :     sal_Int32 nCount = GetParagraphCount();
     474           0 :     for (sal_Int32 i = 0; i < nCount; ++i)
     475             :     {
     476           0 :         xmlTextWriterStartElement(pWriter, BAD_CAST("paragraph"));
     477           0 :         xmlTextWriterWriteString(pWriter, BAD_CAST(GetText(i).toUtf8().getStr()));
     478           0 :         xmlTextWriterEndElement(pWriter);
     479             :     }
     480           0 :     xmlTextWriterEndElement(pWriter);
     481           0 : }
     482             : 
     483             : // from SfxItemPoolUser
     484        1599 : void EditTextObjectImpl::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
     485             : {
     486        1599 :     if(!bOwnerOfPool && pPool && pPool == &rSfxItemPool)
     487             :     {
     488             :         // The pool we are based on gets destructed; get owner of pool by creating own one.
     489             :         // No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor
     490             :         // Base new pool on EditEnginePool; it would also be possible to clone the used
     491             :         // pool if needed, but only text attributes should be used.
     492        1599 :         SfxItemPool* pNewPool = EditEngine::CreatePool();
     493             : 
     494        1599 :         if(pPool)
     495             :         {
     496        1599 :             pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC));
     497             :         }
     498             : 
     499        1599 :         ContentInfosType aReplaced;
     500        1599 :         aReplaced.reserve(aContents.size());
     501        1599 :         ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     502        3205 :         for (; it != itEnd; ++it)
     503        1606 :             aReplaced.push_back(new ContentInfo(*it, *pNewPool));
     504        1599 :         aReplaced.swap(aContents);
     505             : 
     506             :         // set local variables
     507        1599 :         pPool = pNewPool;
     508        1599 :         bOwnerOfPool = true;
     509             :     }
     510        1599 : }
     511             : 
     512             : #if DEBUG_EDIT_ENGINE
     513             : void EditTextObjectImpl::Dump() const
     514             : {
     515             :     ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     516             :     for (; it != itEnd; ++it)
     517             :         it->Dump();
     518             : }
     519             : #endif
     520             : 
     521      126335 : EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
     522             : {
     523      126335 :     EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
     524             : 
     525      368783 :     while(!pRetval && pPool && pPool->GetSecondaryPool())
     526             :     {
     527      116113 :         pPool = pPool->GetSecondaryPool();
     528             : 
     529      116113 :         if(pPool)
     530             :         {
     531      116113 :             pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
     532             :         }
     533             :     }
     534             : 
     535      126335 :     return pRetval;
     536             : }
     537             : 
     538      126335 : EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, SfxItemPool* pP ) :
     539      126335 :     mpFront(pFront)
     540             : {
     541      126335 :     nVersion = 0;
     542      126335 :     nMetric = 0xFFFF;
     543      126335 :     nUserType = 0;
     544      126335 :     nObjSettings = 0;
     545      126335 :     pPortionInfo = 0;
     546             : 
     547             :     // #i101239# ensure target is a EditEngineItemPool, else
     548             :     // fallback to pool ownership. This is needed to ensure that at
     549             :     // pool destruction time of an alien pool, the pool is still alive.
     550             :     // When registering would happen at an alien pool which just uses an
     551             :     // EditEngineItemPool as some sub-pool, that pool could already
     552             :     // be decoupled and deleted which would lead to crashes.
     553      126335 :     pPool = getEditEngineItemPool(pP);
     554             : 
     555      126335 :     if ( pPool )
     556             :     {
     557      111762 :         bOwnerOfPool = false;
     558             :     }
     559             :     else
     560             :     {
     561       14573 :         pPool = EditEngine::CreatePool();
     562       14573 :         bOwnerOfPool =  true;
     563             :     }
     564             : 
     565      126335 :     if(!bOwnerOfPool && pPool)
     566             :     {
     567             :         // it is sure now that the pool is an EditEngineItemPool
     568      111762 :         pPool->AddSfxItemPoolUser(*mpFront);
     569             :     }
     570             : 
     571      126335 :     bVertical = false;
     572      126335 :     bStoreUnicodeStrings = false;
     573      126335 :     nScriptType = SvtScriptType::NONE;
     574      126335 : }
     575             : 
     576      267425 : EditTextObjectImpl::EditTextObjectImpl( EditTextObject* pFront, const EditTextObjectImpl& r ) :
     577      267425 :     mpFront(pFront)
     578             : {
     579      267425 :     nVersion = r.nVersion;
     580      267425 :     nMetric = r.nMetric;
     581      267425 :     nUserType = r.nUserType;
     582      267425 :     nObjSettings = r.nObjSettings;
     583      267425 :     bVertical = r.bVertical;
     584      267425 :     nScriptType = r.nScriptType;
     585      267425 :     pPortionInfo = NULL;    // Do not copy PortionInfo
     586      267425 :     bStoreUnicodeStrings = false;
     587             : 
     588      267425 :     if ( !r.bOwnerOfPool )
     589             :     {
     590             :         // reuse alien pool; this must be a EditEngineItemPool
     591             :         // since there is no other way to construct a BinTextObject
     592             :         // than it's regular constructor where that is ensured
     593      242384 :         pPool = r.pPool;
     594      242384 :         bOwnerOfPool = false;
     595             :     }
     596             :     else
     597             :     {
     598       25041 :         pPool = EditEngine::CreatePool();
     599       25041 :         bOwnerOfPool = true;
     600             : 
     601             :     }
     602             : 
     603      267425 :     if (!bOwnerOfPool)
     604             :     {
     605             :         // it is sure now that the pool is an EditEngineItemPool
     606      242384 :         pPool->AddSfxItemPoolUser(*mpFront);
     607             :     }
     608             : 
     609      267425 :     if (bOwnerOfPool && r.pPool)
     610       25041 :         pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) );
     611             : 
     612      267425 :     aContents.reserve(r.aContents.size());
     613      267425 :     ContentInfosType::const_iterator it = r.aContents.begin(), itEnd = r.aContents.end();
     614      556488 :     for (; it != itEnd; ++it)
     615      289063 :         aContents.push_back(new ContentInfo(*it, *pPool));
     616      267425 : }
     617             : 
     618      774308 : EditTextObjectImpl::~EditTextObjectImpl()
     619             : {
     620      387154 :     if(!bOwnerOfPool && pPool)
     621             :     {
     622      352244 :         pPool->RemoveSfxItemPoolUser(*mpFront);
     623             :     }
     624             : 
     625      387154 :     ClearPortionInfo();
     626             : 
     627             :     // Remove contents before deleting the pool instance since each content
     628             :     // has to access the pool instance in its destructor.
     629      387154 :     aContents.clear();
     630      387154 :     if ( bOwnerOfPool )
     631             :     {
     632       34910 :         SfxItemPool::Free(pPool);
     633             :     }
     634      387154 : }
     635             : 
     636             : 
     637      111196 : void EditTextObjectImpl::SetUserType( sal_uInt16 n )
     638             : {
     639      111196 :     nUserType = n;
     640      111196 : }
     641             : 
     642         677 : void EditTextObjectImpl::NormalizeString( svl::SharedStringPool& rPool )
     643             : {
     644         677 :     ContentInfosType::iterator it = aContents.begin(), itEnd = aContents.end();
     645        1454 :     for (; it != itEnd; ++it)
     646             :     {
     647         777 :         ContentInfo& rInfo = *it;
     648         777 :         rInfo.NormalizeString(rPool);
     649             :     }
     650         677 : }
     651             : 
     652           3 : std::vector<svl::SharedString> EditTextObjectImpl::GetSharedStrings() const
     653             : {
     654           3 :     std::vector<svl::SharedString> aSSs;
     655           3 :     aSSs.reserve(aContents.size());
     656           3 :     ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     657           6 :     for (; it != itEnd; ++it)
     658             :     {
     659           3 :         const ContentInfo& rInfo = *it;
     660           3 :         aSSs.push_back(rInfo.GetSharedString());
     661             :     }
     662           3 :     return aSSs;
     663             : }
     664             : 
     665             : 
     666      126501 : void EditTextObjectImpl::SetVertical( bool b )
     667             : {
     668      126501 :     if ( b != bVertical )
     669             :     {
     670          14 :         bVertical = b;
     671          14 :         ClearPortionInfo();
     672             :     }
     673      126501 : }
     674             : 
     675             : 
     676      126335 : void EditTextObjectImpl::SetScriptType( SvtScriptType nType )
     677             : {
     678      126335 :     nScriptType = nType;
     679      126335 : }
     680             : 
     681      131065 : XEditAttribute* EditTextObjectImpl::CreateAttrib( const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
     682             : {
     683      131065 :     return MakeXEditAttribute( *pPool, rItem, nStart, nEnd );
     684             : }
     685             : 
     686           0 : void EditTextObjectImpl::DestroyAttrib( XEditAttribute* pAttr )
     687             : {
     688           0 :     pPool->Remove( *pAttr->GetItem() );
     689           0 :     delete pAttr;
     690           0 : }
     691             : 
     692             : 
     693             : 
     694      138714 : ContentInfo* EditTextObjectImpl::CreateAndInsertContent()
     695             : {
     696      138714 :     aContents.push_back(new ContentInfo(*pPool));
     697      138714 :     return &aContents.back();
     698             : }
     699             : 
     700      156262 : sal_Int32 EditTextObjectImpl::GetParagraphCount() const
     701             : {
     702      156262 :     size_t nSize = aContents.size();
     703      156262 :     if (nSize > EE_PARA_MAX_COUNT)
     704             :     {
     705             :         SAL_WARN( "editeng", "EditTextObjectImpl::GetParagraphCount - overflow " << nSize);
     706           0 :         return EE_PARA_MAX_COUNT;
     707             :     }
     708      156262 :     return static_cast<sal_Int32>(nSize);
     709             : }
     710             : 
     711      118460 : OUString EditTextObjectImpl::GetText(sal_Int32 nPara) const
     712             : {
     713      118460 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     714           0 :         return OUString();
     715             : 
     716      118460 :     return aContents[nPara].GetText();
     717             : }
     718             : 
     719      388271 : void EditTextObjectImpl::ClearPortionInfo()
     720             : {
     721      388271 :     if ( pPortionInfo )
     722             :     {
     723           0 :         delete pPortionInfo;
     724           0 :         pPortionInfo = NULL;
     725             :     }
     726      388271 : }
     727             : 
     728          10 : bool EditTextObjectImpl::HasOnlineSpellErrors() const
     729             : {
     730          10 :     ContentInfosType::const_iterator it = aContents.begin(), itEnd = aContents.end();
     731          30 :     for (; it != itEnd; ++it)
     732             :     {
     733          20 :         if ( it->GetWrongList() && !it->GetWrongList()->empty() )
     734           0 :             return true;
     735             :     }
     736          10 :     return false;
     737             : }
     738             : 
     739         342 : void EditTextObjectImpl::GetCharAttribs( sal_Int32 nPara, std::vector<EECharAttrib>& rLst ) const
     740             : {
     741         342 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     742         342 :         return;
     743             : 
     744         342 :     rLst.clear();
     745         342 :     const ContentInfo& rC = aContents[nPara];
     746        2971 :     for (size_t nAttr = 0; nAttr < rC.aAttribs.size(); ++nAttr)
     747             :     {
     748        2629 :         const XEditAttribute& rAttr = rC.aAttribs[nAttr];
     749             :         EECharAttrib aEEAttr;
     750        2629 :         aEEAttr.pAttr = rAttr.GetItem();
     751        2629 :         aEEAttr.nPara = nPara;
     752        2629 :         aEEAttr.nStart = rAttr.GetStart();
     753        2629 :         aEEAttr.nEnd = rAttr.GetEnd();
     754        2629 :         rLst.push_back(aEEAttr);
     755             :     }
     756             : }
     757             : 
     758           0 : bool EditTextObjectImpl::IsFieldObject() const
     759             : {
     760           0 :     return GetField() != nullptr;
     761             : }
     762             : 
     763           0 : const SvxFieldItem* EditTextObjectImpl::GetField() const
     764             : {
     765           0 :     if (aContents.size() == 1)
     766             :     {
     767           0 :         const ContentInfo& rC = aContents[0];
     768           0 :         if (rC.GetText().getLength() == 1)
     769             :         {
     770           0 :             size_t nAttribs = rC.aAttribs.size();
     771           0 :             for (size_t nAttr = nAttribs; nAttr; )
     772             :             {
     773           0 :                 const XEditAttribute& rX = rC.aAttribs[--nAttr];
     774           0 :                 if (rX.GetItem()->Which() == EE_FEATURE_FIELD)
     775           0 :                     return static_cast<const SvxFieldItem*>(rX.GetItem());
     776             :             }
     777             :         }
     778             :     }
     779           0 :     return 0;
     780             : }
     781             : 
     782           1 : const SvxFieldData* EditTextObjectImpl::GetFieldData(sal_Int32 nPara, size_t nPos, sal_Int32 nType) const
     783             : {
     784           1 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
     785           0 :         return NULL;
     786             : 
     787           1 :     const ContentInfo& rC = aContents[nPara];
     788           1 :     if (nPos >= rC.aAttribs.size())
     789             :         // URL position is out-of-bound.
     790           0 :         return NULL;
     791             : 
     792           1 :     ContentInfo::XEditAttributesType::const_iterator it = rC.aAttribs.begin(), itEnd = rC.aAttribs.end();
     793           1 :     size_t nCurPos = 0;
     794           1 :     for (; it != itEnd; ++it)
     795             :     {
     796           1 :         const XEditAttribute& rAttr = *it;
     797           1 :         if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
     798             :             // Skip attributes that are not fields.
     799           0 :             continue;
     800             : 
     801           1 :         const SvxFieldItem* pField = static_cast<const SvxFieldItem*>(rAttr.GetItem());
     802           1 :         const SvxFieldData* pFldData = pField->GetField();
     803           1 :         if (nType != text::textfield::Type::UNSPECIFIED && nType != pFldData->GetClassId())
     804             :             // Field type doesn't match. Skip it.  UNSPECIFIED matches all field types.
     805           0 :             continue;
     806             : 
     807           1 :         if (nCurPos == nPos)
     808             :             // Found it!
     809           1 :             return pFldData;
     810             : 
     811           0 :         ++nCurPos;
     812             :     }
     813             : 
     814           0 :     return NULL; // field not found.
     815             : }
     816             : 
     817      479135 : bool EditTextObjectImpl::HasField( sal_Int32 nType ) const
     818             : {
     819      479135 :     size_t nParagraphs = aContents.size();
     820      983592 :     for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
     821             :     {
     822      514295 :         const ContentInfo& rC = aContents[nPara];
     823      514295 :         size_t nAttrs = rC.aAttribs.size();
     824      910868 :         for (size_t nAttr = 0; nAttr < nAttrs; ++nAttr)
     825             :         {
     826      406411 :             const XEditAttribute& rAttr = rC.aAttribs[nAttr];
     827      406411 :             if (rAttr.GetItem()->Which() != EE_FEATURE_FIELD)
     828      377277 :                 continue;
     829             : 
     830       29134 :             if (nType == text::textfield::Type::UNSPECIFIED)
     831             :                 // Match any field type.
     832           0 :                 return true;
     833             : 
     834       29134 :             const SvxFieldData* pFldData = static_cast<const SvxFieldItem*>(rAttr.GetItem())->GetField();
     835       29134 :             if (pFldData && pFldData->GetClassId() == nType)
     836        9838 :                 return true;
     837             :         }
     838             :     }
     839      469297 :     return false;
     840             : }
     841             : 
     842        1067 : const SfxItemSet& EditTextObjectImpl::GetParaAttribs(sal_Int32 nPara) const
     843             : {
     844        1067 :     const ContentInfo& rC = aContents[nPara];
     845        1067 :     return rC.GetParaAttribs();
     846             : }
     847             : 
     848           0 : bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 _nWhich )
     849             : {
     850           0 :     bool bChanged = false;
     851             : 
     852           0 :     for ( size_t nPara = aContents.size(); nPara; )
     853             :     {
     854           0 :         ContentInfo& rC = aContents[--nPara];
     855             : 
     856           0 :         for (size_t nAttr = rC.aAttribs.size(); nAttr; )
     857             :         {
     858           0 :             XEditAttribute& rAttr = rC.aAttribs[--nAttr];
     859           0 :             if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) )
     860             :             {
     861           0 :                 pPool->Remove(*rAttr.GetItem());
     862           0 :                 rC.aAttribs.erase(rC.aAttribs.begin()+nAttr);
     863           0 :                 bChanged = true;
     864             :             }
     865             :         }
     866             :     }
     867             : 
     868           0 :     if ( bChanged )
     869           0 :         ClearPortionInfo();
     870             : 
     871           0 :     return bChanged;
     872             : }
     873             : 
     874             : namespace {
     875             : 
     876             : class FindByParagraph : std::unary_function<editeng::Section, bool>
     877             : {
     878             :     sal_Int32 mnPara;
     879             : public:
     880          60 :     FindByParagraph(sal_Int32 nPara) : mnPara(nPara) {}
     881          84 :     bool operator() (const editeng::Section& rAttr) const
     882             :     {
     883          84 :         return rAttr.mnParagraph == mnPara;
     884             :     }
     885             : };
     886             : 
     887             : class FindBySectionStart : std::unary_function<editeng::Section, bool>
     888             : {
     889             :     sal_Int32 mnPara;
     890             :     sal_Int32 mnStart;
     891             : public:
     892          48 :     FindBySectionStart(sal_Int32 nPara, sal_Int32 nStart) : mnPara(nPara), mnStart(nStart) {}
     893          85 :     bool operator() (const editeng::Section& rAttr) const
     894             :     {
     895          85 :         return rAttr.mnParagraph == mnPara && rAttr.mnStart == mnStart;
     896             :     }
     897             : };
     898             : 
     899             : }
     900             : 
     901          36 : void EditTextObjectImpl::GetAllSections( std::vector<editeng::Section>& rAttrs ) const
     902             : {
     903             :     typedef std::vector<size_t> SectionBordersType;
     904             :     typedef std::vector<SectionBordersType> ParagraphsType;
     905          36 :     ParagraphsType aParaBorders(aContents.size());
     906             : 
     907             :     // First pass: determine section borders for each paragraph.
     908          96 :     for (size_t nPara = 0; nPara < aContents.size(); ++nPara)
     909             :     {
     910          60 :         const ContentInfo& rC = aContents[nPara];
     911          60 :         SectionBordersType& rBorders = aParaBorders[nPara];
     912          60 :         rBorders.push_back(0);
     913          60 :         rBorders.push_back(rC.GetText().getLength());
     914         108 :         for (size_t nAttr = 0; nAttr < rC.aAttribs.size(); ++nAttr)
     915             :         {
     916          48 :             const XEditAttribute& rAttr = rC.aAttribs[nAttr];
     917          48 :             const SfxPoolItem* pItem = rAttr.GetItem();
     918          48 :             if (!pItem)
     919           0 :                 continue;
     920             : 
     921          48 :             rBorders.push_back(rAttr.GetStart());
     922          48 :             rBorders.push_back(rAttr.GetEnd());
     923             :         }
     924             :     }
     925             : 
     926             :     // Sort and remove duplicates for each paragraph.
     927          36 :     ParagraphsType::iterator it = aParaBorders.begin(), itEnd = aParaBorders.end();
     928          96 :     for (; it != itEnd; ++it)
     929             :     {
     930          60 :         SectionBordersType& rBorders = *it;
     931          60 :         std::sort(rBorders.begin(), rBorders.end());
     932          60 :         SectionBordersType::iterator itUniqueEnd = std::unique(rBorders.begin(), rBorders.end());
     933          60 :         rBorders.erase(itUniqueEnd, rBorders.end());
     934             :     }
     935             : 
     936          72 :     std::vector<editeng::Section> aAttrs;
     937             : 
     938             :     // Create storage for each section.  Note that this creates storage even
     939             :     // for unformatted sections.  The entries are sorted first by paragraph,
     940             :     // then by section positions.  They don't overlap with each other.
     941          36 :     it = aParaBorders.begin();
     942          96 :     for (; it != itEnd; ++it)
     943             :     {
     944          60 :         size_t nPara = distance(aParaBorders.begin(), it);
     945          60 :         const SectionBordersType& rBorders = *it;
     946          60 :         if (rBorders.size() == 1 && rBorders[0] == 0)
     947             :         {
     948             :             // Empty paragraph. Push an empty section.
     949           9 :             aAttrs.push_back(editeng::Section(nPara, 0, 0));
     950           9 :             continue;
     951             :         }
     952             : 
     953          51 :         SectionBordersType::const_iterator itBorder = rBorders.begin(), itBorderEnd = rBorders.end();
     954          51 :         size_t nPrev = *itBorder;
     955             :         size_t nCur;
     956         144 :         for (++itBorder; itBorder != itBorderEnd; ++itBorder, nPrev = nCur)
     957             :         {
     958          93 :             nCur = *itBorder;
     959          93 :             aAttrs.push_back(editeng::Section(nPara, nPrev, nCur));
     960             :         }
     961             :     }
     962             : 
     963          36 :     if (aAttrs.empty())
     964           0 :         return;
     965             : 
     966             :     // Go through all formatted paragraphs, and store format items.
     967          36 :     std::vector<editeng::Section>::iterator itAttr = aAttrs.begin();
     968          96 :     for (sal_Int32 nPara = 0; nPara < (sal_Int32)aContents.size(); ++nPara)
     969             :     {
     970          60 :         const ContentInfo& rC = aContents[nPara];
     971             : 
     972          60 :         itAttr = std::find_if(itAttr, aAttrs.end(), FindByParagraph(nPara));
     973          60 :         if (itAttr == aAttrs.end())
     974             :         {
     975             :             // This should never happen. There is a logic error somewhere...
     976             :             assert(false);
     977           0 :             return;
     978             :         }
     979             : 
     980         108 :         for (size_t i = 0; i < rC.aAttribs.size(); ++i)
     981             :         {
     982          48 :             const XEditAttribute& rXAttr = rC.aAttribs[i];
     983          48 :             const SfxPoolItem* pItem = rXAttr.GetItem();
     984          48 :             if (!pItem)
     985           0 :                 continue;
     986             : 
     987          48 :             sal_Int32 nStart = rXAttr.GetStart(), nEnd = rXAttr.GetEnd();
     988          48 :             std::vector<editeng::Section>::iterator itCurAttr = itAttr;
     989             : 
     990             :             // Find the container whose start position matches.
     991          48 :             itCurAttr = std::find_if(itCurAttr, aAttrs.end(), FindBySectionStart(nPara, nStart));
     992          48 :             if (itCurAttr == aAttrs.end())
     993             :             {
     994             :                 // This should never happen. There is a logic error somewhere...
     995             :                 assert(false);
     996           0 :                 return;
     997             :             }
     998             : 
     999          98 :             for (; itCurAttr != aAttrs.end() && itCurAttr->mnParagraph == nPara && itCurAttr->mnEnd <= nEnd; ++itCurAttr)
    1000             :             {
    1001          50 :                 editeng::Section& rSecAttr = *itCurAttr;
    1002             :                 // serious bug: will cause duplicate attributes to be exported
    1003             :                 auto iter(std::find_if(
    1004             :                     rSecAttr.maAttributes.begin(), rSecAttr.maAttributes.end(),
    1005           1 :                     [&pItem](SfxPoolItem const*const pIt)
    1006          51 :                         { return pIt->Which() == pItem->Which(); }));
    1007          50 :                 if (rSecAttr.maAttributes.end() == iter)
    1008             :                 {
    1009          50 :                     rSecAttr.maAttributes.push_back(pItem);
    1010             :                 }
    1011             :                 else
    1012             :                 {
    1013             :                     SAL_WARN("editeng", "GetAllSections(): duplicate attribute suppressed");
    1014             :                 }
    1015             :             }
    1016             :         }
    1017             :     }
    1018             : 
    1019          72 :     rAttrs.swap(aAttrs);
    1020             : }
    1021             : 
    1022       27522 : void EditTextObjectImpl::GetStyleSheet(sal_Int32 nPara, OUString& rName, SfxStyleFamily& rFamily) const
    1023             : {
    1024       27522 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
    1025       27522 :         return;
    1026             : 
    1027       27522 :     const ContentInfo& rC = aContents[nPara];
    1028       27522 :     rName = rC.GetStyle();
    1029       27522 :     rFamily = rC.GetFamily();
    1030             : }
    1031             : 
    1032           0 : void EditTextObjectImpl::SetStyleSheet(sal_Int32 nPara, const OUString& rName, const SfxStyleFamily& rFamily)
    1033             : {
    1034           0 :     if (nPara < 0 || static_cast<size_t>(nPara) >= aContents.size())
    1035           0 :         return;
    1036             : 
    1037           0 :     ContentInfo& rC = aContents[nPara];
    1038           0 :     rC.GetStyle() = rName;
    1039           0 :     rC.GetFamily() = rFamily;
    1040             : }
    1041             : 
    1042       19432 : bool EditTextObjectImpl::ImpChangeStyleSheets(
    1043             :                     const OUString& rOldName, SfxStyleFamily eOldFamily,
    1044             :                     const OUString& rNewName, SfxStyleFamily eNewFamily )
    1045             : {
    1046       19432 :     const size_t nParagraphs = aContents.size();
    1047       19432 :     bool bChanges = false;
    1048             : 
    1049       39956 :     for (size_t nPara = 0; nPara < nParagraphs; ++nPara)
    1050             :     {
    1051       20524 :         ContentInfo& rC = aContents[nPara];
    1052       20524 :         if ( rC.GetFamily() == eOldFamily )
    1053             :         {
    1054       15148 :             if ( rC.GetStyle() == rOldName )
    1055             :             {
    1056        1082 :                 rC.GetStyle() = rNewName;
    1057        1082 :                 rC.GetFamily() = eNewFamily;
    1058        1082 :                 bChanges = true;
    1059             :             }
    1060             :         }
    1061             :     }
    1062       19432 :     return bChanges;
    1063             : }
    1064             : 
    1065       19432 : bool EditTextObjectImpl::ChangeStyleSheets(
    1066             :                     const OUString& rOldName, SfxStyleFamily eOldFamily,
    1067             :                     const OUString& rNewName, SfxStyleFamily eNewFamily)
    1068             : {
    1069       19432 :     bool bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
    1070       19432 :     if ( bChanges )
    1071        1082 :         ClearPortionInfo();
    1072             : 
    1073       19432 :     return bChanges;
    1074             : }
    1075             : 
    1076           0 : void EditTextObjectImpl::ChangeStyleSheetName( SfxStyleFamily eFamily,
    1077             :                 const OUString& rOldName, const OUString& rNewName )
    1078             : {
    1079           0 :     ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
    1080           0 : }
    1081             : 
    1082             : 
    1083             : namespace {
    1084             : 
    1085             : class FindAttribByChar : public std::unary_function<XEditAttribute, bool>
    1086             : {
    1087             :     sal_uInt16 mnWhich;
    1088             :     sal_uInt16 mnChar;
    1089             : public:
    1090           0 :     FindAttribByChar(sal_uInt16 nWhich, sal_uInt16 nChar) : mnWhich(nWhich), mnChar(nChar) {}
    1091           0 :     bool operator() (const XEditAttribute& rAttr) const
    1092             :     {
    1093           0 :         return (rAttr.GetItem()->Which() == mnWhich) && (rAttr.GetStart() <= mnChar) && (rAttr.GetEnd() > mnChar);
    1094             :     }
    1095             : };
    1096             : 
    1097             : }
    1098             : 
    1099        6390 : void EditTextObjectImpl::StoreData( SvStream& rOStream ) const
    1100             : {
    1101        6390 :     sal_uInt16 nVer = 602;
    1102        6390 :     rOStream.WriteUInt16( nVer );
    1103             : 
    1104        6390 :     rOStream.WriteBool( bOwnerOfPool );
    1105             : 
    1106             :     // First store the pool, later only the Surregate
    1107        6390 :     if ( bOwnerOfPool )
    1108             :     {
    1109        6366 :         GetPool()->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 );
    1110        6366 :         GetPool()->Store( rOStream );
    1111             :     }
    1112             : 
    1113             :     // Store Current text encoding ...
    1114        6390 :     rtl_TextEncoding eEncoding = GetSOStoreTextEncoding( osl_getThreadTextEncoding() );
    1115        6390 :     rOStream.WriteUInt16( eEncoding );
    1116             : 
    1117             :     // The number of paragraphs ...
    1118        6390 :     size_t nParagraphs = aContents.size();
    1119             :     // FIXME: this truncates, check usage of stream and if it can be changed,
    1120             :     // i.e. is not persistent, adapt this and reader.
    1121        6390 :     sal_uInt16 nParagraphs_Stream = static_cast<sal_uInt16>(nParagraphs);
    1122        6390 :     rOStream.WriteUInt16( nParagraphs_Stream );
    1123             : 
    1124        6390 :     sal_Unicode nUniChar = CH_FEATURE;
    1125        6390 :     char cFeatureConverted = OString(&nUniChar, 1, eEncoding).toChar();
    1126             : 
    1127             :     // The individual paragraphs ...
    1128       12792 :     for (size_t nPara = 0; nPara < nParagraphs_Stream; ++nPara)
    1129             :     {
    1130        6402 :         const ContentInfo& rC = aContents[nPara];
    1131             : 
    1132             :         // Text...
    1133        6402 :         OStringBuffer aBuffer(OUStringToOString(rC.GetText(), eEncoding));
    1134             : 
    1135             :         // Symbols?
    1136        6402 :         bool bSymbolPara = false;
    1137        6402 :         if (rC.GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SfxItemState::SET)
    1138             :         {
    1139         368 :             const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(rC.GetParaAttribs().Get(EE_CHAR_FONTINFO));
    1140         368 :             if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
    1141             :             {
    1142           0 :                 aBuffer = OStringBuffer(OUStringToOString(rC.GetText(), RTL_TEXTENCODING_SYMBOL));
    1143           0 :                 bSymbolPara = true;
    1144             :             }
    1145             :         }
    1146       12587 :         for (size_t nA = 0; nA < rC.aAttribs.size(); ++nA)
    1147             :         {
    1148        6185 :             const XEditAttribute& rAttr = rC.aAttribs[nA];
    1149             : 
    1150        6185 :             if (rAttr.GetItem()->Which() == EE_CHAR_FONTINFO)
    1151             :             {
    1152         341 :                 const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(*rAttr.GetItem());
    1153        1023 :                 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
    1154         682 :                       || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
    1155             :                 {
    1156             :                     // Not correctly converted
    1157           0 :                     OUString aPart = rC.GetText().copy( rAttr.GetStart(), rAttr.GetEnd() - rAttr.GetStart() );
    1158           0 :                     OString aNew(OUStringToOString(aPart, rFontItem.GetCharSet()));
    1159           0 :                     aBuffer.remove(rAttr.GetStart(), rAttr.GetEnd() - rAttr.GetStart());
    1160           0 :                     aBuffer.insert(rAttr.GetStart(), aNew);
    1161             :                 }
    1162             : 
    1163             :                 // Convert StarSymbol back to StarBats
    1164         341 :                 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FontToSubsFontFlags::EXPORT | FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS );
    1165         341 :                 if ( hConv )
    1166             :                 {
    1167             :                     // Don't create a new Attrib with StarBats font, MBR changed the
    1168             :                     // SvxFontItem::Store() to store StarBats instead of StarSymbol!
    1169           0 :                     for (sal_uInt16 nChar = rAttr.GetStart(); nChar < rAttr.GetEnd(); ++nChar)
    1170             :                     {
    1171           0 :                         sal_Unicode cOld = rC.GetText()[ nChar ];
    1172           0 :                         char cConv = OUStringToOString(OUString(ConvertFontToSubsFontChar(hConv, cOld)), RTL_TEXTENCODING_SYMBOL).toChar();
    1173           0 :                         if ( cConv )
    1174           0 :                             aBuffer[nChar] = cConv;
    1175             :                     }
    1176             : 
    1177           0 :                     DestroyFontToSubsFontConverter( hConv );
    1178             :                 }
    1179             :             }
    1180             :         }
    1181             : 
    1182             :         // Convert StarSymbol back to StarBats
    1183             :         // StarSymbol as paragraph attribute or in StyleSheet?
    1184             : 
    1185        6402 :         FontToSubsFontConverter hConv = NULL;
    1186        6402 :         if (rC.GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SfxItemState::SET)
    1187             :         {
    1188         368 :             hConv = CreateFontToSubsFontConverter( static_cast<const SvxFontItem&>(rC.GetParaAttribs().Get( EE_CHAR_FONTINFO )).GetFamilyName(), FontToSubsFontFlags::EXPORT | FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS );
    1189             :         }
    1190        6402 :         if ( hConv )
    1191             :         {
    1192           0 :             for ( sal_uInt16 nChar = 0; nChar < rC.GetText().getLength(); nChar++ )
    1193             :             {
    1194           0 :                 const ContentInfo::XEditAttributesType& rAttribs = rC.aAttribs;
    1195           0 :                 if ( std::none_of(rAttribs.begin(), rAttribs.end(),
    1196           0 :                                   FindAttribByChar(EE_CHAR_FONTINFO, nChar)) )
    1197             :                 {
    1198           0 :                     sal_Unicode cOld = rC.GetText()[ nChar ];
    1199           0 :                     char cConv = OUStringToOString(OUString(ConvertFontToSubsFontChar(hConv, cOld)), RTL_TEXTENCODING_SYMBOL).toChar();
    1200           0 :                     if ( cConv )
    1201           0 :                         aBuffer[nChar] = cConv;
    1202             :                 }
    1203             :             }
    1204             : 
    1205           0 :             DestroyFontToSubsFontConverter( hConv );
    1206             : 
    1207             :         }
    1208             : 
    1209             : 
    1210             :         // Convert CH_FEATURE to CH_FEATURE_OLD
    1211       12804 :         OString aText = aBuffer.makeStringAndClear().replace(cFeatureConverted, CH_FEATURE_OLD);
    1212        6402 :         write_uInt16_lenPrefixed_uInt8s_FromOString(rOStream, aText);
    1213             : 
    1214             :         // StyleName and Family...
    1215        6402 :         write_uInt16_lenPrefixed_uInt8s_FromOUString(rOStream, rC.GetStyle(), eEncoding);
    1216        6402 :         rOStream.WriteUInt16( rC.GetFamily() );
    1217             : 
    1218             :         // Paragraph attributes ...
    1219        6402 :         rC.GetParaAttribs().Store( rOStream );
    1220             : 
    1221             :         // The number of attributes ...
    1222        6402 :         size_t nAttribs = rC.aAttribs.size();
    1223        6402 :         rOStream.WriteUInt16( nAttribs );
    1224             : 
    1225             :         // And the individual attributes
    1226             :         // Items as Surregate => always 8 bytes per Attribute
    1227             :         // Which = 2; Surregat = 2; Start = 2; End = 2;
    1228       12587 :         for (size_t nAttr = 0; nAttr < nAttribs; ++nAttr)
    1229             :         {
    1230        6185 :             const XEditAttribute& rX = rC.aAttribs[nAttr];
    1231             : 
    1232        6185 :             rOStream.WriteUInt16( rX.GetItem()->Which() );
    1233        6185 :             GetPool()->StoreSurrogate(rOStream, rX.GetItem());
    1234        6185 :             rOStream.WriteUInt16( rX.GetStart() );
    1235        6185 :             rOStream.WriteUInt16( rX.GetEnd() );
    1236             :         }
    1237        6402 :     }
    1238             : 
    1239        6390 :     rOStream.WriteUInt16( nMetric );
    1240             : 
    1241        6390 :     rOStream.WriteUInt16( nUserType );
    1242        6390 :     rOStream.WriteUInt32( nObjSettings );
    1243             : 
    1244        6390 :     rOStream.WriteBool( bVertical );
    1245        6390 :     rOStream.WriteUInt16( static_cast<sal_uInt16>(nScriptType) );
    1246             : 
    1247        6390 :     rOStream.WriteBool( bStoreUnicodeStrings );
    1248        6390 :     if ( bStoreUnicodeStrings )
    1249             :     {
    1250           0 :         for ( size_t nPara = 0; nPara < nParagraphs_Stream; nPara++ )
    1251             :         {
    1252           0 :             const ContentInfo& rC = aContents[nPara];
    1253           0 :             sal_uInt16 nL = rC.GetText().getLength();
    1254           0 :             rOStream.WriteUInt16( nL );
    1255           0 :             rOStream.Write(rC.GetText().getStr(), nL*sizeof(sal_Unicode));
    1256             : 
    1257             :             // StyleSheetName must be Unicode too!
    1258             :             // Copy/Paste from EA3 to BETA or from BETA to EA3 not possible, not needed...
    1259             :             // If needed, change nL back to sal_uLong and increase version...
    1260           0 :             nL = rC.GetStyle().getLength();
    1261           0 :             rOStream.WriteUInt16( nL );
    1262           0 :             rOStream.Write(rC.GetStyle().getStr(), nL*sizeof(sal_Unicode));
    1263             :         }
    1264             :     }
    1265        6390 : }
    1266             : 
    1267           0 : void EditTextObjectImpl::CreateData( SvStream& rIStream )
    1268             : {
    1269           0 :     rIStream.ReadUInt16( nVersion );
    1270             : 
    1271             :     // The text object was first created with the current setting of
    1272             :     // pTextObjectPool.
    1273           0 :     bool bOwnerOfCurrent = bOwnerOfPool;
    1274             :     bool b;
    1275           0 :     rIStream.ReadCharAsBool( b );
    1276           0 :     bOwnerOfPool = b;
    1277             : 
    1278           0 :     if ( bOwnerOfCurrent && !bOwnerOfPool )
    1279             :     {
    1280             :         // A global Pool was used, but not handed over to me, but I need it!
    1281             :         OSL_FAIL( "Give me the global TextObjectPool!" );
    1282           0 :         return;
    1283             :     }
    1284           0 :     else if ( !bOwnerOfCurrent && bOwnerOfPool )
    1285             :     {
    1286             :         // A global Pool should be used, but this Textobject has its own.
    1287           0 :         pPool = EditEngine::CreatePool();
    1288             :     }
    1289             : 
    1290           0 :     if ( bOwnerOfPool )
    1291           0 :         GetPool()->Load( rIStream );
    1292             : 
    1293             :     // CharSet, in which it was saved:
    1294             :     sal_uInt16 nCharSet;
    1295           0 :     rIStream.ReadUInt16( nCharSet );
    1296             : 
    1297           0 :     rtl_TextEncoding eSrcEncoding = GetSOLoadTextEncoding( (rtl_TextEncoding)nCharSet );
    1298             : 
    1299             :     // The number of paragraphs ...
    1300           0 :     sal_uInt16 nParagraphs(0);
    1301           0 :     rIStream.ReadUInt16( nParagraphs );
    1302             : 
    1303           0 :     const size_t nMinParaRecordSize = 6 + eSrcEncoding == RTL_TEXTENCODING_UNICODE ? 4 : 2;
    1304           0 :     const size_t nMaxParaRecords = rIStream.remainingSize() / nMinParaRecordSize;
    1305           0 :     if (nParagraphs > nMaxParaRecords)
    1306             :     {
    1307             :         SAL_WARN("editeng", "Parsing error: " << nMaxParaRecords <<
    1308             :                  " max possible entries, but " << nParagraphs<< " claimed, truncating");
    1309           0 :         nParagraphs = nMaxParaRecords;
    1310             :     }
    1311             : 
    1312             :     // The individual paragraphs ...
    1313           0 :     for ( sal_uLong nPara = 0; nPara < nParagraphs; nPara++ )
    1314             :     {
    1315           0 :         ContentInfo* pC = CreateAndInsertContent();
    1316             : 
    1317             :         // The Text...
    1318           0 :         OString aByteString = read_uInt16_lenPrefixed_uInt8s_ToOString(rIStream);
    1319           0 :         pC->SetText(OStringToOUString(aByteString, eSrcEncoding));
    1320             : 
    1321             :         // StyleName and Family...
    1322           0 :         pC->GetStyle() = rIStream.ReadUniOrByteString(eSrcEncoding);
    1323           0 :         sal_uInt16 nStyleFamily(0);
    1324           0 :         rIStream.ReadUInt16( nStyleFamily );
    1325           0 :         pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
    1326             : 
    1327             :         // Paragraph attributes ...
    1328           0 :         pC->GetParaAttribs().Load( rIStream );
    1329             : 
    1330             :         // The number of attributes ...
    1331           0 :         sal_uInt16 nTmp16(0);
    1332           0 :         rIStream.ReadUInt16( nTmp16 );
    1333           0 :         size_t nAttribs = nTmp16;
    1334             : 
    1335           0 :         const size_t nMinRecordSize(10);
    1336           0 :         const size_t nMaxRecords = rIStream.remainingSize() / nMinRecordSize;
    1337           0 :         if (nAttribs > nMaxRecords)
    1338             :         {
    1339             :             SAL_WARN("editeng", "Parsing error: " << nMaxRecords <<
    1340             :                      " max possible entries, but " << nAttribs << " claimed, truncating");
    1341           0 :             nAttribs = nMaxRecords;
    1342             :         }
    1343             : 
    1344             :         // And the individual attributes
    1345             :         // Items as Surregate => always 8 bytes per Attributes
    1346             :         // Which = 2; Surregat = 2; Start = 2; End = 2;
    1347           0 :         for (size_t nAttr = 0; nAttr < nAttribs; ++nAttr)
    1348             :         {
    1349           0 :             sal_uInt16 _nWhich(0), nStart(0), nEnd(0);
    1350             :             const SfxPoolItem* pItem;
    1351             : 
    1352           0 :             rIStream.ReadUInt16( _nWhich );
    1353           0 :             _nWhich = pPool->GetNewWhich( _nWhich );
    1354           0 :             pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
    1355           0 :             rIStream.ReadUInt16( nStart );
    1356           0 :             rIStream.ReadUInt16( nEnd );
    1357           0 :             if ( pItem )
    1358             :             {
    1359           0 :                 if ( pItem->Which() == EE_FEATURE_NOTCONV )
    1360             :                 {
    1361           0 :                     sal_Char cEncodedChar = aByteString[nStart];
    1362             :                     sal_Unicode cChar = OUString(&cEncodedChar, 1,
    1363           0 :                         static_cast<const SvxCharSetColorItem*>(pItem)->GetCharSet()).toChar();
    1364           0 :                     pC->SetText(pC->GetText().replaceAt(nStart, 1, OUString(cChar)));
    1365             :                 }
    1366             :                 else
    1367             :                 {
    1368           0 :                     XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
    1369           0 :                     pC->aAttribs.push_back(pAttr);
    1370             : 
    1371           0 :                     if ( ( _nWhich >= EE_FEATURE_START ) && ( _nWhich <= EE_FEATURE_END ) )
    1372             :                     {
    1373             :                         // Convert CH_FEATURE to CH_FEATURE_OLD
    1374             :                         DBG_ASSERT( (sal_uInt8) aByteString[nStart] == CH_FEATURE_OLD, "CreateData: CH_FEATURE expected!" );
    1375           0 :                         if ( (sal_uInt8) aByteString[nStart] == CH_FEATURE_OLD )
    1376           0 :                             pC->SetText(pC->GetText().replaceAt(nStart, 1, OUString(CH_FEATURE)));
    1377             :                     }
    1378             :                 }
    1379             :             }
    1380             :         }
    1381             : 
    1382             :         // But check for paragraph and character symbol attribs here,
    1383             :         // FinishLoad will not be called in OpenOffice Calc, no StyleSheets...
    1384             : 
    1385           0 :         bool bSymbolPara = false;
    1386           0 :         if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SfxItemState::SET )
    1387             :         {
    1388           0 :             const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(pC->GetParaAttribs().Get( EE_CHAR_FONTINFO ));
    1389           0 :             if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
    1390             :             {
    1391           0 :                 pC->SetText(OStringToOUString(aByteString, RTL_TEXTENCODING_SYMBOL));
    1392           0 :                 bSymbolPara = true;
    1393             :             }
    1394             :         }
    1395             : 
    1396           0 :         for (size_t nAttr = pC->aAttribs.size(); nAttr; )
    1397             :         {
    1398           0 :             const XEditAttribute& rAttr = pC->aAttribs[--nAttr];
    1399           0 :             if ( rAttr.GetItem()->Which() == EE_CHAR_FONTINFO )
    1400             :             {
    1401           0 :                 const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(*rAttr.GetItem());
    1402           0 :                 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
    1403           0 :                       || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
    1404             :                 {
    1405             :                     // Not correctly converted
    1406           0 :                     OString aPart(aByteString.copy(rAttr.GetStart(), rAttr.GetEnd()-rAttr.GetStart()));
    1407           0 :                     OUString aNew(OStringToOUString(aPart, rFontItem.GetCharSet()));
    1408           0 :                     pC->SetText(pC->GetText().replaceAt(rAttr.GetStart(), rAttr.GetEnd()-rAttr.GetStart(), aNew));
    1409             :                 }
    1410             : 
    1411             :                 // Convert StarMath and StarBats to StarSymbol
    1412           0 :                 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FontToSubsFontFlags::IMPORT | FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS );
    1413           0 :                 if ( hConv )
    1414             :                 {
    1415           0 :                     SvxFontItem aNewFontItem( rFontItem );
    1416           0 :                     aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
    1417             : 
    1418             :                     // Replace the existing attribute with a new one.
    1419           0 :                     XEditAttribute* pNewAttr = CreateAttrib(aNewFontItem, rAttr.GetStart(), rAttr.GetEnd());
    1420             : 
    1421           0 :                     pPool->Remove(*rAttr.GetItem());
    1422           0 :                     pC->aAttribs.erase(pC->aAttribs.begin()+nAttr);
    1423           0 :                     pC->aAttribs.insert(pC->aAttribs.begin()+nAttr, pNewAttr);
    1424             : 
    1425           0 :                     for ( sal_uInt16 nChar = pNewAttr->GetStart(); nChar < pNewAttr->GetEnd(); nChar++ )
    1426             :                     {
    1427           0 :                         sal_Unicode cOld = pC->GetText()[ nChar ];
    1428             :                         DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
    1429           0 :                         sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
    1430           0 :                         if ( cConv )
    1431           0 :                             pC->SetText(pC->GetText().replaceAt(nChar, 1, OUString(cConv)));
    1432             :                     }
    1433             : 
    1434           0 :                     DestroyFontToSubsFontConverter( hConv );
    1435             :                 }
    1436             :             }
    1437             :         }
    1438             : 
    1439             : 
    1440             :         // Convert StarMath and StarBats to StarSymbol
    1441             :         // Maybe old symbol font as paragraph attribute?
    1442           0 :         if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SfxItemState::SET )
    1443             :         {
    1444           0 :             const SvxFontItem& rFontItem = static_cast<const SvxFontItem&>(pC->GetParaAttribs().Get( EE_CHAR_FONTINFO ));
    1445           0 :             FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FontToSubsFontFlags::IMPORT | FontToSubsFontFlags::ONLYOLDSOSYMBOLFONTS );
    1446           0 :             if ( hConv )
    1447             :             {
    1448           0 :                 SvxFontItem aNewFontItem( rFontItem );
    1449           0 :                 aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
    1450           0 :                 pC->GetParaAttribs().Put( aNewFontItem );
    1451             : 
    1452           0 :                 for ( sal_uInt16 nChar = 0; nChar < pC->GetText().getLength(); nChar++ )
    1453             :                 {
    1454           0 :                     const ContentInfo::XEditAttributesType& rAttribs = pC->aAttribs;
    1455           0 :                     if ( std::none_of(rAttribs.begin(), rAttribs.end(),
    1456           0 :                                       FindAttribByChar(EE_CHAR_FONTINFO, nChar)) )
    1457             :                     {
    1458           0 :                         sal_Unicode cOld = pC->GetText()[ nChar ];
    1459             :                         DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
    1460           0 :                         sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
    1461           0 :                         if ( cConv )
    1462           0 :                             pC->SetText(pC->GetText().replaceAt(nChar, 1, OUString(cConv)));
    1463             :                     }
    1464             :                 }
    1465             : 
    1466           0 :                 DestroyFontToSubsFontConverter( hConv );
    1467             :             }
    1468             :         }
    1469           0 :     }
    1470             : 
    1471             :     // From 400 also the DefMetric:
    1472           0 :     if ( nVersion >= 400 )
    1473             :     {
    1474             :         sal_uInt16 nTmpMetric;
    1475           0 :         rIStream.ReadUInt16( nTmpMetric );
    1476           0 :         if ( nVersion >= 401 )
    1477             :         {
    1478             :             // In the 400 there was a bug in text objects with the own Pool,
    1479             :             // therefore evaluate only from 401
    1480           0 :             nMetric = nTmpMetric;
    1481           0 :             if ( bOwnerOfPool && pPool && ( nMetric != 0xFFFF ) )
    1482           0 :                 pPool->SetDefaultMetric( (SfxMapUnit)nMetric );
    1483             :         }
    1484             :     }
    1485             : 
    1486           0 :     if ( nVersion >= 600 )
    1487             :     {
    1488           0 :         rIStream.ReadUInt16( nUserType );
    1489           0 :         rIStream.ReadUInt32( nObjSettings );
    1490             :     }
    1491             : 
    1492           0 :     if ( nVersion >= 601 )
    1493             :     {
    1494           0 :         bool bTmp(false);
    1495           0 :         rIStream.ReadCharAsBool( bTmp );
    1496           0 :         bVertical = bTmp;
    1497             :     }
    1498             : 
    1499           0 :     if ( nVersion >= 602 )
    1500             :     {
    1501             :         sal_uInt16 aTmp16;
    1502           0 :         rIStream.ReadUInt16( aTmp16 );
    1503           0 :         nScriptType = static_cast<SvtScriptType>(aTmp16);
    1504             : 
    1505           0 :         bool bUnicodeStrings(false);
    1506           0 :         rIStream.ReadCharAsBool( bUnicodeStrings );
    1507           0 :         if ( bUnicodeStrings )
    1508             :         {
    1509           0 :             for (sal_uInt16 nPara = 0; nPara < nParagraphs; ++nPara)
    1510             :             {
    1511           0 :                 ContentInfo& rC = aContents[nPara];
    1512           0 :                 sal_uInt16 nL(0);
    1513             : 
    1514             :                 // Text
    1515           0 :                 rIStream.ReadUInt16(nL);
    1516           0 :                 if (nL)
    1517             :                 {
    1518           0 :                     size_t nMaxElementsPossible = rIStream.remainingSize() / sizeof(sal_Unicode);
    1519           0 :                     if (nL > nMaxElementsPossible)
    1520             :                     {
    1521             :                         SAL_WARN("editeng", "Parsing error: " << nMaxElementsPossible <<
    1522             :                                  " max possible entries, but " << nL << " claimed, truncating");
    1523           0 :                         nL = nMaxElementsPossible;
    1524             :                     }
    1525             : 
    1526           0 :                     rtl_uString *pStr = rtl_uString_alloc(nL);
    1527           0 :                     rIStream.Read(pStr->buffer, nL*sizeof(sal_Unicode));
    1528           0 :                     rC.SetText((OUString(pStr, SAL_NO_ACQUIRE)));
    1529             : 
    1530           0 :                     nL = 0;
    1531             :                 }
    1532             : 
    1533             :                 // StyleSheetName
    1534           0 :                 rIStream.ReadUInt16( nL );
    1535           0 :                 if ( nL )
    1536             :                 {
    1537           0 :                     size_t nMaxElementsPossible = rIStream.remainingSize() / sizeof(sal_Unicode);
    1538           0 :                     if (nL > nMaxElementsPossible)
    1539             :                     {
    1540             :                         SAL_WARN("editeng", "Parsing error: " << nMaxElementsPossible <<
    1541             :                                  " max possible entries, but " << nL << " claimed, truncating");
    1542           0 :                         nL = nMaxElementsPossible;
    1543             :                     }
    1544             : 
    1545           0 :                     rtl_uString *pStr = rtl_uString_alloc(nL);
    1546           0 :                     rIStream.Read(pStr->buffer, nL*sizeof(sal_Unicode) );
    1547           0 :                     rC.GetStyle() = OUString(pStr, SAL_NO_ACQUIRE);
    1548             :                 }
    1549             :             }
    1550             :         }
    1551             :     }
    1552             : 
    1553             : 
    1554             :     // from 500 the tabs are interpreted differently: TabPos + LI, previously only TabPos.
    1555             :     // Works only if tab positions are set, not when DefTab.
    1556           0 :     if ( nVersion < 500 )
    1557             :     {
    1558           0 :         for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1559             :         {
    1560           0 :             ContentInfo& rC = aContents[i];
    1561           0 :             const SvxLRSpaceItem& rLRSpace = static_cast<const SvxLRSpaceItem&>(rC.GetParaAttribs().Get(EE_PARA_LRSPACE));
    1562           0 :             if ( rLRSpace.GetTextLeft() && ( rC.GetParaAttribs().GetItemState( EE_PARA_TABS ) == SfxItemState::SET ) )
    1563             :             {
    1564           0 :                 const SvxTabStopItem& rTabs = static_cast<const SvxTabStopItem&>(rC.GetParaAttribs().Get(EE_PARA_TABS));
    1565           0 :                 SvxTabStopItem aNewTabs( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
    1566           0 :                 for ( sal_uInt16 t = 0; t < rTabs.Count(); t++ )
    1567             :                 {
    1568           0 :                     const SvxTabStop& rT = rTabs[ t ];
    1569           0 :                     aNewTabs.Insert( SvxTabStop( rT.GetTabPos() - rLRSpace.GetTextLeft(),
    1570           0 :                                 rT.GetAdjustment(), rT.GetDecimal(), rT.GetFill() ) );
    1571             :                 }
    1572           0 :                 rC.GetParaAttribs().Put( aNewTabs );
    1573             :             }
    1574             :         }
    1575             :     }
    1576             : }
    1577             : 
    1578        3121 : bool EditTextObjectImpl::operator==( const EditTextObjectImpl& rCompare ) const
    1579             : {
    1580        3121 :     if( this == &rCompare )
    1581           0 :         return true;
    1582             : 
    1583        9284 :     if( ( aContents.size() != rCompare.aContents.size() ) ||
    1584        6084 :             ( pPool != rCompare.pPool ) ||
    1585        6084 :             ( nMetric != rCompare.nMetric ) ||
    1586        6081 :             ( nUserType!= rCompare.nUserType ) ||
    1587        9199 :             ( nScriptType != rCompare.nScriptType ) ||
    1588        3039 :             ( bVertical != rCompare.bVertical ) )
    1589          82 :         return false;
    1590             : 
    1591        5230 :     for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1592             :     {
    1593        3874 :         if (aContents[i] != rCompare.aContents[i])
    1594        1683 :             return false;
    1595             :     }
    1596             : 
    1597        1356 :     return true;
    1598             : }
    1599             : 
    1600             : // #i102062#
    1601        1352 : bool EditTextObjectImpl::isWrongListEqual(const EditTextObjectImpl& rCompare) const
    1602             : {
    1603        1352 :     if (aContents.size() != rCompare.aContents.size())
    1604             :     {
    1605           0 :         return false;
    1606             :     }
    1607             : 
    1608        3215 :     for (size_t i = 0, n = aContents.size(); i < n; ++i)
    1609             :     {
    1610        1873 :         const ContentInfo& rCandA = aContents[i];
    1611        1873 :         const ContentInfo& rCandB = rCompare.aContents[i];
    1612             : 
    1613        1873 :         if(!rCandA.isWrongListEqual(rCandB))
    1614             :         {
    1615          10 :             return false;
    1616             :         }
    1617             :     }
    1618             : 
    1619        1342 :     return true;
    1620             : }
    1621             : 
    1622             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11