update dev300-m58
[ooovba.git] / svx / source / editeng / editobj.cxx
blobd8f0a332b9e5bdb48af6606be41bcb16f5d52bdd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: editobj.cxx,v $
10 * $Revision: 1.30 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
35 #include <eeng_pch.hxx>
37 #define ENABLE_STRING_STREAM_OPERATORS
38 #include <tools/stream.hxx>
40 #include <editobj2.hxx>
41 #include <svx/editdata.hxx>
42 #include <editattr.hxx>
43 #include <svx/editeng.hxx>
44 #include <fontitem.hxx>
45 #include <svx/cscoitem.hxx>
46 #include <svx/flditem.hxx>
47 #include <svx/lrspitem.hxx>
48 #include <svx/tstpitem.hxx>
49 #include <bulitem.hxx>
50 #include <svx/numitem.hxx>
51 #include <svx/brshitem.hxx>
52 #include <vcl/graph.hxx>
53 #include <svtools/intitem.hxx>
54 #include <vcl/fontcvt.hxx>
55 #include <tools/tenccvt.hxx>
57 DBG_NAME( EE_EditTextObject )
58 DBG_NAME( XEditAttribute )
60 //--------------------------------------------------------------
62 BOOL lcl_CreateBulletItem( const SvxNumBulletItem& rNumBullet, USHORT nLevel, SvxBulletItem& rBullet )
64 const SvxNumberFormat* pFmt = rNumBullet.GetNumRule()->Get( nLevel );
65 if ( pFmt )
67 rBullet.SetWidth( (-pFmt->GetFirstLineOffset()) + pFmt->GetCharTextDistance() );
68 rBullet.SetSymbol( pFmt->GetBulletChar() );
69 rBullet.SetPrevText( pFmt->GetPrefix() );
70 rBullet.SetFollowText( pFmt->GetSuffix() );
71 rBullet.SetStart( pFmt->GetStart() );
72 rBullet.SetScale( pFmt->GetBulletRelSize() );
74 Font aBulletFont( rBullet.GetFont() );
75 if ( pFmt->GetBulletFont() )
76 aBulletFont = *pFmt->GetBulletFont();
77 aBulletFont.SetColor( pFmt->GetBulletColor() );
78 rBullet.SetFont( aBulletFont );
80 if ( pFmt->GetBrush() && pFmt->GetBrush()->GetGraphic() )
82 Bitmap aBmp( pFmt->GetBrush()->GetGraphic()->GetBitmap() );
83 aBmp.SetPrefSize( pFmt->GetGraphicSize() );
84 aBmp.SetPrefMapMode( MAP_100TH_MM );
85 rBullet.SetBitmap( aBmp );
88 switch ( pFmt->GetNumberingType() )
90 case SVX_NUM_CHARS_UPPER_LETTER:
91 case SVX_NUM_CHARS_UPPER_LETTER_N:
92 rBullet.SetStyle( BS_ABC_BIG );
93 break;
94 case SVX_NUM_CHARS_LOWER_LETTER:
95 case SVX_NUM_CHARS_LOWER_LETTER_N:
96 rBullet.SetStyle( BS_ABC_SMALL );
97 break;
98 case SVX_NUM_ROMAN_UPPER:
99 rBullet.SetStyle( BS_ROMAN_BIG );
100 break;
101 case SVX_NUM_ROMAN_LOWER:
102 rBullet.SetStyle( BS_ROMAN_SMALL );
103 break;
104 case SVX_NUM_ARABIC:
105 rBullet.SetStyle( BS_123 );
106 break;
107 case SVX_NUM_NUMBER_NONE:
108 rBullet.SetStyle( BS_NONE );
109 break;
110 case SVX_NUM_CHAR_SPECIAL:
111 rBullet.SetStyle( BS_BULLET );
112 break;
113 case SVX_NUM_PAGEDESC:
114 DBG_ERROR( "Unknown: SVX_NUM_PAGEDESC" );
115 rBullet.SetStyle( BS_BULLET );
116 break;
117 case SVX_NUM_BITMAP:
118 rBullet.SetStyle( BS_BMP );
119 break;
120 default:
121 DBG_ERROR( "Unknown NumType" );
124 switch ( pFmt->GetNumAdjust() )
126 case SVX_ADJUST_LEFT:
127 rBullet.SetJustification( BJ_VCENTER|BJ_HLEFT );
128 break;
129 case SVX_ADJUST_RIGHT:
130 rBullet.SetJustification( BJ_VCENTER|BJ_HRIGHT );
131 break;
132 case SVX_ADJUST_CENTER:
133 rBullet.SetJustification( BJ_VCENTER|BJ_HCENTER );
134 break;
135 default:
136 DBG_ERROR( "Unknown or invalid NumAdjust" );
139 return pFmt ? TRUE : FALSE;
143 XEditAttribute* MakeXEditAttribute( SfxItemPool& rPool, const SfxPoolItem& rItem, USHORT nStart, USHORT nEnd )
145 // das neue Attribut im Pool anlegen
146 const SfxPoolItem& rNew = rPool.Put( rItem );
148 XEditAttribute* pNew = new XEditAttribute( rNew, nStart, nEnd );
149 return pNew;
153 XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr )
155 DBG_CTOR( XEditAttribute, 0 );
156 pItem = &rAttr;
157 nStart = 0;
158 nEnd = 0;
161 XEditAttribute::XEditAttribute( const SfxPoolItem& rAttr, USHORT nS, USHORT nE )
163 DBG_CTOR( XEditAttribute, 0 );
164 pItem = &rAttr;
165 nStart = nS;
166 nEnd = nE;
169 XEditAttribute::~XEditAttribute()
171 DBG_DTOR( XEditAttribute, 0 );
172 pItem = 0; // Gehoert dem Pool.
175 XEditAttribute* XEditAttributeList::FindAttrib( USHORT _nWhich, USHORT nChar ) const
177 for ( USHORT n = Count(); n; )
179 XEditAttribute* pAttr = GetObject( --n );
180 if( ( pAttr->GetItem()->Which() == _nWhich ) && ( pAttr->GetStart() <= nChar ) && ( pAttr->GetEnd() > nChar ) )
181 return pAttr;
183 return NULL;
186 ContentInfo::ContentInfo( SfxItemPool& rPool ) : aParaAttribs( rPool, EE_PARA_START, EE_CHAR_END )
188 eFamily = SFX_STYLE_FAMILY_PARA;
189 pWrongs = NULL;
190 /* cl removed because not needed anymore since binfilter
191 pTempLoadStoreInfos = NULL;
195 // Richtiger CopyCTOR unsinning, weil ich mit einem anderen Pool arbeiten muss!
196 ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, SfxItemPool& rPoolToUse )
197 : aParaAttribs( rPoolToUse, EE_PARA_START, EE_CHAR_END )
199 pWrongs = NULL;
200 /* cl removed because not needed anymore since binfilter
201 pTempLoadStoreInfos = NULL;
203 if ( rCopyFrom.GetWrongList() )
204 pWrongs = rCopyFrom.GetWrongList()->Clone();
205 // So sollten die Items im richtigen Pool landen!
206 aParaAttribs.Set( rCopyFrom.GetParaAttribs() );
207 aText = rCopyFrom.GetText();
208 aStyle = rCopyFrom.GetStyle();
209 eFamily = rCopyFrom.GetFamily();
211 // Attribute kopieren...
212 for ( USHORT n = 0; n < rCopyFrom.GetAttribs().Count(); n++ )
214 XEditAttribute* pAttr = rCopyFrom.GetAttribs().GetObject( n );
215 XEditAttribute* pMyAttr = MakeXEditAttribute( rPoolToUse, *pAttr->GetItem(), pAttr->GetStart(), pAttr->GetEnd() );
216 aAttribs.Insert( pMyAttr, aAttribs.Count() );
219 // Wrongs
220 pWrongs = NULL;
221 #ifndef SVX_LIGHT
222 if ( rCopyFrom.GetWrongList() )
223 pWrongs = rCopyFrom.GetWrongList()->Clone();
224 #endif // !SVX_LIGHT
227 ContentInfo::~ContentInfo()
229 for ( USHORT nAttr = 0; nAttr < aAttribs.Count(); nAttr++ )
231 XEditAttribute* pAttr = aAttribs.GetObject(nAttr);
232 // Item aus Pool entfernen!
233 aParaAttribs.GetPool()->Remove( *pAttr->GetItem() );
234 delete pAttr;
236 aAttribs.Remove( 0, aAttribs.Count() );
237 #ifndef SVX_LIGHT
238 delete pWrongs;
239 #endif
242 /* cl removed because not needed anymore since binfilter
243 void ContentInfo::CreateLoadStoreTempInfos()
245 delete pTempLoadStoreInfos;
246 pTempLoadStoreInfos = new LoadStoreTempInfos;
249 void ContentInfo::DestroyLoadStoreTempInfos()
251 delete pTempLoadStoreInfos;
252 pTempLoadStoreInfos = NULL;
256 // #i102062#
257 bool ContentInfo::isWrongListEqual(const ContentInfo& rCompare) const
259 if(GetWrongList() == rCompare.GetWrongList())
260 return true;
262 if(!GetWrongList() || !rCompare.GetWrongList())
263 return false;
265 return (*GetWrongList() == *rCompare.GetWrongList());
268 bool ContentInfo::operator==( const ContentInfo& rCompare ) const
270 if( (aText == rCompare.aText) &&
271 (aStyle == rCompare.aStyle ) &&
272 (aAttribs.Count() == rCompare.aAttribs.Count() ) &&
273 (eFamily == rCompare.eFamily ) &&
274 (aParaAttribs == rCompare.aParaAttribs ) )
276 const USHORT nCount = aAttribs.Count();
277 if( nCount == rCompare.aAttribs.Count() )
279 USHORT n;
280 for( n = 0; n < nCount; n++ )
282 if( !(*aAttribs.GetObject(n) == *rCompare.aAttribs.GetObject(n)) )
283 return false;
286 return true;
290 return false;
293 EditTextObject::EditTextObject( USHORT n)
295 DBG_CTOR( EE_EditTextObject, 0 );
296 nWhich = n;
299 EditTextObject::EditTextObject( const EditTextObject& r )
301 DBG_CTOR( EE_EditTextObject, 0 );
302 nWhich = r.nWhich;
305 __EXPORT EditTextObject::~EditTextObject()
307 DBG_DTOR( EE_EditTextObject, 0 );
310 USHORT EditTextObject::GetParagraphCount() const
312 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
313 return 0;
316 XubString EditTextObject::GetText( USHORT /* nParagraph */ ) const
318 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
319 return XubString();
322 void EditTextObject::Insert( const EditTextObject& /* rObj */, USHORT /* nPara */)
324 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
327 EditTextObject* EditTextObject::CreateTextObject( USHORT /*nPara*/, USHORT /*nParas*/ ) const
329 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
330 return 0;
333 void EditTextObject::RemoveParagraph( USHORT /*nPara*/ )
335 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
338 BOOL EditTextObject::HasPortionInfo() const
340 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
341 return FALSE;
344 void EditTextObject::ClearPortionInfo()
346 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
349 BOOL EditTextObject::HasOnlineSpellErrors() const
351 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
352 return FALSE;
355 BOOL EditTextObject::HasCharAttribs( USHORT ) const
357 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
358 return FALSE;
361 void EditTextObject::GetCharAttribs( USHORT /*nPara*/, EECharAttribArray& /*rLst*/ ) const
363 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
366 void EditTextObject::MergeParaAttribs( const SfxItemSet& /*rAttribs*/, USHORT /*nStart*/, USHORT /*nEnd*/ )
368 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
371 BOOL EditTextObject::IsFieldObject() const
373 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
374 return FALSE;
377 const SvxFieldItem* EditTextObject::GetField() const
379 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
380 return 0;
383 BOOL EditTextObject::HasField( TypeId /*aType*/ ) const
385 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
386 return FALSE;
389 SfxItemSet EditTextObject::GetParaAttribs( USHORT /*nPara*/ ) const
391 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
392 return SfxItemSet( *(SfxItemPool*)NULL );
395 void EditTextObject::SetParaAttribs( USHORT /*nPara*/, const SfxItemSet& /*rAttribs*/ )
397 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
400 BOOL EditTextObject::RemoveCharAttribs( USHORT /*nWhich*/ )
402 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
403 return FALSE;
406 BOOL EditTextObject::RemoveParaAttribs( USHORT /*nWhich*/ )
408 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
409 return FALSE;
412 BOOL EditTextObject::HasStyleSheet( const XubString& /*rName*/, SfxStyleFamily /*eFamily*/ ) const
414 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
415 return FALSE;
418 void EditTextObject::GetStyleSheet( USHORT /*nPara*/, XubString& /*rName*/, SfxStyleFamily& /*eFamily*/ ) const
420 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
423 void EditTextObject::SetStyleSheet( USHORT /*nPara*/, const XubString& /*rName*/, const SfxStyleFamily& /*eFamily*/ )
425 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
428 BOOL __EXPORT EditTextObject::ChangeStyleSheets( const XubString&, SfxStyleFamily,
429 const XubString&, SfxStyleFamily )
431 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
432 return FALSE;
435 void __EXPORT EditTextObject::ChangeStyleSheetName( SfxStyleFamily /*eFamily*/,
436 const XubString& /*rOldName*/, const XubString& /*rNewName*/ )
438 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
441 USHORT EditTextObject::GetUserType() const
443 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
444 return 0;
447 void EditTextObject::SetUserType( USHORT )
449 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
452 ULONG EditTextObject::GetObjectSettings() const
454 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
455 return 0;
458 void EditTextObject::SetObjectSettings( ULONG )
460 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
463 BOOL EditTextObject::IsVertical() const
465 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
466 return FALSE;
469 void EditTextObject::SetVertical( BOOL bVertical )
471 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
472 ((BinTextObject*)this)->SetVertical( bVertical );
475 USHORT EditTextObject::GetScriptType() const
477 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
478 return ((const BinTextObject*)this)->GetScriptType();
482 BOOL EditTextObject::Store( SvStream& rOStream ) const
484 if ( rOStream.GetError() )
485 return FALSE;
487 // Vorspann:
488 sal_Size nStartPos = rOStream.Tell();
490 rOStream << (USHORT)Which();
492 sal_uInt32 nStructSz = 0;
493 rOStream << nStructSz;
495 // Eigene Daten:
496 StoreData( rOStream );
498 // Nachspann:
499 sal_Size nEndPos = rOStream.Tell();
500 nStructSz = nEndPos - nStartPos - sizeof( nWhich ) - sizeof( nStructSz );
501 rOStream.Seek( nStartPos + sizeof( nWhich ) );
502 rOStream << nStructSz;
503 rOStream.Seek( nEndPos );
505 return rOStream.GetError() ? FALSE : TRUE;
508 EditTextObject* EditTextObject::Create( SvStream& rIStream, SfxItemPool* pGlobalTextObjectPool )
510 ULONG nStartPos = rIStream.Tell();
512 // Ertmal sehen, was fuer ein Object...
513 USHORT nWhich;
514 rIStream >> nWhich;
516 sal_uInt32 nStructSz;
517 rIStream >> nStructSz;
519 DBG_ASSERT( ( nWhich == 0x22 /*EE_FORMAT_BIN300*/ ) || ( nWhich == EE_FORMAT_BIN ), "CreateTextObject: Unbekanntes Objekt!" );
521 if ( rIStream.GetError() )
522 return NULL;
524 EditTextObject* pTxtObj = NULL;
525 switch ( nWhich )
527 case 0x22 /*BIN300*/: pTxtObj = new BinTextObject( 0 );
528 ((BinTextObject*)pTxtObj)->CreateData300( rIStream );
529 break;
530 case EE_FORMAT_BIN: pTxtObj = new BinTextObject( pGlobalTextObjectPool );
531 pTxtObj->CreateData( rIStream );
532 break;
533 default:
535 // Wenn ich das Format nicht kenne, ueberlese ich den Inhalt:
536 rIStream.SetError( EE_READWRITE_WRONGFORMAT );
540 // Sicherstellen, dass der Stream an der richtigen Stelle hinterlassen wird.
541 sal_Size nFullSz = sizeof( nWhich ) + sizeof( nStructSz ) + nStructSz;
542 rIStream.Seek( nStartPos + nFullSz );
543 return pTxtObj;
546 void EditTextObject::Skip( SvStream& rIStream )
548 sal_Size nStartPos = rIStream.Tell();
550 USHORT _nWhich;
551 rIStream >> _nWhich;
553 sal_uInt32 nStructSz;
554 rIStream >> nStructSz;
556 sal_Size nFullSz = sizeof( _nWhich ) + sizeof( nStructSz ) + nStructSz;
557 rIStream.Seek( nStartPos + nFullSz );
560 void __EXPORT EditTextObject::StoreData( SvStream& ) const
562 DBG_ERROR( "StoreData: Basisklasse!" );
565 void __EXPORT EditTextObject::CreateData( SvStream& )
567 DBG_ERROR( "CreateData: Basisklasse!" );
570 USHORT EditTextObject::GetVersion() const
572 DBG_ERROR( "V-Methode direkt vom EditTextObject!" );
573 return 0;
576 bool EditTextObject::operator==( const EditTextObject& rCompare ) const
578 return static_cast< const BinTextObject* >( this )->operator==( static_cast< const BinTextObject& >( rCompare ) );
581 // #i102062#
582 bool EditTextObject::isWrongListEqual(const EditTextObject& rCompare) const
584 return static_cast< const BinTextObject* >(this)->isWrongListEqual(static_cast< const BinTextObject& >(rCompare));
587 // from SfxItemPoolUser
588 void BinTextObject::ObjectInDestruction(const SfxItemPool& rSfxItemPool)
590 if(!bOwnerOfPool && pPool && pPool == &rSfxItemPool)
592 // The pool we are based on gets destructed; get owner of pool by creating own one.
593 // No need to call RemoveSfxItemPoolUser(), this is done from the pool's destructor
594 // Base new pool on EditEnginePool; it would also be possible to clone the used
595 // pool if needed, but only text attributes should be used.
596 SfxItemPool* pNewPool = EditEngine::CreatePool();
598 if(pPool)
600 pNewPool->SetDefaultMetric(pPool->GetMetric(DEF_METRIC));
603 for(sal_uInt16 n(0); n < aContents.Count(); n++)
605 // clone ContentInfos for new pool
606 ContentInfo* pOrg = aContents.GetObject(n);
607 DBG_ASSERT(pOrg, "NULL-Pointer in ContentList!");
609 ContentInfo* pNew = new ContentInfo(*pOrg, *pNewPool);
610 aContents.Replace(pNew, n);
611 delete pOrg;
614 // set local variables
615 pPool = pNewPool;
616 bOwnerOfPool = TRUE;
620 EditEngineItemPool* getEditEngineItemPool(SfxItemPool* pPool)
622 EditEngineItemPool* pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
624 while(!pRetval && pPool && pPool->GetSecondaryPool())
626 pPool = pPool->GetSecondaryPool();
628 if(pPool)
630 pRetval = dynamic_cast< EditEngineItemPool* >(pPool);
634 return pRetval;
637 BinTextObject::BinTextObject( SfxItemPool* pP ) :
638 EditTextObject( EE_FORMAT_BIN ),
639 SfxItemPoolUser()
641 nVersion = 0;
642 nMetric = 0xFFFF;
643 nUserType = 0;
644 nObjSettings = 0;
645 pPortionInfo = 0;
647 // #i101239# ensure target is a EditEngineItemPool, else
648 // fallback to pool ownership. This is needed to ensure that at
649 // pool destruction time of an alien pool, the pool is still alive.
650 // When registering would happen at an alien pool which just uses an
651 // EditEngineItemPool as some sub-pool, that pool could already
652 // be decoupled and deleted whcih would lead to crashes.
653 pPool = getEditEngineItemPool(pP);
655 if ( pPool )
657 bOwnerOfPool = FALSE;
659 else
661 pPool = EditEngine::CreatePool();
662 bOwnerOfPool = TRUE;
665 if(!bOwnerOfPool && pPool)
667 // it is sure now that the pool is an EditEngineItemPool
668 pPool->AddSfxItemPoolUser(*this);
671 bVertical = FALSE;
672 bStoreUnicodeStrings = FALSE;
673 nScriptType = 0;
676 BinTextObject::BinTextObject( const BinTextObject& r ) :
677 EditTextObject( r ),
678 SfxItemPoolUser()
680 nVersion = r.nVersion;
681 nMetric = r.nMetric;
682 nUserType = r.nUserType;
683 nObjSettings = r.nObjSettings;
684 bVertical = r.bVertical;
685 nScriptType = r.nScriptType;
686 pPortionInfo = NULL; // PortionInfo nicht kopieren
687 bStoreUnicodeStrings = FALSE;
689 if ( !r.bOwnerOfPool )
691 // reuse alien pool; this must be a EditEngineItemPool
692 // since there is no other way to construct a BinTextObject
693 // than it's regular constructor where that is ensured
694 pPool = r.pPool;
695 bOwnerOfPool = FALSE;
697 else
699 pPool = EditEngine::CreatePool();
700 bOwnerOfPool = TRUE;
704 if(!bOwnerOfPool && pPool)
706 // it is sure now that the pool is an EditEngineItemPool
707 pPool->AddSfxItemPoolUser(*this);
710 if ( bOwnerOfPool && pPool && r.pPool )
711 pPool->SetDefaultMetric( r.pPool->GetMetric( DEF_METRIC ) );
713 for ( USHORT n = 0; n < r.aContents.Count(); n++ )
715 ContentInfo* pOrg = r.aContents.GetObject( n );
716 DBG_ASSERT( pOrg, "NULL-Pointer in ContentList!" );
717 ContentInfo* pNew = new ContentInfo( *pOrg, *pPool );
718 aContents.Insert( pNew, aContents.Count() );
722 __EXPORT BinTextObject::~BinTextObject()
724 if(!bOwnerOfPool && pPool)
726 pPool->RemoveSfxItemPoolUser(*this);
729 ClearPortionInfo();
730 DeleteContents();
731 if ( bOwnerOfPool )
733 // Nicht mehr, wegen 1xDefItems.
734 // siehe auch ~EditDoc().
735 // pPool->ReleaseDefaults( TRUE /* bDelete */ );
736 SfxItemPool::Free(pPool);
740 USHORT BinTextObject::GetUserType() const
742 return nUserType;
745 void BinTextObject::SetUserType( USHORT n )
747 nUserType = n;
750 ULONG BinTextObject::GetObjectSettings() const
752 return nObjSettings;
755 void BinTextObject::SetObjectSettings( ULONG n )
757 nObjSettings = n;
760 BOOL BinTextObject::IsVertical() const
762 return bVertical;
765 void BinTextObject::SetVertical( BOOL b )
767 if ( b != bVertical )
769 bVertical = b;
770 ClearPortionInfo();
774 USHORT BinTextObject::GetScriptType() const
776 return nScriptType;
779 void BinTextObject::SetScriptType( USHORT nType )
781 nScriptType = nType;
785 void BinTextObject::DeleteContents()
787 for ( USHORT n = 0; n < aContents.Count(); n++ )
789 ContentInfo* p = aContents.GetObject( n );
790 DBG_ASSERT( p, "NULL-Pointer in ContentList!" );
791 delete p;
793 aContents.Remove( 0, aContents.Count() );
796 EditTextObject* __EXPORT BinTextObject::Clone() const
798 return new BinTextObject( *this );
801 XEditAttribute* BinTextObject::CreateAttrib( const SfxPoolItem& rItem, USHORT nStart, USHORT nEnd )
803 return MakeXEditAttribute( *pPool, rItem, nStart, nEnd );
806 void BinTextObject::DestroyAttrib( XEditAttribute* pAttr )
808 pPool->Remove( *pAttr->GetItem() );
809 delete pAttr;
812 ContentInfo* BinTextObject::CreateAndInsertContent()
814 ContentInfo* pC = new ContentInfo( *pPool );
815 aContents.Insert( pC, aContents.Count() );
816 return pC;
819 USHORT BinTextObject::GetParagraphCount() const
821 return aContents.Count();
824 XubString BinTextObject::GetText( USHORT nPara ) const
826 DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
827 if ( nPara < aContents.Count() )
829 ContentInfo* pC = aContents[ nPara ];
830 return pC->GetText();
832 return XubString();
835 void BinTextObject::Insert( const EditTextObject& rObj, USHORT nDestPara )
837 DBG_ASSERT( rObj.Which() == EE_FORMAT_BIN, "UTO: Unbekanntes Textobjekt" );
839 const BinTextObject& rBinObj = (const BinTextObject&)rObj;
841 if ( nDestPara > aContents.Count() )
842 nDestPara = aContents.Count();
844 const USHORT nParas = rBinObj.GetContents().Count();
845 for ( USHORT nP = 0; nP < nParas; nP++ )
847 ContentInfo* pC = rBinObj.GetContents()[ nP ];
848 ContentInfo* pNew = new ContentInfo( *pC, *GetPool() );
849 aContents.Insert( pNew, nDestPara+nP );
851 ClearPortionInfo();
854 EditTextObject* BinTextObject::CreateTextObject( USHORT nPara, USHORT nParas ) const
856 if ( ( nPara >= aContents.Count() ) || !nParas )
857 return NULL;
859 // Pool nur teilen, wenn von aussen eingestellter Pool.
860 BinTextObject* pObj = new BinTextObject( bOwnerOfPool ? 0 : pPool );
861 if ( bOwnerOfPool && pPool )
862 pObj->GetPool()->SetDefaultMetric( pPool->GetMetric( DEF_METRIC ) );
864 // If complete text is only one ScriptType, this is valid.
865 // If text contains different ScriptTypes, this shouldn't be a problem...
866 pObj->nScriptType = nScriptType;
868 const USHORT nEndPara = nPara+nParas-1;
869 for ( USHORT nP = nPara; nP <= nEndPara; nP++ )
871 ContentInfo* pC = aContents[ nP ];
872 ContentInfo* pNew = new ContentInfo( *pC, *pObj->GetPool() );
873 pObj->GetContents().Insert( pNew, pObj->GetContents().Count() );
875 return pObj;
878 void BinTextObject::RemoveParagraph( USHORT nPara )
880 DBG_ASSERT( nPara < aContents.Count(), "BinTextObject::GetText: Absatz existiert nicht!" );
881 if ( nPara < aContents.Count() )
883 ContentInfo* pC = aContents[ nPara ];
884 aContents.Remove( nPara );
885 delete pC;
886 ClearPortionInfo();
890 BOOL BinTextObject::HasPortionInfo() const
892 return pPortionInfo ? TRUE : FALSE;
895 void BinTextObject::ClearPortionInfo()
897 if ( pPortionInfo )
899 for ( USHORT n = pPortionInfo->Count(); n; )
900 delete pPortionInfo->GetObject( --n );
901 delete pPortionInfo;
902 pPortionInfo = NULL;
906 BOOL BinTextObject::HasOnlineSpellErrors() const
908 #ifndef SVX_LIGHT
909 for ( USHORT n = 0; n < aContents.Count(); n++ )
911 ContentInfo* p = aContents.GetObject( n );
912 if ( p->GetWrongList() && p->GetWrongList()->Count() )
913 return TRUE;
915 #endif // !SVX_LIGHT
916 return FALSE;
920 BOOL BinTextObject::HasCharAttribs( USHORT _nWhich ) const
922 for ( USHORT nPara = GetContents().Count(); nPara; )
924 ContentInfo* pC = GetContents().GetObject( --nPara );
926 USHORT nAttribs = pC->GetAttribs().Count();
927 if ( nAttribs && !_nWhich )
928 return TRUE;
930 for ( USHORT nAttr = nAttribs; nAttr; )
932 XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
933 if ( pX->GetItem()->Which() == _nWhich )
934 return TRUE;
937 return FALSE;
940 void BinTextObject::GetCharAttribs( USHORT nPara, EECharAttribArray& rLst ) const
942 rLst.Remove( 0, rLst.Count() );
943 ContentInfo* pC = GetContents().GetObject( nPara );
944 if ( pC )
946 for ( USHORT nAttr = 0; nAttr < pC->GetAttribs().Count(); nAttr++ )
948 XEditAttribute* pAttr = pC->GetAttribs().GetObject( nAttr );
949 EECharAttrib aEEAttr;
950 aEEAttr.pAttr = pAttr->GetItem();
951 aEEAttr.nPara = nPara;
952 aEEAttr.nStart = pAttr->GetStart();
953 aEEAttr.nEnd = pAttr->GetEnd();
954 rLst.Insert( aEEAttr, rLst.Count() );
959 void BinTextObject::MergeParaAttribs( const SfxItemSet& rAttribs, USHORT nStart, USHORT nEnd )
961 BOOL bChanged = FALSE;
963 for ( USHORT nPara = GetContents().Count(); nPara; )
965 ContentInfo* pC = GetContents().GetObject( --nPara );
967 for ( USHORT nW = nStart; nW <= nEnd; nW++ )
969 if ( ( pC->GetParaAttribs().GetItemState( nW, FALSE ) != SFX_ITEM_ON )
970 && ( rAttribs.GetItemState( nW, FALSE ) == SFX_ITEM_ON ) )
972 pC->GetParaAttribs().Put( rAttribs.Get( nW ) );
973 bChanged = TRUE;
978 if ( bChanged )
979 ClearPortionInfo();
982 BOOL BinTextObject::IsFieldObject() const
984 return BinTextObject::GetField() ? TRUE : FALSE;
987 const SvxFieldItem* BinTextObject::GetField() const
989 if ( GetContents().Count() == 1 )
991 ContentInfo* pC = GetContents()[0];
992 if ( pC->GetText().Len() == 1 )
994 USHORT nAttribs = pC->GetAttribs().Count();
995 for ( USHORT nAttr = nAttribs; nAttr; )
997 XEditAttribute* pX = pC->GetAttribs().GetObject( --nAttr );
998 if ( pX->GetItem()->Which() == EE_FEATURE_FIELD )
999 return (const SvxFieldItem*)pX->GetItem();
1003 return 0;
1006 BOOL BinTextObject::HasField( TypeId aType ) const
1008 USHORT nParagraphs = GetContents().Count();
1009 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1011 ContentInfo* pC = GetContents().GetObject( nPara );
1012 USHORT nAttrs = pC->GetAttribs().Count();
1013 for ( USHORT nAttr = 0; nAttr < nAttrs; nAttr++ )
1015 XEditAttribute* pAttr = pC->GetAttribs()[nAttr];
1016 if ( pAttr->GetItem()->Which() == EE_FEATURE_FIELD )
1018 if ( !aType )
1019 return TRUE;
1021 const SvxFieldData* pFldData = ((const SvxFieldItem*)pAttr->GetItem())->GetField();
1022 if ( pFldData && pFldData->IsA( aType ) )
1023 return TRUE;
1027 return FALSE;
1030 SfxItemSet BinTextObject::GetParaAttribs( USHORT nPara ) const
1032 ContentInfo* pC = GetContents().GetObject( nPara );
1033 return pC->GetParaAttribs();
1036 void BinTextObject::SetParaAttribs( USHORT nPara, const SfxItemSet& rAttribs )
1038 ContentInfo* pC = GetContents().GetObject( nPara );
1039 pC->GetParaAttribs().Set( rAttribs );
1040 ClearPortionInfo();
1043 BOOL BinTextObject::RemoveCharAttribs( USHORT _nWhich )
1045 BOOL bChanged = FALSE;
1047 for ( USHORT nPara = GetContents().Count(); nPara; )
1049 ContentInfo* pC = GetContents().GetObject( --nPara );
1051 for ( USHORT nAttr = pC->GetAttribs().Count(); nAttr; )
1053 XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
1054 if ( !_nWhich || ( pAttr->GetItem()->Which() == _nWhich ) )
1056 pC->GetAttribs().Remove( nAttr );
1057 DestroyAttrib( pAttr );
1058 bChanged = TRUE;
1063 if ( bChanged )
1064 ClearPortionInfo();
1066 return bChanged;
1069 BOOL BinTextObject::RemoveParaAttribs( USHORT _nWhich )
1071 BOOL bChanged = FALSE;
1073 for ( USHORT nPara = GetContents().Count(); nPara; )
1075 ContentInfo* pC = GetContents().GetObject( --nPara );
1077 if ( !_nWhich )
1079 if( pC->GetParaAttribs().Count() )
1080 bChanged = TRUE;
1081 pC->GetParaAttribs().ClearItem();
1083 else
1085 if ( pC->GetParaAttribs().GetItemState( _nWhich ) == SFX_ITEM_ON )
1087 pC->GetParaAttribs().ClearItem( _nWhich );
1088 bChanged = TRUE;
1093 if ( bChanged )
1094 ClearPortionInfo();
1096 return bChanged;
1099 BOOL BinTextObject::HasStyleSheet( const XubString& rName, SfxStyleFamily eFamily ) const
1101 USHORT nParagraphs = GetContents().Count();
1102 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1104 ContentInfo* pC = GetContents().GetObject( nPara );
1105 if ( ( pC->GetFamily() == eFamily ) && ( pC->GetStyle() == rName ) )
1106 return TRUE;
1108 return FALSE;
1111 void BinTextObject::GetStyleSheet( USHORT nPara, XubString& rName, SfxStyleFamily& rFamily ) const
1113 if ( nPara < aContents.Count() )
1115 ContentInfo* pC = aContents[ nPara ];
1116 rName = pC->GetStyle();
1117 rFamily = pC->GetFamily();
1121 void BinTextObject::SetStyleSheet( USHORT nPara, const XubString& rName, const SfxStyleFamily& rFamily )
1123 if ( nPara < aContents.Count() )
1125 ContentInfo* pC = aContents[ nPara ];
1126 pC->GetStyle() = rName;
1127 pC->GetFamily() = rFamily;
1131 BOOL BinTextObject::ImpChangeStyleSheets(
1132 const XubString& rOldName, SfxStyleFamily eOldFamily,
1133 const XubString& rNewName, SfxStyleFamily eNewFamily )
1135 const USHORT nParagraphs = GetContents().Count();
1136 BOOL bChanges = FALSE;
1138 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1140 ContentInfo* pC = GetContents().GetObject( nPara );
1141 if ( pC->GetFamily() == eOldFamily )
1143 if ( pC->GetStyle() == rOldName )
1145 pC->GetStyle() = rNewName;
1146 pC->GetFamily() = eNewFamily;
1147 bChanges = TRUE;
1151 return bChanges;
1154 BOOL __EXPORT BinTextObject::ChangeStyleSheets(
1155 const XubString& rOldName, SfxStyleFamily eOldFamily,
1156 const XubString& rNewName, SfxStyleFamily eNewFamily )
1158 BOOL bChanges = ImpChangeStyleSheets( rOldName, eOldFamily, rNewName, eNewFamily );
1159 if ( bChanges )
1160 ClearPortionInfo();
1162 return bChanges;
1165 void __EXPORT BinTextObject::ChangeStyleSheetName( SfxStyleFamily eFamily,
1166 const XubString& rOldName, const XubString& rNewName )
1168 ImpChangeStyleSheets( rOldName, eFamily, rNewName, eFamily );
1171 void __EXPORT BinTextObject::StoreData( SvStream& rOStream ) const
1173 USHORT nVer = 602;
1174 rOStream << nVer;
1176 rOStream << bOwnerOfPool;
1178 // Erst den Pool speichern, spaeter nur noch Surregate
1179 if ( bOwnerOfPool )
1181 GetPool()->SetFileFormatVersion( SOFFICE_FILEFORMAT_50 );
1182 GetPool()->Store( rOStream );
1185 // Aktuelle Zeichensatz speichern...
1186 // #90477# GetSOStoreTextEncoding: Bug in 5.2, when default char set is multi byte text encoding
1187 rtl_TextEncoding eEncoding = GetSOStoreTextEncoding( gsl_getSystemTextEncoding(), (USHORT) rOStream.GetVersion() );
1188 rOStream << (USHORT) eEncoding;
1190 // Die Anzahl der Absaetze...
1191 USHORT nParagraphs = GetContents().Count();
1192 rOStream << nParagraphs;
1194 char cFeatureConverted = ByteString( CH_FEATURE, eEncoding ).GetChar(0);
1196 // Die einzelnen Absaetze...
1197 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1199 ContentInfo* pC = GetContents().GetObject( nPara );
1201 // Text...
1202 ByteString aText( pC->GetText(), eEncoding );
1204 // Symbols?
1205 BOOL bSymbolPara = FALSE;
1206 if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
1208 const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
1209 if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
1211 aText = ByteString( pC->GetText(), RTL_TEXTENCODING_SYMBOL );
1212 bSymbolPara = TRUE;
1215 for ( USHORT nA = 0; nA < pC->GetAttribs().Count(); nA++ )
1217 XEditAttribute* pAttr = pC->GetAttribs().GetObject( nA );
1219 if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
1221 const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
1222 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
1223 || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
1225 // Not correctly converted
1226 String aPart( pC->GetText(), pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
1227 ByteString aNew( aPart, rFontItem.GetCharSet() );
1228 aText.Erase( pAttr->GetStart(), pAttr->GetEnd() - pAttr->GetStart() );
1229 aText.Insert( aNew, pAttr->GetStart() );
1232 // #88414# Convert StarSymbol back to StarBats
1233 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
1234 if ( hConv )
1236 // Don't create a new Attrib with StarBats font, MBR changed the
1237 // SvxFontItem::Store() to store StarBats instead of StarSymbol!
1238 for ( USHORT nChar = pAttr->GetStart(); nChar < pAttr->GetEnd(); nChar++ )
1240 sal_Unicode cOld = pC->GetText().GetChar( nChar );
1241 char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
1242 if ( cConv )
1243 aText.SetChar( nChar, cConv );
1246 DestroyFontToSubsFontConverter( hConv );
1251 // #88414# Convert StarSymbol back to StarBats
1252 // StarSymbol as paragraph attribute or in StyleSheet?
1254 FontToSubsFontConverter hConv = NULL;
1255 if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
1257 hConv = CreateFontToSubsFontConverter( ((const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO )).GetFamilyName(), FONTTOSUBSFONT_EXPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
1259 /* cl removed because not needed anymore since binfilter
1261 else if ( pC->GetStyle().Len() && pC->GetLoadStoreTempInfos() )
1263 hConv = pC->GetLoadStoreTempInfos()->hOldSymbolConv_Store;
1266 if ( hConv )
1268 for ( USHORT nChar = 0; nChar < pC->GetText().Len(); nChar++ )
1270 if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
1272 sal_Unicode cOld = pC->GetText().GetChar( nChar );
1273 char cConv = ByteString::ConvertFromUnicode( ConvertFontToSubsFontChar( hConv, cOld ), RTL_TEXTENCODING_SYMBOL );
1274 if ( cConv )
1275 aText.SetChar( nChar, cConv );
1279 DestroyFontToSubsFontConverter( hConv );
1284 // Convert CH_FEATURE to CH_FEATURE_OLD
1285 aText.SearchAndReplaceAll( cFeatureConverted, CH_FEATURE_OLD );
1286 rOStream.WriteByteString( aText );
1288 // StyleName und Family...
1289 rOStream.WriteByteString( ByteString( pC->GetStyle(), eEncoding ) );
1290 rOStream << (USHORT)pC->GetFamily();
1292 // Absatzattribute...
1293 pC->GetParaAttribs().Store( rOStream );
1295 // Die Anzahl der Attribute...
1296 USHORT nAttribs = pC->GetAttribs().Count();
1297 rOStream << nAttribs;
1299 // Und die einzelnen Attribute
1300 // Items als Surregate => immer 8 Byte pro Attrib
1301 // Which = 2; Surregat = 2; Start = 2; End = 2;
1302 for ( USHORT nAttr = 0; nAttr < nAttribs; nAttr++ )
1304 XEditAttribute* pX = pC->GetAttribs().GetObject( nAttr );
1306 rOStream << pX->GetItem()->Which();
1307 GetPool()->StoreSurrogate( rOStream, pX->GetItem() );
1308 rOStream << pX->GetStart();
1309 rOStream << pX->GetEnd();
1313 // Ab 400:
1314 rOStream << nMetric;
1316 // Ab 600
1317 rOStream << nUserType;
1318 rOStream << nObjSettings;
1320 // Ab 601
1321 rOStream << bVertical;
1323 // Ab 602
1324 rOStream << nScriptType;
1326 rOStream << bStoreUnicodeStrings;
1327 if ( bStoreUnicodeStrings )
1329 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1331 ContentInfo* pC = GetContents().GetObject( nPara );
1332 USHORT nL = pC->GetText().Len();
1333 rOStream << nL;
1334 rOStream.Write( pC->GetText().GetBuffer(), nL*sizeof(sal_Unicode) );
1336 // #91575# StyleSheetName must be Unicode too!
1337 // Copy/Paste from EA3 to BETA or from BETA to EA3 not possible, not needed...
1338 // If needed, change nL back to ULONG and increase version...
1339 nL = pC->GetStyle().Len();
1340 rOStream << nL;
1341 rOStream.Write( pC->GetStyle().GetBuffer(), nL*sizeof(sal_Unicode) );
1346 void __EXPORT BinTextObject::CreateData( SvStream& rIStream )
1348 rIStream >> nVersion;
1350 // Das Textobject wurde erstmal mit der aktuellen Einstellung
1351 // von pTextObjectPool erzeugt.
1352 BOOL bOwnerOfCurrent = bOwnerOfPool;
1353 rIStream >> bOwnerOfPool;
1355 if ( bOwnerOfCurrent && !bOwnerOfPool )
1357 // Es wurde ein globaler Pool verwendet, mir jetzt nicht uebergeben,
1358 // aber ich brauche ihn!
1359 DBG_ERROR( "Man gebe mir den globalen TextObjectPool!" );
1360 return;
1362 else if ( !bOwnerOfCurrent && bOwnerOfPool )
1364 // Es soll ein globaler Pool verwendet werden, aber dieses
1365 // Textobject hat einen eigenen.
1366 pPool = EditEngine::CreatePool();
1369 if ( bOwnerOfPool )
1370 GetPool()->Load( rIStream );
1372 // CharSet, in dem gespeichert wurde:
1373 USHORT nCharSet;
1374 rIStream >> nCharSet;
1376 rtl_TextEncoding eSrcEncoding = GetSOLoadTextEncoding( (rtl_TextEncoding)nCharSet, (USHORT)rIStream.GetVersion() );
1378 // Die Anzahl der Absaetze...
1379 USHORT nParagraphs;
1380 rIStream >> nParagraphs;
1382 // Die einzelnen Absaetze...
1383 for ( ULONG nPara = 0; nPara < nParagraphs; nPara++ )
1385 ContentInfo* pC = CreateAndInsertContent();
1387 // Der Text...
1388 ByteString aByteString;
1389 rIStream.ReadByteString( aByteString );
1390 pC->GetText() = String( aByteString, eSrcEncoding );
1392 // StyleName und Family...
1393 rIStream.ReadByteString( pC->GetStyle(), eSrcEncoding );
1394 USHORT nStyleFamily;
1395 rIStream >> nStyleFamily;
1396 pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
1398 // Absatzattribute...
1399 pC->GetParaAttribs().Load( rIStream );
1401 // Die Anzahl der Attribute...
1402 USHORT nAttribs;
1403 rIStream >> nAttribs;
1405 // Und die einzelnen Attribute
1406 // Items als Surregate => immer 8 Byte pro Attrib
1407 // Which = 2; Surregat = 2; Start = 2; End = 2;
1408 USHORT nAttr;
1409 for ( nAttr = 0; nAttr < nAttribs; nAttr++ )
1411 USHORT _nWhich, nStart, nEnd;
1412 const SfxPoolItem* pItem;
1414 rIStream >> _nWhich;
1415 _nWhich = pPool->GetNewWhich( _nWhich );
1416 pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
1417 rIStream >> nStart;
1418 rIStream >> nEnd;
1419 if ( pItem )
1421 if ( pItem->Which() == EE_FEATURE_NOTCONV )
1423 pC->GetText().SetChar( nStart, ByteString::ConvertToUnicode( aByteString.GetChar( nStart ), ((SvxCharSetColorItem*)pItem)->GetCharSet() ) );
1425 else
1427 XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
1428 pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
1430 if ( ( _nWhich >= EE_FEATURE_START ) && ( _nWhich <= EE_FEATURE_END ) )
1432 // Convert CH_FEATURE to CH_FEATURE_OLD
1433 DBG_ASSERT( (BYTE) aByteString.GetChar( nStart ) == CH_FEATURE_OLD, "CreateData: CH_FEATURE expected!" );
1434 if ( (BYTE) aByteString.GetChar( nStart ) == CH_FEATURE_OLD )
1435 pC->GetText().SetChar( nStart, CH_FEATURE );
1441 // But check for paragraph and character symbol attribs here,
1442 // FinishLoad will not be called in OpenOffice Calc, no StyleSheets...
1444 BOOL bSymbolPara = FALSE;
1445 if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
1447 const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
1448 if ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL )
1450 pC->GetText() = String( aByteString, RTL_TEXTENCODING_SYMBOL );
1451 bSymbolPara = TRUE;
1455 for ( nAttr = pC->GetAttribs().Count(); nAttr; )
1457 XEditAttribute* pAttr = pC->GetAttribs().GetObject( --nAttr );
1458 if ( pAttr->GetItem()->Which() == EE_CHAR_FONTINFO )
1460 const SvxFontItem& rFontItem = (const SvxFontItem&)*pAttr->GetItem();
1461 if ( ( !bSymbolPara && ( rFontItem.GetCharSet() == RTL_TEXTENCODING_SYMBOL ) )
1462 || ( bSymbolPara && ( rFontItem.GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
1464 // Not correctly converted
1465 ByteString aPart( aByteString, pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
1466 String aNew( aPart, rFontItem.GetCharSet() );
1467 pC->GetText().Erase( pAttr->GetStart(), pAttr->GetEnd()-pAttr->GetStart() );
1468 pC->GetText().Insert( aNew, pAttr->GetStart() );
1471 // #88414# Convert StarMath and StarBats to StarSymbol
1472 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
1473 if ( hConv )
1475 SvxFontItem aNewFontItem( rFontItem );
1476 aNewFontItem.GetFamilyName() = GetFontToSubsFontName( hConv );
1478 pC->GetAttribs().Remove( nAttr );
1479 XEditAttribute* pNewAttr = CreateAttrib( aNewFontItem, pAttr->GetStart(), pAttr->GetEnd() );
1480 pC->GetAttribs().Insert( pNewAttr, nAttr );
1481 DestroyAttrib( pAttr );
1483 for ( USHORT nChar = pNewAttr->GetStart(); nChar < pNewAttr->GetEnd(); nChar++ )
1485 sal_Unicode cOld = pC->GetText().GetChar( nChar );
1486 DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
1487 sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
1488 if ( cConv )
1489 pC->GetText().SetChar( nChar, cConv );
1492 DestroyFontToSubsFontConverter( hConv );
1498 // #88414# Convert StarMath and StarBats to StarSymbol
1499 // Maybe old symbol font as paragraph attribute?
1500 if ( pC->GetParaAttribs().GetItemState( EE_CHAR_FONTINFO ) == SFX_ITEM_ON )
1502 const SvxFontItem& rFontItem = (const SvxFontItem&)pC->GetParaAttribs().Get( EE_CHAR_FONTINFO );
1503 FontToSubsFontConverter hConv = CreateFontToSubsFontConverter( rFontItem.GetFamilyName(), FONTTOSUBSFONT_IMPORT | FONTTOSUBSFONT_ONLYOLDSOSYMBOLFONTS );
1504 if ( hConv )
1506 SvxFontItem aNewFontItem( rFontItem );
1507 aNewFontItem.GetFamilyName() = GetFontToSubsFontName( hConv );
1508 pC->GetParaAttribs().Put( aNewFontItem );
1510 for ( USHORT nChar = 0; nChar < pC->GetText().Len(); nChar++ )
1512 if ( !pC->GetAttribs().FindAttrib( EE_CHAR_FONTINFO, nChar ) )
1514 sal_Unicode cOld = pC->GetText().GetChar( nChar );
1515 DBG_ASSERT( cOld >= 0xF000, "cOld not converted?!" );
1516 sal_Unicode cConv = ConvertFontToSubsFontChar( hConv, cOld );
1517 if ( cConv )
1518 pC->GetText().SetChar( nChar, cConv );
1522 DestroyFontToSubsFontConverter( hConv );
1527 // Ab 400 auch die DefMetric:
1528 if ( nVersion >= 400 )
1530 USHORT nTmpMetric;
1531 rIStream >> nTmpMetric;
1532 if ( nVersion >= 401 )
1534 // In der 400 gab es noch einen Bug bei Textobjekten mit eigenem
1535 // Pool, deshalb erst ab 401 auswerten.
1536 nMetric = nTmpMetric;
1537 if ( bOwnerOfPool && pPool && ( nMetric != 0xFFFF ) )
1538 pPool->SetDefaultMetric( (SfxMapUnit)nMetric );
1542 if ( nVersion >= 600 )
1544 rIStream >> nUserType;
1545 rIStream >> nObjSettings;
1548 if ( nVersion >= 601 )
1550 rIStream >> bVertical;
1553 if ( nVersion >= 602 )
1555 rIStream >> nScriptType;
1557 BOOL bUnicodeStrings;
1558 rIStream >> bUnicodeStrings;
1559 if ( bUnicodeStrings )
1561 for ( USHORT nPara = 0; nPara < nParagraphs; nPara++ )
1563 ContentInfo* pC = GetContents().GetObject( nPara );
1564 USHORT nL;
1566 // Text
1567 rIStream >> nL;
1568 if ( nL )
1570 pC->GetText().AllocBuffer( nL );
1571 rIStream.Read( pC->GetText().GetBufferAccess(), nL*sizeof(sal_Unicode) );
1572 pC->GetText().ReleaseBufferAccess( (USHORT)nL );
1575 // StyleSheetName
1576 rIStream >> nL;
1577 if ( nL )
1579 pC->GetStyle().AllocBuffer( nL );
1580 rIStream.Read( pC->GetStyle().GetBufferAccess(), nL*sizeof(sal_Unicode) );
1581 pC->GetStyle().ReleaseBufferAccess( (USHORT)nL );
1588 // Ab 500 werden die Tabs anders interpretiert: TabPos + LI, vorher nur TabPos.
1589 // Wirkt nur wenn auch Tab-Positionen eingestellt wurden, nicht beim DefTab.
1590 if ( nVersion < 500 )
1592 for ( USHORT n = 0; n < aContents.Count(); n++ )
1594 ContentInfo* pC = aContents.GetObject( n );
1595 const SvxLRSpaceItem& rLRSpace = (const SvxLRSpaceItem&) pC->GetParaAttribs().Get( EE_PARA_LRSPACE );
1596 if ( rLRSpace.GetTxtLeft() && ( pC->GetParaAttribs().GetItemState( EE_PARA_TABS ) == SFX_ITEM_ON ) )
1598 const SvxTabStopItem& rTabs = (const SvxTabStopItem&) pC->GetParaAttribs().Get( EE_PARA_TABS );
1599 SvxTabStopItem aNewTabs( 0, 0, SVX_TAB_ADJUST_LEFT, EE_PARA_TABS );
1600 for ( USHORT t = 0; t < rTabs.Count(); t++ )
1602 const SvxTabStop& rT = rTabs[ t ];
1603 aNewTabs.Insert( SvxTabStop( rT.GetTabPos() - rLRSpace.GetTxtLeft(),
1604 rT.GetAdjustment(), rT.GetDecimal(), rT.GetFill() ) );
1606 pC->GetParaAttribs().Put( aNewTabs );
1612 USHORT BinTextObject::GetVersion() const
1614 return nVersion;
1617 bool BinTextObject::operator==( const BinTextObject& rCompare ) const
1619 if( this == &rCompare )
1620 return true;
1622 if( ( aContents.Count() != rCompare.aContents.Count() ) ||
1623 ( pPool != rCompare.pPool ) ||
1624 ( nMetric != rCompare.nMetric ) ||
1625 ( nUserType!= rCompare.nUserType ) ||
1626 ( nScriptType != rCompare.nScriptType ) ||
1627 ( bVertical != rCompare.bVertical ) )
1628 return false;
1630 USHORT n;
1631 for( n = 0; n < aContents.Count(); n++ )
1633 if( !( *aContents.GetObject( n ) == *rCompare.aContents.GetObject( n ) ) )
1634 return false;
1637 return true;
1640 // #i102062#
1641 bool BinTextObject::isWrongListEqual(const BinTextObject& rCompare) const
1643 if(GetContents().Count() != rCompare.GetContents().Count())
1645 return false;
1648 for(USHORT a(0); a < GetContents().Count(); a++)
1650 const ContentInfo& rCandA(*GetContents().GetObject(a));
1651 const ContentInfo& rCandB(*rCompare.GetContents().GetObject(a));
1653 if(!rCandA.isWrongListEqual(rCandB))
1655 return false;
1659 return true;
1662 #define CHARSETMARKER 0x9999
1664 void __EXPORT BinTextObject::CreateData300( SvStream& rIStream )
1666 // Fuer Aufwaertskompatibilitaet.
1668 // Erst den Pool laden...
1669 // Ist in der 300 immer gespeichert worden!
1670 GetPool()->Load( rIStream );
1672 // Die Anzahl der Absaetze...
1673 sal_uInt32 nParagraphs;
1674 rIStream >> nParagraphs;
1676 // Die einzelnen Absaetze...
1677 for ( ULONG nPara = 0; nPara < nParagraphs; nPara++ )
1679 ContentInfo* pC = CreateAndInsertContent();
1681 // Der Text...
1682 rIStream.ReadByteString( pC->GetText() );
1684 // StyleName und Family...
1685 rIStream.ReadByteString( pC->GetStyle() );
1686 USHORT nStyleFamily;
1687 rIStream >> nStyleFamily;
1688 pC->GetFamily() = (SfxStyleFamily)nStyleFamily;
1690 // Absatzattribute...
1691 pC->GetParaAttribs().Load( rIStream );
1693 // Die Anzahl der Attribute...
1694 sal_uInt32 nAttribs;
1695 rIStream >> nAttribs;
1697 // Und die einzelnen Attribute
1698 // Items als Surregate => immer 8 Byte pro Attrib
1699 // Which = 2; Surregat = 2; Start = 2; End = 2;
1700 for ( ULONG nAttr = 0; nAttr < nAttribs; nAttr++ )
1702 USHORT _nWhich, nStart, nEnd;
1703 const SfxPoolItem* pItem;
1705 rIStream >> _nWhich;
1706 _nWhich = pPool->GetNewWhich( _nWhich );
1707 pItem = pPool->LoadSurrogate( rIStream, _nWhich, 0 );
1708 rIStream >> nStart;
1709 rIStream >> nEnd;
1710 if ( pItem )
1712 XEditAttribute* pAttr = new XEditAttribute( *pItem, nStart, nEnd );
1713 pC->GetAttribs().Insert( pAttr, pC->GetAttribs().Count() );
1718 // Prueffen, ob ein Zeichensatz gespeichert wurde
1719 USHORT nCharSetMarker;
1720 rIStream >> nCharSetMarker;
1721 if ( nCharSetMarker == CHARSETMARKER )
1723 USHORT nCharSet;
1724 rIStream >> nCharSet;