blob: 2223130a5081bc9b6f275491fbc9a830ea8551b9 [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_editeng.hxx"
#include <vcl/wrkwin.hxx>
#include <vcl/dialog.hxx>
#include <vcl/msgbox.hxx>
#include <vcl/svapp.hxx>
#define ENABLE_STRING_STREAM_OPERATORS
#include <tools/stream.hxx>
#include <editobj2.hxx>
#include <editeng/editdata.hxx>
#include <editattr.hxx>
#include <editeng/editeng.hxx>
#include <editeng/fontitem.hxx>
#include <editeng/cscoitem.hxx>
#include <editeng/flditem.hxx>
#include <editeng/lrspitem.hxx>
#include <editeng/tstpitem.hxx>
#include <editeng/bulitem.hxx>
#include <editeng/numitem.hxx>
#include <editeng/brshitem.hxx>
#include <vcl/graph.hxx>
#include <svl/intitem.hxx>
#include <unotools/fontcvt.hxx>
#include <tools/tenccvt.hxx>
DBG_NAME( EE_EditTextObject )
DBG_NAME( XEditAttribute )
//--------------------------------------------------------------
sal_Bool lcl_CreateBulletItem( const SvxNumBulletItem& rNumBullet, sal_uInt16 nLevel, SvxBulletItem& rBullet )
{
const SvxNumberFormat* pFmt = rNumBullet.GetNumRule()->Get( nLevel );
if ( pFmt )
{
rBullet.SetWidth( (-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance() );
rBullet.SetSymbol( pFmt->GetBulletChar() );
rBullet.SetPrevText( pFmt->GetPrefix() );
rBullet.SetFollowText( pFmt->GetSuffix() );
rBullet.SetStart( pFmt->GetStart() );
rBullet.SetScale( pFmt->GetBulletRelSize() );
Font aBulletFont( rBullet.GetFont() );
if ( pFmt->GetBulletFont() )
aBulletFont = *pFmt->GetBulletFont();
aBulletFont.SetColor( pFmt->GetBulletColor() );
rBullet.SetFont( aBulletFont );
if ( pFmt->GetBrush() && pFmt->GetBrush()->GetGraphic() )
{
Bitmap aBmp( pFmt->GetBrush()->GetGraphic()->GetBitmap() );
aBmp.SetPrefSize( pFmt->GetGraphicSize() );
aBmp.SetPrefMapMode( MAP_100TH_MM );
rBullet.SetBitmap( aBmp );
}
switch ( pFmt->GetNumberingType() )
{
case SVX_NUM_CHARS_UPPER_LETTER:
case SVX_NUM_CHARS_UPPER_LETTER_N:
rBullet.SetStyle( BS_ABC_BIG );
break;
case SVX_NUM_CHARS_LOWER_LETTER:
case SVX_NUM_CHARS_LOWER_LETTER_N:
rBullet.SetStyle( BS_ABC_SMALL );
break;
case SVX_NUM_ROMAN_UPPER:
rBullet.SetStyle( BS_ROMAN_BIG );
break;
case SVX_NUM_ROMAN_LOWER:
rBullet.SetStyle( BS_ROMAN_SMALL );
break;
case SVX_NUM_ARABIC:
rBullet.SetStyle( BS_123 );
break;
case SVX_NUM_NUMBER_NONE:
rBullet.SetStyle( BS_NONE );
break;
case SVX_NUM_CHAR_SPECIAL:
rBullet.SetStyle( BS_BULLET );
break;
case SVX_NUM_PAGEDESC:
DBG_ERROR( "Unknown: SVX_NUM_PAGEDESC" );
rBullet.SetStyle( BS_BULLET );
break;
case SVX_NUM_BITMAP:
rBullet.SetStyle( BS_BMP );
break;
default:
DBG_ERROR( "Unknown NumType" );
}
switch ( pFmt->GetNumAdjust() )
{
case SVX_ADJUST_LEFT:
rBullet.SetJustification( BJ_VCENTER|BJ_HLEFT );
break;
case SVX_ADJUST_RIGHT:
rBullet.SetJustification( BJ_VCENTER|BJ_HRIGHT );
break;
case SVX_ADJUST_CENTER:
rBullet.SetJustification( BJ_VCENTER|BJ_HCENTER );
break;
default:
DBG_ERROR( "Unknown or invalid NumAdjust" );
}
}
return pFmt ? sal_True : sal_False;
}
XEditAttribute* MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
{
// das neue Attribut im Pool anlegen
const SfxPoolItem& rNew = rPool.Put( rItem );
XEditAttribute* pNew = new XEditAttribute( rNew, nStart, nEnd );
return pNew;
}
XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr )
{
DBG_CTOR( XEditAttribute, 0 );
pItem = &rAttr;
nStart = 0;
nEnd = 0;
}
XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, sal_uInt16 nS, sal_uInt16 nE )
{
DBG_CTOR( XEditAttribute, 0 );
pItem = &rAttr;
nStart = nS;
nEnd = nE;
}
XEditAttribute::~XEditAttribute()
{
DBG_DTOR( XEditAttribute, 0 );
pItem = 0; // Gehoert dem Pool.
}
XEditAttribute* XEditAttributeList::FindAttrib( sal_uInt16 _nWhich, sal_uInt16 nChar ) const
{
for ( sal_uInt16 n = Count(); n; )
{
XEditAttribute* pAttr = GetObject( --n );
if( ( pAttr->GetItem()->Which() == _nWhich ) && ( pAttr->GetStart() <= nChar ) && ( pAttr->GetEnd() > nChar ) )
return pAttr;
}
return NULL;
}
ContentInfo::ContentInfo( SfxItemPool& rPool ) : aParaAttribs( rPool, EE_PARA_START, EE_CHAR_END )
{
eFamily = SFX_STYLE_FAMILY_PARA;
pWrongs = NULL;
/* cl removed because not needed anymore since binfilter
pTempLoadStoreInfos = NULL;
*/
}
// Richtiger CopyCTOR unsinning, weil ich mit einem anderen Pool arbeiten muss!
ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse )
: aParaAttribs( rPoolToUse, EE_PARA_START, EE_CHAR_END )
{
pWrongs = NULL;
/* cl removed because not needed anymore since binfilter
pTempLoadStoreInfos = NULL;
*/
if ( rCopyFrom.GetWrongList() )
pWrongs = rCopyFrom.GetWrongList()->Clone();
// So sollten die Items im richtigen Pool landen!
aParaAttribs.Set( rCopyFrom.GetParaAttribs() );
aText = rCopyFrom.GetText();
aStyle = rCopyFrom.GetStyle();
eFamily = rCopyFrom.GetFamily();
// Attribute kopieren...
for ( sal_uInt16 n = 0; n < rCopyFrom.GetAttribs().Count(); n++ )
{
XEditAttribute* pAttr = rCopyFrom.GetAttribs().GetObject( n );
XEditAttribute* pMyAttr = MakeXEditAttribute( rPoolToUse, *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
aAttribs.Insert( pMyAttr, aAttribs.Count() );
}
// memory leak #119992: to release pWrongs cloned from rCopyFrom
if (pWrongs != NULL)
delete pWrongs;
// Wrongs
pWrongs = NULL;
#ifndef SVX_LIGHT
if ( rCopyFrom.GetWrongList() )
pWrongs = rCopyFrom.GetWrongList()->Clone();
#endif // !SVX_LIGHT
}
ContentInfo::~ContentInfo()
{
for ( sal_uInt16 nAttr = 0; nAttr < aAttribs.Count(); nAttr++ )
{
XEditAttribute* pAttr = aAttribs.GetObject(nAttr);
// Item aus Pool entfernen!
aParaAttribs.GetPool()->Remove( *pAttr->GetItem() );
delete pAttr;
}
aAttribs.Remove( 0, aAttribs.Count() );
#ifndef SVX_LIGHT
delete pWrongs;
#endif
}
/* cl removed because not needed anymore since binfilter
void ContentInfo::CreateLoadStoreTempInfos()
{
delete pTempLoadStoreInfos;
pTempLoadStoreInfos = new LoadStoreTempInfos;
}
void ContentInfo::DestroyLoadStoreTempInfos()
{
delete pTempLoadStoreInfos;
pTempLoadStoreInfos = NULL;
}
*/
// #i102062#
bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
{
if(GetWrongList() == rCompare.GetWrongList())
return true;
if(!GetWrongList() || !rCompare.GetWrongList())
return false;
return (*GetWrongList() == *rCompare.GetWrongList());
}
bool ContentInfo::operator==( const ContentInfo& rCompare ) const
{
if( (aText == rCompare.aText) &&
(aStyle == rCompare.aStyle ) &&
(aAttribs.Count() == rCompare.aAttribs.Count() ) &&
(eFamily == rCompare.eFamily ) &&
(aParaAttribs == rCompare.aParaAttribs ) )
{
const sal_uInt16 nCount = aAttribs.Count();
if( nCount == rCompare.aAttribs.Count() )
{
sal_uInt16 n;
for( n = 0; n < nCount; n++ )
{
if( !(*aAttribs.GetObject(n) == *rCompare.aAttribs.GetObject(n)) )
return false;
}
return true;
}
}
return false;
}
EditTextObject::EditTextObject( sal_uInt16 n)
{
DBG_CTOR( EE_EditTextObject, 0 );
nWhich = n;
}
EditTextObject::EditTextObject( const EditTextObject& r )
{
DBG_CTOR( EE_EditTextObject, 0 );
nWhich = r.nWhich;
}
__EXPORT EditTextObject::~EditTextObject()
{
DBG_DTOR( EE_EditTextObject, 0 );
}
sal_uInt16 EditTextObject::GetParagraphCount() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
XubString EditTextObject::GetText( sal_uInt16 /* nParagraph */ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return XubString();
}
void EditTextObject::Insert( const EditTextObject& /* rObj */, sal_uInt16 /* nPara */)
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
EditTextObject* EditTextObject::CreateTextObject( sal_uInt16 /*nPara*/, sal_uInt16 /*nParas*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
void EditTextObject::RemoveParagraph( sal_uInt16 /*nPara*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool EditTextObject::HasPortionInfo() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
void EditTextObject::ClearPortionInfo()
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool EditTextObject::HasOnlineSpellErrors() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
sal_Bool EditTextObject::HasCharAttribs( sal_uInt16 ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
void EditTextObject::GetCharAttribs( sal_uInt16 /*nPara*/, EECharAttribArray& /*rLst*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
void EditTextObject::MergeParaAttribs( const SfxItemSet& /*rAttribs*/, sal_uInt16 /*nStart*/, sal_uInt16 /*nEnd*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool EditTextObject::IsFieldObject() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
const SvxFieldItem* EditTextObject::GetField() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
sal_Bool EditTextObject::HasField( TypeId /*aType*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
SfxItemSet EditTextObject::GetParaAttribs( sal_uInt16 /*nPara*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return SfxItemSet( *(SfxItemPool*)NULL );
}
void EditTextObject::SetParaAttribs( sal_uInt16 /*nPara*/, const SfxItemSet& /*rAttribs*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool EditTextObject::RemoveCharAttribs( sal_uInt16 /*nWhich*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
sal_Bool EditTextObject::RemoveParaAttribs( sal_uInt16 /*nWhich*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
sal_Bool EditTextObject::HasStyleSheet( const XubString& /*rName*/, SfxStyleFamily /*eFamily*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
void EditTextObject::GetStyleSheet( sal_uInt16 /*nPara*/, XubString& /*rName*/, SfxStyleFamily& /*eFamily*/ ) const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
void EditTextObject::SetStyleSheet( sal_uInt16 /*nPara*/, const XubString& /*rName*/, const SfxStyleFamily& /*eFamily*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool __EXPORT EditTextObject::ChangeStyleSheets( const XubString&, SfxStyleFamily,
const XubString&, SfxStyleFamily )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
void __EXPORT EditTextObject::ChangeStyleSheetName( SfxStyleFamily /*eFamily*/,
const XubString& /*rOldName*/, const XubString& /*rNewName*/ )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_uInt16 EditTextObject::GetUserType() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
void EditTextObject::SetUserType( sal_uInt16 )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_uLong EditTextObject::GetObjectSettings() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
void EditTextObject::SetObjectSettings( sal_uLong )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
}
sal_Bool EditTextObject::IsVertical() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return sal_False;
}
void EditTextObject::SetVertical( sal_Bool bVertical )
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
((BinTextObject*)this)->SetVertical( bVertical );
}
sal_uInt16 EditTextObject::GetScriptType() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return ((const BinTextObject*)this)->GetScriptType();
}
sal_Bool EditTextObject::Store( SvStream& rOStream ) const
{
if ( rOStream.GetError() )
return sal_False;
// Vorspann:
sal_Size nStartPos = rOStream.Tell();
rOStream << (sal_uInt16)Which();
sal_uInt32 nStructSz = 0;
rOStream << nStructSz;
// Eigene Daten:
StoreData( rOStream );
// Nachspann:
sal_Size nEndPos = rOStream.Tell();
nStructSz = nEndPos - nStartPos - sizeof( nWhich ) - sizeof( nStructSz );
rOStream.Seek( nStartPos + sizeof( nWhich ) );
rOStream << nStructSz;
rOStream.Seek( nEndPos );
return rOStream.GetError() ? sal_False : sal_True;
}
EditTextObject* EditTextObject::Create( SvStream& rIStream, SfxItemPool* pGlobalTextObjectPool )
{
sal_uLong nStartPos = rIStream.Tell();
// Ertmal sehen, was fuer ein Object...
sal_uInt16 nWhich;
rIStream >> nWhich;
sal_uInt32 nStructSz;
rIStream >> nStructSz;
DBG_ASSERT( ( nWhich == 0x22 /*EE_FORMAT_BIN300*/ ) || ( nWhich == EE_FORMAT_BIN ), "CreateTextObject: Unbekanntes Objekt!" );
if ( rIStream.GetError() )
return NULL;
EditTextObject* pTxtObj = NULL;
switch ( nWhich )
{
case 0x22 /*BIN300*/: pTxtObj = new BinTextObject( 0 );
((BinTextObject*)pTxtObj)->CreateData300( rIStream );
break;
case EE_FORMAT_BIN: pTxtObj = new BinTextObject( pGlobalTextObjectPool );
pTxtObj->CreateData( rIStream );
break;
default:
{
// Wenn ich das Format nicht kenne, ueberlese ich den Inhalt:
rIStream.SetError( EE_READWRITE_WRONGFORMAT );
}
}
// Sicherstellen, dass der Stream an der richtigen Stelle hinterlassen wird.
sal_Size nFullSz = sizeof( nWhich ) + sizeof( nStructSz ) + nStructSz;
rIStream.Seek( nStartPos + nFullSz );
return pTxtObj;
}
void EditTextObject::Skip( SvStream& rIStream )
{
sal_Size nStartPos = rIStream.Tell();
sal_uInt16 _nWhich;
rIStream >> _nWhich;
sal_uInt32 nStructSz;
rIStream >> nStructSz;
sal_Size nFullSz = sizeof( _nWhich ) + sizeof( nStructSz ) + nStructSz;
rIStream.Seek( nStartPos + nFullSz );
}
void __EXPORT EditTextObject::StoreData( SvStream& ) const
{
DBG_ERROR( "StoreData: Basisklasse!" );
}
void __EXPORT EditTextObject::CreateData( SvStream& )
{
DBG_ERROR( "CreateData: Basisklasse!" );
}
sal_uInt16 EditTextObject::GetVersion() const
{
DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
return 0;
}
bool EditTextObject::operator==( const EditTextObject& rCompare ) const
{
return static_cast< const BinTextObject* >( this )->operator==( static_cast< const BinTextObject& >( rCompare ) );
}
// #i102062#
bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
{
return static_cast< const BinTextObject* >(this)->isWrongListEqual(static_cast< const BinTextObject& >(rCompare));
}
// from SfxItemPoolUser
void BinTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
{
if(!bOwnerOfPool && pPool && pPool == &rSfxItemPool)
{
// The pool we are based on gets destructed; get owner of pool by creating own one.
// No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor
// Base new pool on EditEnginePool; it would also be possible to clone the used
// pool if needed, but only text attributes should be used.
SfxItemPool* pNewPool = EditEngine::CreatePool();
if(pPool)
{
pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC));
}
for(sal_uInt16 n(0); n < aContents.Count(); n++)
{
// clone ContentInfos for new pool
ContentInfo* pOrg = aContents.GetObject(n);
DBG_ASSERT(pOrg, "NULL-Pointer in ContentList!");
ContentInfo* pNew = new ContentInfo(*pOrg, *pNewPool);
aContents.Replace(pNew, n);
delete pOrg;
}
// set local variables
pPool = pNewPool;
bOwnerOfPool = sal_True;
}
}
EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
{
EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
while(!pRetval && pPool && pPool->GetSecondaryPool())
{
pPool = pPool->GetSecondaryPool();
if(pPool)
{
pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
}
}
return pRetval;
}
BinTextObject::BinTextObject( SfxItemPool* pP ) :
EditTextObject( EE_FORMAT_BIN ),
SfxItemPoolUser()
{
nVersion = 0;
nMetric = 0xFFFF;
nUserType = 0;
nObjSettings = 0;
pPortionInfo = 0;
// #i101239# ensure target is a EditEngineItemPool, else
// fallback to pool ownership. This is needed to ensure that at
// pool destruction time of an alien pool, the pool is still alive.
// When registering would happen at an alien pool which just uses an
// EditEngineItemPool as some sub-pool, that pool could already
// be decoupled and deleted whcih would lead to crashes.
pPool = getEditEngineItemPool(pP);
if ( pPool )
{
bOwnerOfPool = sal_False;
}
else
{
pPool = EditEngine::CreatePool();
bOwnerOfPool = sal_True;
}
if(!bOwnerOfPool && pPool)
{
// it is sure now that the pool is an EditEngineItemPool
pPool->AddSfxItemPoolUser(*this);
}
bVertical = sal_False;
bStoreUnicodeStrings = sal_False;
nScriptType = 0;
}
BinTextObject::BinTextObject( const BinTextObject& r ) :
EditTextObject( r ),
SfxItemPoolUser()
{
nVersion = r.nVersion;
nMetric = r.nMetric;
nUserType = r.nUserType;
nObjSettings = r.nObjSettings;
bVertical = r.bVertical;
nScriptType = r.nScriptType;
pPortionInfo = NULL; // PortionInfo nicht kopieren
bStoreUnicodeStrings = sal_False;
if ( !r.bOwnerOfPool )
{
// reuse alien pool; this must be a EditEngineItemPool
// since there is no other way to construct a BinTextObject
// than it's regular constructor where that is ensured
pPool = r.pPool;
bOwnerOfPool = sal_False;
}
else
{
pPool = EditEngine::CreatePool();
bOwnerOfPool = sal_True;
}
if(!bOwnerOfPool && pPool)
{
// it is sure now that the pool is an EditEngineItemPool
pPool->AddSfxItemPoolUser(*this);
}
if ( bOwnerOfPool && pPool && r.pPool )
pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) );
for ( sal_uInt16 n = 0; n < r.aContents.Count(); n++ )
{
ContentInfo* pOrg = r.aContents.GetObject( n );
DBG_ASSERT( pOrg, "NULL-Pointer in ContentList!" );
ContentInfo* pNew = new ContentInfo( *pOrg, *pPool );
aContents.Insert( pNew, aContents.Count() );
}
}
__EXPORT BinTextObject::~BinTextObject()
{
if(!bOwnerOfPool && pPool)
{
pPool->RemoveSfxItemPoolUser(*this);
}
ClearPortionInfo();
DeleteContents();
if ( bOwnerOfPool )
{
// Nicht mehr, wegen 1xDefItems.
// siehe auch ~EditDoc().
// pPool->ReleaseDefaults( sal_True /* bDelete */ );
SfxItemPool::Free(pPool);
}
}
sal_uInt16 BinTextObject::GetUserType() const
{
return nUserType;
}
void BinTextObject::SetUserType( sal_uInt16 n )
{
nUserType = n;
}
sal_uLong BinTextObject::GetObjectSettings() const
{
return nObjSettings;
}
void BinTextObject::SetObjectSettings( sal_uLong n )
{
nObjSettings = n;
}
sal_Bool BinTextObject::IsVertical() const
{
return bVertical;
}
void BinTextObject::SetVertical( sal_Bool b )
{
if ( b != bVertical )
{
bVertical = b;
ClearPortionInfo();
}
}
sal_uInt16 BinTextObject::GetScriptType() const
{
return nScriptType;
}
void BinTextObject::SetScriptType( sal_uInt16 nType )
{
nScriptType = nType;
}
void BinTextObject::DeleteContents()
{
for ( sal_uInt16 n = 0; n < aContents.Count(); n++ )
{
ContentInfo* p = aContents.GetObject( n );
DBG_ASSERT( p, "NULL-Pointer in ContentList!" );
delete p;
}
aContents.Remove( 0, aContents.Count() );
}
EditTextObject* __EXPORT BinTextObject::Clone() const
{
return new BinTextObject( *this );
}
XEditAttribute* BinTextObject::CreateAttrib( const SfxPoolItem& rItem, sal_uInt16 nStart, sal_uInt16 nEnd )
{
return MakeXEditAttribute( *pPool, rItem, nStart, nEnd );
}
void BinTextObject::DestroyAttrib( XEditAttribute* pAttr )
{
pPool->Remove( *pAttr->GetItem() );
delete pAttr;
}
ContentInfo* BinTextObject::CreateAndInsertContent()
{
ContentInfo* pC = new ContentInfo( *pPool );
aContents.Insert( pC, aContents.Count() );
return pC;
}
sal_uInt16 BinTextObject::GetParagraphCount() const
{
return aContents.Count();
}
XubString BinTextObject::GetText( sal_uInt16 nPara ) const
{
DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
if ( nPara < aContents.Count() )
{
ContentInfo* pC = aContents[ nPara ];
return pC->GetText();
}
return XubString();
}
void BinTextObject::Insert( const EditTextObject& rObj, sal_uInt16 nDestPara )
{
DBG_ASSERT( rObj.Which() == EE_FORMAT_BIN, "UTO: Unbekanntes Textobjekt" );
const BinTextObject& rBinObj = (const BinTextObject&)rObj;
if ( nDestPara > aContents.Count() )
nDestPara = aContents.Count();
const sal_uInt16 nParas = rBinObj.GetContents().Count();
for ( sal_uInt16 nP = 0; nP < nParas; nP++ )
{
ContentInfo* pC = rBinObj.GetContents()[ nP ];
ContentInfo* pNew = new ContentInfo( *pC, *GetPool() );
aContents.Insert( pNew, nDestPara+nP );
}
ClearPortionInfo();
}
EditTextObject* BinTextObject::CreateTextObject( sal_uInt16 nPara, sal_uInt16 nParas ) const
{
if ( ( nPara >= aContents.Count() ) || !nParas )
return NULL;
// Pool nur teilen, wenn von aussen eingestellter Pool.
BinTextObject* pObj = new BinTextObject( bOwnerOfPool ? 0 : pPool );
if ( bOwnerOfPool && pPool )
pObj->GetPool()->SetDefaultMetric( pPool->GetMetric( DEF_METRIC ) );
// If complete text is only one ScriptType, this is valid.
// If text contains different ScriptTypes, this shouldn't be a problem...
pObj->nScriptType = nScriptType;
const sal_uInt16 nEndPara = nPara+nParas-1;
for ( sal_uInt16 nP = nPara; nP <= nEndPara; nP++ )
{
ContentInfo* pC = aContents[ nP ];
ContentInfo* pNew = new ContentInfo( *pC, *pObj->GetPool() );
pObj->GetContents().Insert( pNew, pObj->GetContents().Count() );
}
return pObj;
}
void BinTextObject::RemoveParagraph( sal_uInt16 nPara )
{
DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
if ( nPara < aContents.Count() )
{
ContentInfo* pC = aContents[ nPara ];
aContents.Remove( nPara );
delete pC;
ClearPortionInfo();
}
}
sal_Bool BinTextObject::HasPortionInfo() const
{
return pPortionInfo ? sal_True : sal_False;
}
void BinTextObject::ClearPortionInfo()
{
if ( pPortionInfo )
{
for ( sal_uInt16 n = pPortionInfo->Count(); n; )
delete pPortionInfo->GetObject( --n );
delete pPortionInfo;
pPortionInfo = NULL;
}
}
sal_Bool BinTextObject::HasOnlineSpellErrors() const
{
#ifndef SVX_LIGHT
for ( sal_uInt16 n = 0; n < aContents.Count(); n++ )
{
ContentInfo* p = aContents.GetObject( n );
if ( p->GetWrongList() && p->GetWrongList()->Count() )
return sal_True;
}
#endif // !SVX_LIGHT
return sal_False;
}
sal_Bool BinTextObject::HasCharAttribs( sal_uInt16 _nWhich ) const
{
for ( sal_uInt16 nPara = GetContents().Count(); nPara; )
{
ContentInfo* pC = GetContents().GetObject( --nPara );
sal_uInt16 nAttribs = pC->GetAttribs().Count();
if ( nAttribs && !_nWhich )
return sal_True;
for ( sal_uInt16 nAttr = nAttribs; nAttr; )
{
XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
if ( pX->GetItem()->Which() == _nWhich )
return sal_True;
}
}
return sal_False;
}
void BinTextObject::GetCharAttribs( sal_uInt16 nPara, EECharAttribArray& rLst ) const
{
rLst.Remove( 0, rLst.Count() );
ContentInfo* pC = GetContents().GetObject( nPara );
if ( pC )
{
for ( sal_uInt16 nAttr = 0; nAttr < pC->GetAttribs().Count(); nAttr++ )
{
XEditAttribute* pAttr = pC->GetAttribs().GetObject( nAttr );
EECharAttrib aEEAttr;
aEEAttr.pAttr = pAttr->GetItem();
aEEAttr.nPara = nPara;
aEEAttr.nStart = pAttr->GetStart();
aEEAttr.nEnd = pAttr->GetEnd();
rLst.Insert( aEEAttr, rLst.Count() );
}
}
}
void BinTextObject::MergeParaAttribs( const SfxItemSet& rAttribs, sal_uInt16 nStart, sal_uInt16 nEnd )
{
sal_Bool bChanged = sal_False;
for ( sal_uInt16 nPara = GetContents().Count(); nPara; )
{
ContentInfo* pC = GetContents().GetObject( --nPara );
for ( sal_uInt16 nW = nStart; nW <= nEnd; nW++ )
{
if ( ( pC->GetParaAttribs().GetItemState( nW, sal_False ) != SFX_ITEM_ON )
&& ( rAttribs.GetItemState( nW, sal_False ) == SFX_ITEM_ON ) )
{
pC->GetParaAttribs().Put( rAttribs.Get( nW ) );
bChanged = sal_True;
}
}
}
if ( bChanged )
ClearPortionInfo();
}
sal_Bool BinTextObject::IsFieldObject() const
{
return BinTextObject::GetField() ? sal_True : sal_False;
}
const SvxFieldItem* BinTextObject::GetField() const
{
if ( GetContents().Count() == 1 )
{
ContentInfo* pC = GetContents()[0];
if ( pC->GetText().Len() == 1 )
{
sal_uInt16 nAttribs = pC->GetAttribs().Count();
for ( sal_uInt16 nAttr = nAttribs; nAttr; )
{
XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
if ( pX->GetItem()->Which() == EE_FEATURE_FIELD )
return (const SvxFieldItem*)pX->GetItem();
}
}
}
return 0;
}
sal_Bool BinTextObject::HasField( TypeId aType ) const
{
sal_uInt16 nParagraphs = GetContents().Count();
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
sal_uInt16 nAttrs = pC->GetAttribs().Count();
for ( sal_uInt16 nAttr = 0; nAttr < nAttrs; nAttr++ )
{
XEditAttribute* pAttr = pC->GetAttribs()[nAttr];
if ( pAttr->GetItem()->Which() == EE_FEATURE_FIELD )
{
if ( !aType )
return sal_True;
const SvxFieldData* pFldData = ((const SvxFieldItem*)pAttr->GetItem())->GetField();
if ( pFldData && pFldData->IsA( aType ) )
return sal_True;
}
}
}
return sal_False;
}
SfxItemSet BinTextObject::GetParaAttribs( sal_uInt16 nPara ) const
{
ContentInfo* pC = GetContents().GetObject( nPara );
return pC->GetParaAttribs();
}
void BinTextObject::SetParaAttribs( sal_uInt16 nPara, const SfxItemSet& rAttribs )
{
ContentInfo* pC = GetContents().GetObject( nPara );
pC->GetParaAttribs().Set( rAttribs );
ClearPortionInfo();
}
sal_Bool BinTextObject::RemoveCharAttribs( sal_uInt16 _nWhich )
{
sal_Bool bChanged = sal_False;
for ( sal_uInt16 nPara = GetContents().Count(); nPara; )
{
ContentInfo* pC = GetContents().GetObject( --nPara );
for ( sal_uInt16 nAttr = pC->GetAttribs().Count(); nAttr; )
{
XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
if ( !_nWhich || ( pAttr->GetItem()->Which() == _nWhich ) )
{
pC->GetAttribs().Remove( nAttr );
DestroyAttrib( pAttr );
bChanged = sal_True;
}
}
}
if ( bChanged )
ClearPortionInfo();
return bChanged;
}
sal_Bool BinTextObject::RemoveParaAttribs( sal_uInt16 _nWhich )
{
sal_Bool bChanged = sal_False;
for ( sal_uInt16 nPara = GetContents().Count(); nPara; )
{
ContentInfo* pC = GetContents().GetObject( --nPara );
if ( !_nWhich )
{
if( pC->GetParaAttribs().Count() )
bChanged = sal_True;
pC->GetParaAttribs().ClearItem();
}
else
{
if ( pC->GetParaAttribs().GetItemState( _nWhich ) == SFX_ITEM_ON )
{
pC->GetParaAttribs().ClearItem( _nWhich );
bChanged = sal_True;
}
}
}
if ( bChanged )
ClearPortionInfo();
return bChanged;
}
sal_Bool BinTextObject::HasStyleSheet( const XubString& rName, SfxStyleFamily eFamily ) const
{
sal_uInt16 nParagraphs = GetContents().Count();
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
if ( ( pC->GetFamily() == eFamily ) && ( pC->GetStyle() == rName ) )
return sal_True;
}
return sal_False;
}
void BinTextObject::GetStyleSheet( sal_uInt16 nPara, XubString& rName, SfxStyleFamily& rFamily ) const
{
if ( nPara < aContents.Count() )
{
ContentInfo* pC = aContents[ nPara ];
rName = pC->GetStyle();
rFamily = pC->GetFamily();
}
}
void BinTextObject::SetStyleSheet( sal_uInt16 nPara, const XubString& rName, const SfxStyleFamily& rFamily )
{
if ( nPara < aContents.Count() )
{
ContentInfo* pC = aContents[ nPara ];
pC->GetStyle() = rName;
pC->GetFamily() = rFamily;
}
}
sal_Bool BinTextObject::ImpChangeStyleSheets(
const XubString& rOldName, SfxStyleFamily eOldFamily,
const XubString& rNewName, SfxStyleFamily eNewFamily )
{
const sal_uInt16 nParagraphs = GetContents().Count();
sal_Bool bChanges = sal_False;
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
if ( pC->GetFamily() == eOldFamily )
{
if ( pC->GetStyle() == rOldName )
{
pC->GetStyle() = rNewName;
pC->GetFamily() = eNewFamily;
bChanges = sal_True;
}
}
}
return bChanges;
}
sal_Bool __EXPORT BinTextObject::ChangeStyleSheets(
const XubString& rOldName, SfxStyleFamily eOldFamily,
const XubString& rNewName, SfxStyleFamily eNewFamily )
{
sal_Bool bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
if ( bChanges )
ClearPortionInfo();
return bChanges;
}
void __EXPORT BinTextObject::ChangeStyleSheetName( SfxStyleFamily eFamily,
const XubString& rOldName, const XubString& rNewName )
{
ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
}
void __EXPORT BinTextObject::StoreData( SvStream& rOStream ) const
{
sal_uInt16 nVer = 602;
rOStream << nVer;
rOStream << bOwnerOfPool;
// Erst den Pool speichern, spaeter nur noch Surregate
if ( bOwnerOfPool )
{
GetPool()->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 );
GetPool()->Store( rOStream );
}
// Aktuelle Zeichensatz speichern...
// #90477# GetSOStoreTextEncoding: Bug in 5.2, when default char set is multi byte text encoding
rtl_TextEncoding eEncoding = GetSOStoreTextEncoding( gsl_getSystemTextEncoding(), (sal_uInt16) rOStream.GetVersion() );
rOStream << (sal_uInt16) eEncoding;
// Die Anzahl der Absaetze...
sal_uInt16 nParagraphs = GetContents().Count();
rOStream << nParagraphs;
char cFeatureConverted = ByteString( CH_FEATURE, eEncoding ).GetChar(0);
// Die einzelnen Absaetze...
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
// Text...
ByteString aText( pC->GetText(), eEncoding );
// Symbols?
sal_Bool bSymbolPara = sal_False;
if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
{
const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
{
aText = ByteString( pC->GetText(), RTL_TEXTENCODING_SYMBOL );
bSymbolPara = sal_True;
}
}
for ( sal_uInt16 nA = 0; nA < pC->GetAttribs().Count(); nA++ )
{
XEditAttribute* pAttr = pC->GetAttribs().GetObject( nA );
if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
{
const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
|| ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
{
// Not correctly converted
String aPart( pC->GetText(), pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
ByteString aNew( aPart, rFontItem.GetCharSet() );
aText.Erase( pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
aText.Insert( aNew, pAttr->GetStart() );
}
// #88414# Convert StarSymbol back to StarBats
FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
if ( hConv )
{
// Don't create a new Attrib with StarBats font, MBR changed the
// SvxFontItem::Store() to store StarBats instead of StarSymbol!
for ( sal_uInt16 nChar = pAttr->GetStart(); nChar < pAttr->GetEnd(); nChar++ )
{
sal_Unicode cOld = pC->GetText().GetChar( nChar );
char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
if ( cConv )
aText.SetChar( nChar, cConv );
}
DestroyFontToSubsFontConverter( hConv );
}
}
}
// #88414# Convert StarSymbol back to StarBats
// StarSymbol as paragraph attribute or in StyleSheet?
FontToSubsFontConverter hConv = NULL;
if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
{
hConv = CreateFontToSubsFontConverter( ((const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO )).GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
}
/* cl removed because not needed anymore since binfilter
else if ( pC->GetStyle().Len() && pC->GetLoadStoreTempInfos() )
{
hConv = pC->GetLoadStoreTempInfos()->hOldSymbolConv_Store;
}
*/
if ( hConv )
{
for ( sal_uInt16 nChar = 0; nChar < pC->GetText().Len(); nChar++ )
{
if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
{
sal_Unicode cOld = pC->GetText().GetChar( nChar );
char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
if ( cConv )
aText.SetChar( nChar, cConv );
}
}
DestroyFontToSubsFontConverter( hConv );
}
// Convert CH_FEATURE to CH_FEATURE_OLD
aText.SearchAndReplaceAll( cFeatureConverted, CH_FEATURE_OLD );
rOStream.WriteByteString( aText );
// StyleName und Family...
rOStream.WriteByteString( ByteString( pC->GetStyle(), eEncoding ) );
rOStream << (sal_uInt16)pC->GetFamily();
// Absatzattribute...
pC->GetParaAttribs().Store( rOStream );
// Die Anzahl der Attribute...
sal_uInt16 nAttribs = pC->GetAttribs().Count();
rOStream << nAttribs;
// Und die einzelnen Attribute
// Items als Surregate => immer 8 Byte pro Attrib
// Which = 2; Surregat = 2; Start = 2; End = 2;
for ( sal_uInt16 nAttr = 0; nAttr < nAttribs; nAttr++ )
{
XEditAttribute* pX = pC->GetAttribs().GetObject( nAttr );
rOStream << pX->GetItem()->Which();
GetPool()->StoreSurrogate( rOStream, pX->GetItem() );
rOStream << pX->GetStart();
rOStream << pX->GetEnd();
}
}
// Ab 400:
rOStream << nMetric;
// Ab 600
rOStream << nUserType;
rOStream << nObjSettings;
// Ab 601
rOStream << bVertical;
// Ab 602
rOStream << nScriptType;
rOStream << bStoreUnicodeStrings;
if ( bStoreUnicodeStrings )
{
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
sal_uInt16 nL = pC->GetText().Len();
rOStream << nL;
rOStream.Write( pC->GetText().GetBuffer(), nL*sizeof(sal_Unicode) );
// #91575# StyleSheetName must be Unicode too!
// Copy/Paste from EA3 to BETA or from BETA to EA3 not possible, not needed...
// If needed, change nL back to sal_uLong and increase version...
nL = pC->GetStyle().Len();
rOStream << nL;
rOStream.Write( pC->GetStyle().GetBuffer(), nL*sizeof(sal_Unicode) );
}
}
}
void __EXPORT BinTextObject::CreateData( SvStream& rIStream )
{
rIStream >> nVersion;
// Das Textobject wurde erstmal mit der aktuellen Einstellung
// von pTextObjectPool erzeugt.
sal_Bool bOwnerOfCurrent = bOwnerOfPool;
rIStream >> bOwnerOfPool;
if ( bOwnerOfCurrent && !bOwnerOfPool )
{
// Es wurde ein globaler Pool verwendet, mir jetzt nicht uebergeben,
// aber ich brauche ihn!
DBG_ERROR( "Man gebe mir den globalen TextObjectPool!" );
return;
}
else if ( !bOwnerOfCurrent && bOwnerOfPool )
{
// Es soll ein globaler Pool verwendet werden, aber dieses
// Textobject hat einen eigenen.
pPool = EditEngine::CreatePool();
}
if ( bOwnerOfPool )
GetPool()->Load( rIStream );
// CharSet, in dem gespeichert wurde:
sal_uInt16 nCharSet;
rIStream >> nCharSet;
rtl_TextEncoding eSrcEncoding = GetSOLoadTextEncoding( (rtl_TextEncoding)nCharSet, (sal_uInt16)rIStream.GetVersion() );
// Die Anzahl der Absaetze...
sal_uInt16 nParagraphs;
rIStream >> nParagraphs;
// Die einzelnen Absaetze...
for ( sal_uLong nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = CreateAndInsertContent();
// Der Text...
ByteString aByteString;
rIStream.ReadByteString( aByteString );
pC->GetText() = String( aByteString, eSrcEncoding );
// StyleName und Family...
rIStream.ReadByteString( pC->GetStyle(), eSrcEncoding );
sal_uInt16 nStyleFamily;
rIStream >> nStyleFamily;
pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
// Absatzattribute...
pC->GetParaAttribs().Load( rIStream );
// Die Anzahl der Attribute...
sal_uInt16 nAttribs;
rIStream >> nAttribs;
// Und die einzelnen Attribute
// Items als Surregate => immer 8 Byte pro Attrib
// Which = 2; Surregat = 2; Start = 2; End = 2;
sal_uInt16 nAttr;
for ( nAttr = 0; nAttr < nAttribs; nAttr++ )
{
sal_uInt16 _nWhich, nStart, nEnd;
const SfxPoolItem* pItem;
rIStream >> _nWhich;
_nWhich = pPool->GetNewWhich( _nWhich );
pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
rIStream >> nStart;
rIStream >> nEnd;
if ( pItem )
{
if ( pItem->Which() == EE_FEATURE_NOTCONV )
{
pC->GetText().SetChar( nStart, ByteString::ConvertToUnicode( aByteString.GetChar( nStart ), ((SvxCharSetColorItem*)pItem)->GetCharSet() ) );
}
else
{
XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
if ( ( _nWhich >= EE_FEATURE_START ) && ( _nWhich <= EE_FEATURE_END ) )
{
// Convert CH_FEATURE to CH_FEATURE_OLD
DBG_ASSERT( (sal_uInt8) aByteString.GetChar( nStart ) == CH_FEATURE_OLD, "CreateData: CH_FEATURE expected!" );
if ( (sal_uInt8) aByteString.GetChar( nStart ) == CH_FEATURE_OLD )
pC->GetText().SetChar( nStart, CH_FEATURE );
}
}
}
}
// But check for paragraph and character symbol attribs here,
// FinishLoad will not be called in OpenOffice Calc, no StyleSheets...
sal_Bool bSymbolPara = sal_False;
if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
{
const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
{
pC->GetText() = String( aByteString, RTL_TEXTENCODING_SYMBOL );
bSymbolPara = sal_True;
}
}
for ( nAttr = pC->GetAttribs().Count(); nAttr; )
{
XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
{
const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
|| ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
{
// Not correctly converted
ByteString aPart( aByteString, pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
String aNew( aPart, rFontItem.GetCharSet() );
pC->GetText().Erase( pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
pC->GetText().Insert( aNew, pAttr->GetStart() );
}
// #88414# Convert StarMath and StarBats to StarSymbol
FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
if ( hConv )
{
SvxFontItem aNewFontItem( rFontItem );
aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
pC->GetAttribs().Remove( nAttr );
XEditAttribute* pNewAttr = CreateAttrib( aNewFontItem, pAttr->GetStart(), pAttr->GetEnd() );
pC->GetAttribs().Insert( pNewAttr, nAttr );
DestroyAttrib( pAttr );
for ( sal_uInt16 nChar = pNewAttr->GetStart(); nChar < pNewAttr->GetEnd(); nChar++ )
{
sal_Unicode cOld = pC->GetText().GetChar( nChar );
DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
if ( cConv )
pC->GetText().SetChar( nChar, cConv );
}
DestroyFontToSubsFontConverter( hConv );
}
}
}
// #88414# Convert StarMath and StarBats to StarSymbol
// Maybe old symbol font as paragraph attribute?
if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
{
const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
if ( hConv )
{
SvxFontItem aNewFontItem( rFontItem );
aNewFontItem.SetFamilyName( GetFontToSubsFontName( hConv ) );
pC->GetParaAttribs().Put( aNewFontItem );
for ( sal_uInt16 nChar = 0; nChar < pC->GetText().Len(); nChar++ )
{
if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
{
sal_Unicode cOld = pC->GetText().GetChar( nChar );
DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
if ( cConv )
pC->GetText().SetChar( nChar, cConv );
}
}
DestroyFontToSubsFontConverter( hConv );
}
}
}
// Ab 400 auch die DefMetric:
if ( nVersion >= 400 )
{
sal_uInt16 nTmpMetric;
rIStream >> nTmpMetric;
if ( nVersion >= 401 )
{
// In der 400 gab es noch einen Bug bei Textobjekten mit eigenem
// Pool, deshalb erst ab 401 auswerten.
nMetric = nTmpMetric;
if ( bOwnerOfPool && pPool && ( nMetric != 0xFFFF ) )
pPool->SetDefaultMetric( (SfxMapUnit)nMetric );
}
}
if ( nVersion >= 600 )
{
rIStream >> nUserType;
rIStream >> nObjSettings;
}
if ( nVersion >= 601 )
{
rIStream >> bVertical;
}
if ( nVersion >= 602 )
{
rIStream >> nScriptType;
sal_Bool bUnicodeStrings;
rIStream >> bUnicodeStrings;
if ( bUnicodeStrings )
{
for ( sal_uInt16 nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = GetContents().GetObject( nPara );
sal_uInt16 nL;
// Text
rIStream >> nL;
if ( nL )
{
pC->GetText().AllocBuffer( nL );
rIStream.Read( pC->GetText().GetBufferAccess(), nL*sizeof(sal_Unicode) );
pC->GetText().ReleaseBufferAccess( (sal_uInt16)nL );
}
// StyleSheetName
rIStream >> nL;
if ( nL )
{
pC->GetStyle().AllocBuffer( nL );
rIStream.Read( pC->GetStyle().GetBufferAccess(), nL*sizeof(sal_Unicode) );
pC->GetStyle().ReleaseBufferAccess( (sal_uInt16)nL );
}
}
}
}
// Ab 500 werden die Tabs anders interpretiert: TabPos + LI, vorher nur TabPos.
// Wirkt nur wenn auch Tab-Positionen eingestellt wurden, nicht beim DefTab.
if ( nVersion < 500 )
{
for ( sal_uInt16 n = 0; n < aContents.Count(); n++ )
{
ContentInfo* pC = aContents.GetObject( n );
const SvxLRSpaceItem& rLRSpace = (const SvxLRSpaceItem&) pC->GetParaAttribs().Get( EE_PARA_LRSPACE );
if ( rLRSpace.GetTxtLeft() && ( pC->GetParaAttribs().GetItemState( EE_PARA_TABS ) == SFX_ITEM_ON ) )
{
const SvxTabStopItem& rTabs = (const SvxTabStopItem&) pC->GetParaAttribs().Get( EE_PARA_TABS );
SvxTabStopItem aNewTabs( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
for ( sal_uInt16 t = 0; t < rTabs.Count(); t++ )
{
const SvxTabStop& rT = rTabs[ t ];
aNewTabs.Insert( SvxTabStop( rT.GetTabPos() - rLRSpace.GetTxtLeft(),
rT.GetAdjustment(), rT.GetDecimal(), rT.GetFill() ) );
}
pC->GetParaAttribs().Put( aNewTabs );
}
}
}
}
sal_uInt16 BinTextObject::GetVersion() const
{
return nVersion;
}
bool BinTextObject::operator==( const BinTextObject& rCompare ) const
{
if( this == &rCompare )
return true;
if( ( aContents.Count() != rCompare.aContents.Count() ) ||
( pPool != rCompare.pPool ) ||
( nMetric != rCompare.nMetric ) ||
( nUserType!= rCompare.nUserType ) ||
( nScriptType != rCompare.nScriptType ) ||
( bVertical != rCompare.bVertical ) )
return false;
sal_uInt16 n;
for( n = 0; n < aContents.Count(); n++ )
{
if( !( *aContents.GetObject( n ) == *rCompare.aContents.GetObject( n ) ) )
return false;
}
return true;
}
// #i102062#
bool BinTextObject::isWrongListEqual(const BinTextObject& rCompare) const
{
if(GetContents().Count() != rCompare.GetContents().Count())
{
return false;
}
for(sal_uInt16 a(0); a < GetContents().Count(); a++)
{
const ContentInfo& rCandA(*GetContents().GetObject(a));
const ContentInfo& rCandB(*rCompare.GetContents().GetObject(a));
if(!rCandA.isWrongListEqual(rCandB))
{
return false;
}
}
return true;
}
#define CHARSETMARKER 0x9999
void __EXPORT BinTextObject::CreateData300( SvStream& rIStream )
{
// Fuer Aufwaertskompatibilitaet.
// Erst den Pool laden...
// Ist in der 300 immer gespeichert worden!
GetPool()->Load( rIStream );
// Die Anzahl der Absaetze...
sal_uInt32 nParagraphs;
rIStream >> nParagraphs;
// Die einzelnen Absaetze...
for ( sal_uLong nPara = 0; nPara < nParagraphs; nPara++ )
{
ContentInfo* pC = CreateAndInsertContent();
// Der Text...
rIStream.ReadByteString( pC->GetText() );
// StyleName und Family...
rIStream.ReadByteString( pC->GetStyle() );
sal_uInt16 nStyleFamily;
rIStream >> nStyleFamily;
pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
// Absatzattribute...
pC->GetParaAttribs().Load( rIStream );
// Die Anzahl der Attribute...
sal_uInt32 nAttribs;
rIStream >> nAttribs;
// Und die einzelnen Attribute
// Items als Surregate => immer 8 Byte pro Attrib
// Which = 2; Surregat = 2; Start = 2; End = 2;
for ( sal_uLong nAttr = 0; nAttr < nAttribs; nAttr++ )
{
sal_uInt16 _nWhich, nStart, nEnd;
const SfxPoolItem* pItem;
rIStream >> _nWhich;
_nWhich = pPool->GetNewWhich( _nWhich );
pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
rIStream >> nStart;
rIStream >> nEnd;
if ( pItem )
{
XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
}
}
}
// Prueffen, ob ein Zeichensatz gespeichert wurde
sal_uInt16 nCharSetMarker;
rIStream >> nCharSetMarker;
if ( nCharSetMarker == CHARSETMARKER )
{
sal_uInt16 nCharSet;
rIStream >> nCharSet;
}
}