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