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