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