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