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 <svl/style.hxx>
21 :
22 : #include <com/sun/star/lang/XComponent.hpp>
23 :
24 : #include <sal/log.hxx>
25 : #include <tools/tenccvt.hxx>
26 : #include <osl/diagnose.h>
27 : #include <comphelper/processfactory.hxx>
28 : #include <unotools/intlwrapper.hxx>
29 : #include <svl/smplhint.hxx>
30 : #include <svl/poolitem.hxx>
31 : #include <svl/itemset.hxx>
32 : #include <svl/itempool.hxx>
33 : #include <svl/IndexedStyleSheets.hxx>
34 : #include <svl/itemiter.hxx>
35 : #include <unotools/syslocale.hxx>
36 : #include <algorithm>
37 : #include <comphelper/servicehelper.hxx>
38 :
39 : #include <string.h>
40 :
41 : #ifdef DBG_UTIL
42 : class DbgStyleSheetReferences
43 : {
44 : public:
45 : DbgStyleSheetReferences() : mnStyles(0), mnPools(0) {}
46 : ~DbgStyleSheetReferences()
47 : {
48 : SAL_WARN_IF(
49 : mnStyles != 0 || mnPools != 0, "svl.items",
50 : "SfxStyleSheetBase left " << mnStyles
51 : << "; SfxStyleSheetBasePool left " << mnPools);
52 : }
53 :
54 : sal_uInt32 mnStyles;
55 : sal_uInt32 mnPools;
56 : }
57 : aDbgStyleSheetReferences;
58 :
59 : #endif
60 :
61 0 : TYPEINIT0(SfxStyleSheetBase)
62 :
63 441840 : TYPEINIT3(SfxStyleSheet, SfxStyleSheetBase, SfxListener, SfxBroadcaster)
64 :
65 2069 : SfxStyleSheetHintExtended::SfxStyleSheetHintExtended
66 : (
67 : sal_uInt16 nAction, // SfxStyleSheetHintId::... (see above)
68 : const OUString& rOldName,
69 : SfxStyleSheetBase& rStyleSheet // Remains with the caller
70 : )
71 : : SfxStyleSheetHint( nAction, rStyleSheet ),
72 2069 : aName( rOldName )
73 2069 : {}
74 :
75 :
76 174400 : SfxStyleSheetHint::SfxStyleSheetHint
77 : (
78 : sal_uInt16 nAction, // SfxStyleSheetHintId::... (see above)
79 : SfxStyleSheetBase& rStyleSheet // Remains with the caller
80 : )
81 : : pStyleSh( &rStyleSheet ),
82 174400 : nHint( nAction )
83 174400 : {}
84 :
85 :
86 4554 : class SfxStyleSheetBasePool_Impl
87 : {
88 : private:
89 : SfxStyleSheetBasePool_Impl(const SfxStyleSheetBasePool_Impl&) SAL_DELETED_FUNCTION;
90 : SfxStyleSheetBasePool_Impl& operator=(const SfxStyleSheetBasePool_Impl&) SAL_DELETED_FUNCTION;
91 : public:
92 : SfxStyleSheetIteratorPtr pIter;
93 :
94 : /** This member holds the indexed style sheets.
95 : *
96 : * @internal
97 : * This member is private and not protected in order to have more control which style sheets are added
98 : * where. Ideally, all calls which add/remove/change style sheets are done in the base class.
99 : */
100 : std::shared_ptr<svl::IndexedStyleSheets> mxIndexedStyleSheets;
101 :
102 4597 : SfxStyleSheetBasePool_Impl() :
103 4597 : mxIndexedStyleSheets(new svl::IndexedStyleSheets) {}
104 : };
105 :
106 :
107 74131 : SfxStyleSheetBase::SfxStyleSheetBase( const OUString& rName, SfxStyleSheetBasePool* p, SfxStyleFamily eFam, sal_uInt16 mask )
108 : : pPool( p )
109 : , nFamily( eFam )
110 : , aName( rName )
111 : , aParent()
112 : , aFollow( rName )
113 : , pSet( NULL )
114 : , nMask(mask)
115 : , nHelpId( 0 )
116 : , bMySet( false )
117 74131 : , bHidden( false )
118 : {
119 : #ifdef DBG_UTIL
120 : aDbgStyleSheetReferences.mnStyles++;
121 : #endif
122 74131 : }
123 :
124 497167 : SfxStyleSheetBase::SfxStyleSheetBase( const SfxStyleSheetBase& r )
125 : : comphelper::OWeakTypeObject()
126 : , pPool( r.pPool )
127 : , nFamily( r.nFamily )
128 : , aName( r.aName )
129 : , aParent( r.aParent )
130 : , aFollow( r.aFollow )
131 : , aHelpFile( r.aHelpFile )
132 : , nMask( r.nMask )
133 : , nHelpId( r.nHelpId )
134 : , bMySet( r.bMySet )
135 497167 : , bHidden( r.bHidden )
136 : {
137 : #ifdef DBG_UTIL
138 : aDbgStyleSheetReferences.mnStyles++;
139 : #endif
140 497167 : if( r.pSet )
141 0 : pSet = bMySet ? new SfxItemSet( *r.pSet ) : r.pSet;
142 : else
143 497167 : pSet = NULL;
144 497167 : }
145 :
146 1141644 : SfxStyleSheetBase::~SfxStyleSheetBase()
147 : {
148 : #ifdef DBG_UTIL
149 : --aDbgStyleSheetReferences.mnStyles;
150 : #endif
151 :
152 570822 : if( bMySet )
153 : {
154 5567 : delete pSet;
155 5567 : pSet = 0;
156 : }
157 570822 : }
158 :
159 : // Change name
160 2239842 : const OUString& SfxStyleSheetBase::GetName() const
161 : {
162 2239842 : return aName;
163 : }
164 :
165 2069 : bool SfxStyleSheetBase::SetName(const OUString& rName, bool bReIndexNow)
166 : {
167 2069 : if(rName.isEmpty())
168 0 : return false;
169 :
170 2069 : if( aName != rName )
171 : {
172 2069 : OUString aOldName = aName;
173 2069 : SfxStyleSheetBase *pOther = pPool->Find( rName, nFamily ) ;
174 2069 : if ( pOther && pOther != this )
175 0 : return false;
176 :
177 2069 : SfxStyleFamily eTmpFam = pPool->GetSearchFamily();
178 2069 : sal_uInt16 nTmpMask = pPool->GetSearchMask();
179 :
180 2069 : pPool->SetSearchMask(nFamily);
181 :
182 2069 : if ( !aName.isEmpty() )
183 2069 : pPool->ChangeParent( aName, rName, false );
184 :
185 2069 : if ( aFollow == aName )
186 2061 : aFollow = rName;
187 2069 : aName = rName;
188 2069 : if (bReIndexNow)
189 2069 : pPool->Reindex();
190 2069 : pPool->SetSearchMask(eTmpFam, nTmpMask);
191 : pPool->Broadcast( SfxStyleSheetHintExtended(
192 2069 : SfxStyleSheetHintId::MODIFIED, aOldName, *this ) );
193 : }
194 2069 : return true;
195 : }
196 :
197 2401 : OUString SfxStyleSheetBase::GetDisplayName() const
198 : {
199 2401 : if( maDisplayName.isEmpty() )
200 : {
201 2401 : return aName;
202 : }
203 : else
204 : {
205 0 : return maDisplayName;
206 : }
207 : }
208 :
209 : // Change Parent
210 71220 : const OUString& SfxStyleSheetBase::GetParent() const
211 : {
212 71220 : return aParent;
213 : }
214 :
215 21500 : bool SfxStyleSheetBase::SetParent( const OUString& rName )
216 : {
217 21500 : if ( rName == aName )
218 0 : return false;
219 :
220 21500 : if( aParent != rName )
221 : {
222 21500 : SfxStyleSheetBase* pIter = pPool->Find(rName, nFamily);
223 21500 : if( !rName.isEmpty() && !pIter )
224 : {
225 : OSL_FAIL( "StyleSheet-Parent not found" );
226 0 : return false;
227 : }
228 : // prevent recursive linkages
229 21500 : if( !aName.isEmpty() )
230 : {
231 80642 : while(pIter)
232 : {
233 37642 : if(pIter->GetName() == aName)
234 0 : return false;
235 37642 : pIter = pPool->Find(pIter->GetParent(), nFamily);
236 : }
237 : }
238 21500 : aParent = rName;
239 : }
240 21500 : pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
241 21500 : return true;
242 : }
243 :
244 1389 : void SfxStyleSheetBase::SetHidden( bool hidden )
245 : {
246 1389 : bHidden = hidden;
247 1389 : pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
248 1389 : }
249 :
250 : /**
251 : * Change follow
252 : */
253 4157 : const OUString& SfxStyleSheetBase::GetFollow() const
254 : {
255 4157 : return aFollow;
256 : }
257 :
258 5706 : bool SfxStyleSheetBase::SetFollow( const OUString& rName )
259 : {
260 5706 : if( aFollow != rName )
261 : {
262 5697 : if( !pPool->Find( rName, nFamily ) )
263 : {
264 : SAL_WARN( "svl", "StyleSheet-Follow not found" );
265 1322 : return false;
266 : }
267 4375 : aFollow = rName;
268 : }
269 4384 : pPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::MODIFIED, *this ) );
270 4384 : return true;
271 : }
272 :
273 : /**
274 : * Set Itemset
275 : * The default implementation creates a new set
276 : */
277 0 : SfxItemSet& SfxStyleSheetBase::GetItemSet()
278 : {
279 0 : if( !pSet )
280 : {
281 0 : pSet = new SfxItemSet( pPool->GetPool() );
282 0 : bMySet = true;
283 : }
284 0 : return *pSet;
285 : }
286 :
287 : /**
288 : * Set help file and ID and return it
289 : */
290 1374 : sal_uLong SfxStyleSheetBase::GetHelpId( OUString& rFile )
291 : {
292 1374 : rFile = aHelpFile;
293 1374 : return nHelpId;
294 : }
295 :
296 15934 : void SfxStyleSheetBase::SetHelpId( const OUString& rFile, sal_uLong nId )
297 : {
298 15934 : aHelpFile = rFile;
299 15934 : nHelpId = nId;
300 15934 : }
301 :
302 : /**
303 : * Next style possible?
304 : * Default: Yes
305 : */
306 0 : bool SfxStyleSheetBase::HasFollowSupport() const
307 : {
308 0 : return true;
309 : }
310 :
311 : /**
312 : * Base template possible?
313 : * Default: Yes
314 : */
315 0 : bool SfxStyleSheetBase::HasParentSupport() const
316 : {
317 0 : return true;
318 : }
319 :
320 : /**
321 : * Setting base template to NULL possible?
322 : * Default: No
323 : */
324 0 : bool SfxStyleSheetBase::HasClearParentSupport() const
325 : {
326 0 : return false;
327 : }
328 :
329 : /**
330 : * By default all stylesheets are set to used
331 : */
332 0 : bool SfxStyleSheetBase::IsUsed() const
333 : {
334 0 : return true;
335 : }
336 :
337 : /**
338 : * Return set attributes
339 : */
340 0 : OUString SfxStyleSheetBase::GetDescription()
341 : {
342 0 : return GetDescription( SFX_MAPUNIT_CM );
343 : }
344 :
345 : /**
346 : * Return set attributes
347 : */
348 0 : OUString SfxStyleSheetBase::GetDescription( SfxMapUnit eMetric )
349 : {
350 0 : SfxItemIter aIter( GetItemSet() );
351 0 : OUString aDesc;
352 0 : const SfxPoolItem* pItem = aIter.FirstItem();
353 :
354 0 : IntlWrapper aIntlWrapper( SvtSysLocale().GetLanguageTag() );
355 0 : while ( pItem )
356 : {
357 0 : OUString aItemPresentation;
358 :
359 0 : if ( !IsInvalidItem( pItem ) &&
360 0 : pPool->GetPool().GetPresentation(
361 0 : *pItem, eMetric, aItemPresentation, &aIntlWrapper ) )
362 : {
363 0 : if ( !aDesc.isEmpty() && !aItemPresentation.isEmpty() )
364 0 : aDesc += " + ";
365 0 : if ( !aItemPresentation.isEmpty() )
366 0 : aDesc += aItemPresentation;
367 : }
368 0 : pItem = aIter.NextItem();
369 0 : }
370 0 : return aDesc;
371 : }
372 :
373 1099757 : SfxStyleFamily SfxStyleSheetIterator::GetSearchFamily() const
374 : {
375 1099757 : return nSearchFamily;
376 : }
377 :
378 89290 : inline bool SfxStyleSheetIterator::IsTrivialSearch()
379 : {
380 178580 : return (( nMask & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE) &&
381 178580 : (GetSearchFamily() == SFX_STYLE_FAMILY_ALL);
382 : }
383 :
384 : namespace {
385 :
386 338119 : struct DoesStyleMatchStyleSheetPredicate SAL_FINAL : public svl::StyleSheetPredicate
387 : {
388 338119 : explicit DoesStyleMatchStyleSheetPredicate(SfxStyleSheetIterator *it)
389 338119 : : mIterator(it) {;}
390 :
391 : bool
392 289813 : Check(const SfxStyleSheetBase& styleSheet) SAL_OVERRIDE
393 : {
394 579626 : bool bMatchFamily = ((mIterator->GetSearchFamily() == SFX_STYLE_FAMILY_ALL) ||
395 579626 : ( styleSheet.GetFamily() == mIterator->GetSearchFamily() ));
396 :
397 289813 : bool bUsed = mIterator->SearchUsed() && styleSheet.IsUsed( );
398 :
399 289813 : bool bSearchHidden = ( mIterator->GetSearchMask() & SFXSTYLEBIT_HIDDEN );
400 289813 : bool bMatchVisibility = !( !bSearchHidden && styleSheet.IsHidden() && !bUsed );
401 289813 : bool bOnlyHidden = mIterator->GetSearchMask( ) == SFXSTYLEBIT_HIDDEN && styleSheet.IsHidden( );
402 :
403 256742 : bool bMatches = bMatchFamily && bMatchVisibility
404 800525 : && (( styleSheet.GetMask() & ( mIterator->GetSearchMask() & ~SFXSTYLEBIT_USED )) ||
405 144212 : bUsed || bOnlyHidden ||
406 361919 : ( mIterator->GetSearchMask() & SFXSTYLEBIT_ALL_VISIBLE ) == SFXSTYLEBIT_ALL_VISIBLE );
407 289813 : return bMatches;
408 : }
409 :
410 : SfxStyleSheetIterator *mIterator;
411 : };
412 :
413 : }
414 :
415 370296 : SfxStyleSheetIterator::SfxStyleSheetIterator(SfxStyleSheetBasePool *pBase,
416 : SfxStyleFamily eFam, sal_uInt16 n)
417 : : pAktStyle(NULL)
418 370296 : , nAktPosition(0)
419 : {
420 370296 : pBasePool=pBase;
421 370296 : nSearchFamily=eFam;
422 370296 : bSearchUsed=false;
423 370296 : if( (( n & SFXSTYLEBIT_ALL_VISIBLE ) != SFXSTYLEBIT_ALL_VISIBLE )
424 30391 : && ((n & SFXSTYLEBIT_USED) == SFXSTYLEBIT_USED))
425 : {
426 11997 : bSearchUsed = true;
427 11997 : n &= ~SFXSTYLEBIT_USED;
428 : }
429 370296 : nMask=n;
430 370296 : }
431 :
432 371646 : SfxStyleSheetIterator::~SfxStyleSheetIterator()
433 : {
434 371646 : }
435 :
436 11463 : sal_uInt16 SfxStyleSheetIterator::Count()
437 : {
438 11463 : sal_uInt16 n = 0;
439 11463 : if( IsTrivialSearch())
440 : {
441 17 : n = (sal_uInt16) pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheets();
442 : }
443 11446 : else if(nMask == SFXSTYLEBIT_ALL)
444 : {
445 11446 : n = static_cast<sal_uInt16>(pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).size());
446 : }
447 : else
448 : {
449 0 : DoesStyleMatchStyleSheetPredicate predicate(this);
450 0 : n = pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheetsWithPredicate(predicate);
451 : }
452 11463 : return n;
453 : }
454 :
455 11172 : SfxStyleSheetBase* SfxStyleSheetIterator::operator[](sal_uInt16 nIdx)
456 : {
457 11172 : SfxStyleSheetBase* retval = NULL;
458 11172 : if( IsTrivialSearch())
459 : {
460 15 : retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(nIdx).get();
461 15 : nAktPosition = nIdx;
462 : }
463 11157 : else if(nMask == SFXSTYLEBIT_ALL)
464 : {
465 : rtl::Reference< SfxStyleSheetBase > ref =
466 : pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(
467 11157 : pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily).at(nIdx))
468 : ;
469 11157 : retval = ref.get();
470 11157 : nAktPosition = nIdx;
471 : }
472 : else
473 : {
474 0 : DoesStyleMatchStyleSheetPredicate predicate(this);
475 : rtl::Reference< SfxStyleSheetBase > ref =
476 0 : pBasePool->pImp->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(nIdx, predicate);
477 0 : if (ref.get() != NULL)
478 : {
479 0 : nAktPosition = pBasePool->pImp->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
480 0 : retval = ref.get();
481 0 : }
482 : }
483 :
484 : if (retval == NULL)
485 : {
486 : OSL_FAIL("Incorrect index");
487 : }
488 :
489 11172 : return retval;
490 : }
491 :
492 10300 : SfxStyleSheetBase* SfxStyleSheetIterator::First()
493 : {
494 10300 : if (Count() != 0) {
495 10282 : return operator[](0);
496 : }
497 : else {
498 18 : return NULL;
499 : }
500 : }
501 :
502 :
503 66655 : SfxStyleSheetBase* SfxStyleSheetIterator::Next()
504 : {
505 66655 : SfxStyleSheetBase* retval = NULL;
506 :
507 66655 : if ( IsTrivialSearch() )
508 : {
509 1030 : unsigned nStyleSheets = pBasePool->pImp->mxIndexedStyleSheets->GetNumberOfStyleSheets();
510 1030 : unsigned newPosition = nAktPosition +1;
511 1030 : if (nStyleSheets > newPosition)
512 : {
513 1015 : nAktPosition = newPosition;
514 1015 : retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(nAktPosition).get();
515 : }
516 : }
517 65625 : else if(nMask == SFXSTYLEBIT_ALL)
518 : {
519 65625 : unsigned newPosition = nAktPosition +1;
520 : const std::vector<unsigned>& familyVector =
521 65625 : pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetPositionsByFamily(nSearchFamily);
522 65625 : if (familyVector.size() > newPosition)
523 : {
524 62934 : nAktPosition = newPosition;
525 62934 : unsigned stylePosition = familyVector.at(newPosition);
526 62934 : retval = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(stylePosition).get();
527 : }
528 : }
529 : else
530 : {
531 0 : DoesStyleMatchStyleSheetPredicate predicate(this);
532 : rtl::Reference< SfxStyleSheetBase > ref =
533 : pBasePool->pImp->mxIndexedStyleSheets->GetNthStyleSheetThatMatchesPredicate(
534 0 : 0, predicate, nAktPosition+1);
535 0 : retval = ref.get();
536 0 : if (retval != NULL) {
537 0 : nAktPosition = pBasePool->pImp->mxIndexedStyleSheets->FindStyleSheetPosition(*ref);
538 0 : }
539 : }
540 66655 : pAktStyle = retval;
541 66655 : return retval;
542 : }
543 :
544 338119 : SfxStyleSheetBase* SfxStyleSheetIterator::Find(const OUString& rStr)
545 : {
546 338119 : DoesStyleMatchStyleSheetPredicate predicate(this);
547 :
548 : std::vector<unsigned> positions =
549 : pBasePool->pImp->mxIndexedStyleSheets->FindPositionsByNameAndPredicate(rStr, predicate,
550 676238 : svl::IndexedStyleSheets::RETURN_FIRST);
551 338119 : if (positions.empty()) {
552 84149 : return NULL;
553 : }
554 :
555 253970 : unsigned pos = positions.front();
556 253970 : SfxStyleSheetBase* pStyle = pBasePool->pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(pos).get();
557 253970 : nAktPosition = pos;
558 253970 : pAktStyle = pStyle;
559 592089 : return pAktStyle;
560 : }
561 :
562 1348717 : sal_uInt16 SfxStyleSheetIterator::GetSearchMask() const
563 : {
564 1348717 : sal_uInt16 mask = nMask;
565 :
566 1348717 : if ( bSearchUsed )
567 29751 : mask |= SFXSTYLEBIT_USED;
568 1348717 : return mask;
569 : }
570 :
571 :
572 0 : void SfxStyleSheetBasePool::Replace( SfxStyleSheetBase& rSource, SfxStyleSheetBase& rTarget )
573 : {
574 0 : rTarget.SetFollow( rSource.GetFollow() );
575 0 : rTarget.SetParent( rSource.GetParent() );
576 0 : SfxItemSet& rSourceSet = rSource.GetItemSet();
577 0 : SfxItemSet& rTargetSet = rTarget.GetItemSet();
578 0 : rTargetSet.Intersect( rSourceSet );
579 0 : rTargetSet.Put( rSourceSet );
580 0 : }
581 :
582 442516 : SfxStyleSheetIterator& SfxStyleSheetBasePool::GetIterator_Impl()
583 : {
584 442516 : if( !pImp->pIter || (pImp->pIter->GetSearchMask() != nMask) || (pImp->pIter->GetSearchFamily() != nSearchFamily) )
585 : {
586 21502 : pImp->pIter = CreateIterator( nSearchFamily, nMask );
587 : }
588 :
589 442516 : return *pImp->pIter;
590 : }
591 :
592 4597 : SfxStyleSheetBasePool::SfxStyleSheetBasePool( SfxItemPool& r ) :
593 4597 : pImp(new SfxStyleSheetBasePool_Impl),
594 4597 : aAppName(r.GetName()),
595 : rPool(r),
596 : nSearchFamily(SFX_STYLE_FAMILY_PARA),
597 13791 : nMask(SFXSTYLEBIT_ALL)
598 : {
599 : #ifdef DBG_UTIL
600 : aDbgStyleSheetReferences.mnPools++;
601 : #endif
602 4597 : }
603 :
604 0 : SfxStyleSheetBasePool::SfxStyleSheetBasePool( const SfxStyleSheetBasePool& r ) :
605 : SfxBroadcaster( r ),
606 : comphelper::OWeakTypeObject(),
607 0 : pImp(new SfxStyleSheetBasePool_Impl),
608 : aAppName(r.aAppName),
609 : rPool(r.rPool),
610 : nSearchFamily(r.nSearchFamily),
611 0 : nMask( r.nMask )
612 : {
613 : #ifdef DBG_UTIL
614 : aDbgStyleSheetReferences.mnPools++;
615 : #endif
616 :
617 0 : *this += r;
618 0 : }
619 :
620 9108 : SfxStyleSheetBasePool::~SfxStyleSheetBasePool()
621 : {
622 : #ifdef DBG_UTIL
623 : aDbgStyleSheetReferences.mnPools--;
624 : #endif
625 :
626 4554 : Broadcast( SfxSimpleHint(SFX_HINT_DYING) );
627 4554 : Clear();
628 4554 : delete pImp;
629 4554 : }
630 :
631 0 : bool SfxStyleSheetBasePool::SetParent(SfxStyleFamily eFam, const OUString& rStyle, const OUString& rParent)
632 : {
633 0 : SfxStyleSheetIterator aIter(this,eFam,SFXSTYLEBIT_ALL);
634 0 : SfxStyleSheetBase *pStyle = aIter.Find(rStyle);
635 : OSL_ENSURE(pStyle, "Template not found. Writer with solar <2541?");
636 0 : if(pStyle)
637 0 : return pStyle->SetParent(rParent);
638 : else
639 0 : return false;
640 : }
641 :
642 :
643 1224721 : void SfxStyleSheetBasePool::SetSearchMask(SfxStyleFamily eFam, sal_uInt16 n)
644 : {
645 1224721 : nSearchFamily = eFam; nMask = n;
646 1224721 : }
647 :
648 :
649 1360 : SfxStyleSheetIteratorPtr SfxStyleSheetBasePool::CreateIterator
650 : (
651 : SfxStyleFamily eFam,
652 : sal_uInt16 mask
653 : )
654 : {
655 1360 : return SfxStyleSheetIteratorPtr(new SfxStyleSheetIterator(this,eFam,mask));
656 : }
657 :
658 0 : SfxStyleSheetBase* SfxStyleSheetBasePool::Create
659 : (
660 : const OUString& rName,
661 : SfxStyleFamily eFam,
662 : sal_uInt16 mask
663 : )
664 : {
665 0 : return new SfxStyleSheetBase( rName, this, eFam, mask );
666 : }
667 :
668 0 : SfxStyleSheetBase* SfxStyleSheetBasePool::Create( const SfxStyleSheetBase& r )
669 : {
670 0 : return new SfxStyleSheetBase( r );
671 : }
672 :
673 25688 : SfxStyleSheetBase& SfxStyleSheetBasePool::Make( const OUString& rName, SfxStyleFamily eFam, sal_uInt16 mask)
674 : {
675 : OSL_ENSURE( eFam != SFX_STYLE_FAMILY_ALL, "svl::SfxStyleSheetBasePool::Make(), FamilyAll is not a allowed Familie" );
676 :
677 25688 : SfxStyleSheetIterator aIter(this, eFam, mask);
678 51376 : rtl::Reference< SfxStyleSheetBase > xStyle( aIter.Find( rName ) );
679 : OSL_ENSURE( !xStyle.is(), "svl::SfxStyleSheetBasePool::Make(), StyleSheet already exists" );
680 :
681 25688 : if( !xStyle.is() )
682 : {
683 25688 : xStyle = Create( rName, eFam, mask );
684 25688 : StoreStyleSheet(xStyle);
685 25688 : Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CREATED, *xStyle.get() ) );
686 : }
687 51376 : return *xStyle.get();
688 : }
689 :
690 : /**
691 : * Helper function: If a template with this name exists it is created
692 : * anew. All templates that have this template as a parent are reconnected.
693 : */
694 0 : SfxStyleSheetBase& SfxStyleSheetBasePool::Add( const SfxStyleSheetBase& rSheet )
695 : {
696 0 : SfxStyleSheetIterator aIter(this, rSheet.GetFamily(), nMask);
697 0 : SfxStyleSheetBase* pOld = aIter.Find( rSheet.GetName() );
698 0 : if (pOld) {
699 0 : Remove( pOld );
700 : }
701 0 : rtl::Reference< SfxStyleSheetBase > xNew( Create( rSheet ) );
702 0 : pImp->mxIndexedStyleSheets->AddStyleSheet(xNew);
703 0 : Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CHANGED, *xNew.get() ) );
704 0 : return *xNew.get();
705 : }
706 :
707 0 : SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator=( const SfxStyleSheetBasePool& r )
708 : {
709 0 : if( &r != this )
710 : {
711 0 : Clear();
712 0 : *this += r;
713 : }
714 0 : return *this;
715 : }
716 :
717 : namespace {
718 0 : struct AddStyleSheetCallback : svl::StyleSheetCallback
719 : {
720 0 : explicit AddStyleSheetCallback(SfxStyleSheetBasePool *pool)
721 0 : : mPool(pool) {;}
722 :
723 0 : void DoIt(const SfxStyleSheetBase& ssheet) SAL_OVERRIDE
724 : {
725 0 : mPool->Add(ssheet);
726 0 : }
727 :
728 : SfxStyleSheetBasePool *mPool;
729 : };
730 : }
731 :
732 0 : SfxStyleSheetBasePool& SfxStyleSheetBasePool::operator+=( const SfxStyleSheetBasePool& r )
733 : {
734 0 : if( &r != this )
735 : {
736 0 : AddStyleSheetCallback callback(this);
737 0 : pImp->mxIndexedStyleSheets->ApplyToAllStyleSheets(callback);
738 : }
739 0 : return *this;
740 : }
741 :
742 4703 : sal_uInt16 SfxStyleSheetBasePool::Count()
743 : {
744 4703 : return GetIterator_Impl().Count();
745 : }
746 :
747 0 : SfxStyleSheetBase *SfxStyleSheetBasePool::operator[](sal_uInt16 nIdx)
748 : {
749 0 : return GetIterator_Impl()[nIdx];
750 : }
751 :
752 312431 : SfxStyleSheetBase* SfxStyleSheetBasePool::Find(const OUString& rName,
753 : SfxStyleFamily eFam,
754 : sal_uInt16 mask)
755 : {
756 312431 : SfxStyleSheetIterator aIter(this,eFam,mask);
757 312431 : return aIter.Find(rName);
758 : }
759 :
760 49001 : SfxStyleSheetBase* SfxStyleSheetBasePool::First()
761 : {
762 49001 : return GetIterator_Impl().First();
763 : }
764 :
765 343522 : SfxStyleSheetBase* SfxStyleSheetBasePool::Next()
766 : {
767 343522 : return GetIterator_Impl().Next();
768 : }
769 :
770 1 : void SfxStyleSheetBasePool::Remove( SfxStyleSheetBase* p )
771 : {
772 1 : if( p )
773 : {
774 : // Reference to keep p alive until after Broadcast call!
775 1 : rtl::Reference<SfxStyleSheetBase> xP(p);
776 1 : bool bWasRemoved = pImp->mxIndexedStyleSheets->RemoveStyleSheet(xP);
777 1 : if( bWasRemoved )
778 : {
779 : // Adapt all styles which have this style as parant
780 1 : ChangeParent( p->GetName(), p->GetParent() );
781 :
782 : // #120015# Do not dispose, the removed StyleSheet may still be used in
783 : // existing SdrUndoAttrObj incarnations. Rely on refcounting for disposal,
784 : // this works well under normal conditions (checked breaking and counting
785 : // on SfxStyleSheetBase constructors and destructors)
786 :
787 : // com::sun::star::uno::Reference< com::sun::star::lang::XComponent > xComp( static_cast< ::cppu::OWeakObject* >((*aIter).get()), com::sun::star::uno::UNO_QUERY );
788 : // if( xComp.is() ) try
789 : // {
790 : // xComp->dispose();
791 : // }
792 : // catch( com::sun::star::uno::Exception& )
793 : // {
794 : // }
795 1 : Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::ERASED, *p ) );
796 1 : }
797 : }
798 1 : }
799 :
800 3 : void SfxStyleSheetBasePool::Insert( SfxStyleSheetBase* p )
801 : {
802 : #if OSL_DEBUG_LEVEL > 0
803 : OSL_ENSURE( p, "svl::SfxStyleSheetBasePool::Insert(), no stylesheet?" );
804 :
805 : SfxStyleSheetIterator aIter(this, p->GetFamily(), p->GetMask());
806 : SfxStyleSheetBase* pOld = aIter.Find( p->GetName() );
807 : OSL_ENSURE( !pOld, "svl::SfxStyleSheetBasePool::Insert(), StyleSheet already inserted" );
808 : if( !p->GetParent().isEmpty() )
809 : {
810 : pOld = aIter.Find( p->GetParent() );
811 : OSL_ENSURE( pOld, "svl::SfxStyleSheetBasePool::Insert(), Parent not found!" );
812 : }
813 : #endif
814 3 : StoreStyleSheet(rtl::Reference< SfxStyleSheetBase >( p ) );
815 3 : Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::CREATED, *p ) );
816 3 : }
817 :
818 : namespace
819 : {
820 :
821 4869 : struct StyleSheetDisposerFunctor SAL_FINAL : public svl::StyleSheetDisposer
822 : {
823 4869 : explicit StyleSheetDisposerFunctor(SfxStyleSheetBasePool* pool)
824 4869 : : mPool(pool) {;}
825 :
826 : void
827 25223 : Dispose(rtl::Reference<SfxStyleSheetBase> styleSheet) SAL_OVERRIDE
828 : {
829 25223 : cppu::OWeakObject* weakObject = static_cast< ::cppu::OWeakObject* >(styleSheet.get());
830 : com::sun::star::uno::Reference< com::sun::star::lang::XComponent >
831 25223 : xComp( weakObject, com::sun::star::uno::UNO_QUERY );
832 25223 : if( xComp.is() ) try
833 : {
834 19657 : xComp->dispose();
835 : }
836 0 : catch( com::sun::star::uno::Exception& )
837 : {
838 : }
839 25223 : mPool->Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::ERASED, *styleSheet.get() ) );
840 25223 : }
841 :
842 : SfxStyleSheetBasePool* mPool;
843 : };
844 :
845 : }
846 :
847 4869 : void SfxStyleSheetBasePool::Clear()
848 : {
849 4869 : StyleSheetDisposerFunctor cleanup(this);
850 4869 : pImp->mxIndexedStyleSheets->Clear(cleanup);
851 4869 : }
852 :
853 2070 : void SfxStyleSheetBasePool::ChangeParent(const OUString& rOld,
854 : const OUString& rNew,
855 : bool bVirtual)
856 : {
857 2070 : const sal_uInt16 nTmpMask = GetSearchMask();
858 2070 : SetSearchMask(GetSearchFamily(), SFXSTYLEBIT_ALL);
859 34447 : for( SfxStyleSheetBase* p = First(); p; p = Next() )
860 : {
861 32377 : if( p->GetParent() == rOld )
862 : {
863 1176 : if(bVirtual)
864 0 : p->SetParent( rNew );
865 : else
866 1176 : p->aParent = rNew;
867 : }
868 : }
869 2070 : SetSearchMask(GetSearchFamily(), nTmpMask);
870 2070 : }
871 :
872 0 : void SfxStyleSheetBase::Load( SvStream&, sal_uInt16 )
873 : {
874 0 : }
875 :
876 0 : void SfxStyleSheetBase::Store( SvStream& )
877 : {
878 0 : }
879 :
880 25691 : SfxStyleSheet::SfxStyleSheet(const OUString &rName,
881 : const SfxStyleSheetBasePool& r_Pool,
882 : SfxStyleFamily eFam,
883 : sal_uInt16 mask )
884 25691 : : SfxStyleSheetBase(rName, const_cast< SfxStyleSheetBasePool* >( &r_Pool ), eFam, mask)
885 : {
886 25691 : }
887 :
888 0 : SfxStyleSheet::SfxStyleSheet(const SfxStyleSheet& rStyle)
889 : : SfxStyleSheetBase(rStyle)
890 : , SfxListener( rStyle )
891 : , SfxBroadcaster( rStyle )
892 0 : , svl::StyleSheetUser()
893 : {
894 0 : }
895 :
896 50448 : SfxStyleSheet::~SfxStyleSheet()
897 : {
898 25224 : Broadcast( SfxStyleSheetHint( SfxStyleSheetHintId::INDESTRUCTION, *this ) );
899 25224 : }
900 :
901 :
902 29419 : bool SfxStyleSheet::SetParent( const OUString& rName )
903 : {
904 29419 : if(aParent == rName)
905 7919 : return true;
906 21500 : const OUString aOldParent(aParent);
907 21500 : if(SfxStyleSheetBase::SetParent(rName))
908 : {
909 : // Remove from notification chain of the old parent if applicable
910 21500 : if(!aOldParent.isEmpty())
911 : {
912 1890 : SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(pPool->Find(aOldParent, nFamily, SFXSTYLEBIT_ALL));
913 1890 : if(pParent)
914 1890 : EndListening(*pParent);
915 : }
916 : // Add to the notification chain of the new parent
917 21500 : if(!aParent.isEmpty())
918 : {
919 21500 : SfxStyleSheet *pParent = static_cast<SfxStyleSheet *>(pPool->Find(aParent, nFamily, SFXSTYLEBIT_ALL));
920 21500 : if(pParent)
921 21500 : StartListening(*pParent);
922 : }
923 21500 : return true;
924 : }
925 0 : return false;
926 : }
927 :
928 : /**
929 : * Notify all listeners
930 : */
931 1566362 : void SfxStyleSheet::Notify(SfxBroadcaster& rBC, const SfxHint& rHint )
932 : {
933 1566362 : Forward(rBC, rHint);
934 1566362 : }
935 :
936 16623 : bool SfxStyleSheet::isUsedByModel() const
937 : {
938 16623 : return IsUsed();
939 : }
940 :
941 :
942 1645 : SfxStyleSheetPool::SfxStyleSheetPool( SfxItemPool const& rSet)
943 1645 : : SfxStyleSheetBasePool( const_cast< SfxItemPool& >( rSet ) )
944 : {
945 1645 : }
946 :
947 0 : SfxStyleSheetBase* SfxStyleSheetPool::Create( const OUString& rName,
948 : SfxStyleFamily eFam, sal_uInt16 mask )
949 : {
950 0 : return new SfxStyleSheet( rName, *this, eFam, mask );
951 : }
952 :
953 20047 : SfxUnoStyleSheet::SfxUnoStyleSheet( const OUString& _rName, const SfxStyleSheetBasePool& _rPool, SfxStyleFamily _eFamily, sal_uInt16 _nMaske )
954 20047 : : ::cppu::ImplInheritanceHelper2< SfxStyleSheet, ::com::sun::star::style::XStyle, ::com::sun::star::lang::XUnoTunnel >( _rName, _rPool, _eFamily, _nMaske )
955 : {
956 20047 : }
957 :
958 1971 : SfxUnoStyleSheet* SfxUnoStyleSheet::getUnoStyleSheet( const ::com::sun::star::uno::Reference< ::com::sun::star::style::XStyle >& xStyle )
959 : {
960 1971 : SfxUnoStyleSheet* pRet = dynamic_cast< SfxUnoStyleSheet* >( xStyle.get() );
961 1971 : if( !pRet )
962 : {
963 0 : ::com::sun::star::uno::Reference< ::com::sun::star::lang::XUnoTunnel > xUT( xStyle, ::com::sun::star::uno::UNO_QUERY );
964 0 : if( xUT.is() )
965 0 : pRet = reinterpret_cast<SfxUnoStyleSheet*>(sal::static_int_cast<sal_uIntPtr>(xUT->getSomething( SfxUnoStyleSheet::getIdentifier())));
966 : }
967 1971 : return pRet;
968 : }
969 :
970 : /**
971 : * XUnoTunnel
972 : */
973 0 : ::sal_Int64 SAL_CALL SfxUnoStyleSheet::getSomething( const ::com::sun::star::uno::Sequence< ::sal_Int8 >& rId ) throw (::com::sun::star::uno::RuntimeException, std::exception)
974 : {
975 0 : if( rId.getLength() == 16 && 0 == memcmp( getIdentifier().getConstArray(), rId.getConstArray(), 16 ) )
976 : {
977 0 : return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_uIntPtr>(this));
978 : }
979 : else
980 : {
981 0 : return 0;
982 : }
983 : }
984 :
985 : void
986 25691 : SfxStyleSheetBasePool::StoreStyleSheet(rtl::Reference< SfxStyleSheetBase > xStyle)
987 : {
988 25691 : pImp->mxIndexedStyleSheets->AddStyleSheet(xStyle);
989 25691 : }
990 :
991 : namespace
992 : {
993 : class theSfxUnoStyleSheetIdentifier : public rtl::Static< UnoTunnelIdInit, theSfxUnoStyleSheetIdentifier > {};
994 : }
995 :
996 0 : const ::com::sun::star::uno::Sequence< ::sal_Int8 >& SfxUnoStyleSheet::getIdentifier()
997 : {
998 0 : return theSfxUnoStyleSheetIdentifier::get().getSeq();
999 : }
1000 :
1001 : void
1002 2069 : SfxStyleSheetBasePool::Reindex()
1003 : {
1004 2069 : pImp->mxIndexedStyleSheets->Reindex();
1005 2069 : }
1006 :
1007 : const svl::IndexedStyleSheets&
1008 0 : SfxStyleSheetBasePool::GetIndexedStyleSheets() const
1009 : {
1010 0 : return *pImp->mxIndexedStyleSheets;
1011 : }
1012 :
1013 : rtl::Reference<SfxStyleSheetBase>
1014 0 : SfxStyleSheetBasePool::GetStyleSheetByPositionInIndex(unsigned pos)
1015 : {
1016 0 : return pImp->mxIndexedStyleSheets->GetStyleSheetByPosition(pos);
1017 : }
1018 :
1019 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|