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