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 :
21 : #include <com/sun/star/lang/DisposedException.hpp>
22 : #include <com/sun/star/lang/IllegalAccessException.hpp>
23 : #include <comphelper/serviceinfohelper.hxx>
24 :
25 : #include <osl/mutex.hxx>
26 : #include <vcl/svapp.hxx>
27 :
28 : #include <svl/style.hxx>
29 :
30 : #include <svx/unoprov.hxx>
31 :
32 : #include "../ui/inc/strings.hrc"
33 : #include "stlfamily.hxx"
34 : #include "stlsheet.hxx"
35 : #include "sdresid.hxx"
36 : #include "drawdoc.hxx"
37 : #include "sdpage.hxx"
38 : #include "glob.hxx"
39 :
40 : #include <map>
41 :
42 : using ::rtl::OUString;
43 : using namespace ::com::sun::star::uno;
44 : using namespace ::com::sun::star::lang;
45 : using namespace ::com::sun::star::container;
46 : using namespace ::com::sun::star::style;
47 : using namespace ::com::sun::star::beans;
48 :
49 : // ----------------------------------------------------------
50 :
51 : typedef std::map< rtl::OUString, rtl::Reference< SdStyleSheet > > PresStyleMap;
52 :
53 32 : struct SdStyleFamilyImpl
54 : {
55 : SdrPageWeakRef mxMasterPage;
56 : OUString maLayoutName;
57 :
58 : PresStyleMap& getStyleSheets();
59 : rtl::Reference< SfxStyleSheetPool > mxPool;
60 :
61 : private:
62 : PresStyleMap maStyleSheets;
63 : };
64 :
65 126 : PresStyleMap& SdStyleFamilyImpl::getStyleSheets()
66 : {
67 126 : if( mxMasterPage.is() && (mxMasterPage->GetLayoutName() != maLayoutName) )
68 : {
69 6 : maLayoutName = mxMasterPage->GetLayoutName();
70 :
71 6 : String aLayoutName( maLayoutName );
72 6 : const sal_uInt16 nLen = aLayoutName.Search(String( RTL_CONSTASCII_USTRINGPARAM(SD_LT_SEPARATOR)))+4;
73 6 : aLayoutName.Erase( nLen );
74 :
75 6 : if( (maStyleSheets.empty()) || !((*maStyleSheets.begin()).second->GetName().Equals( aLayoutName, 0, nLen )) )
76 : {
77 6 : maStyleSheets.clear();
78 :
79 6 : const SfxStyles& rStyles = mxPool->GetStyles();
80 517 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
81 : {
82 511 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
83 511 : if( pStyle && (pStyle->GetFamily() == SD_STYLE_FAMILY_MASTERPAGE) && (pStyle->GetName().Equals( aLayoutName, 0, nLen )) )
84 84 : maStyleSheets[ pStyle->GetApiName() ] = rtl::Reference< SdStyleSheet >( pStyle );
85 : }
86 6 : }
87 : }
88 :
89 126 : return maStyleSheets;
90 : }
91 :
92 : // ----------------------------------------------------------
93 :
94 40 : SdStyleFamily::SdStyleFamily( const rtl::Reference< SfxStyleSheetPool >& xPool, SfxStyleFamily nFamily )
95 : : mnFamily( nFamily )
96 : , mxPool( xPool )
97 40 : , mpImpl( 0 )
98 : {
99 40 : }
100 :
101 : // ----------------------------------------------------------
102 :
103 17 : SdStyleFamily::SdStyleFamily( const rtl::Reference< SfxStyleSheetPool >& xPool, const SdPage* pMasterPage )
104 : : mnFamily( SD_STYLE_FAMILY_MASTERPAGE )
105 : , mxPool( xPool )
106 17 : , mpImpl( new SdStyleFamilyImpl() )
107 : {
108 17 : mpImpl->mxMasterPage.reset( const_cast< SdPage* >( pMasterPage ) );
109 17 : mpImpl->mxPool = xPool;
110 17 : }
111 :
112 : // ----------------------------------------------------------
113 :
114 153 : SdStyleFamily::~SdStyleFamily()
115 : {
116 : DBG_ASSERT( !mxPool.is(), "SdStyleFamily::~SdStyleFamily(), dispose me first!" );
117 51 : delete mpImpl;
118 102 : }
119 :
120 : // ----------------------------------------------------------
121 :
122 323 : void SdStyleFamily::throwIfDisposed() const throw(RuntimeException)
123 : {
124 323 : if( !mxPool.is() )
125 0 : throw DisposedException();
126 323 : }
127 :
128 : // ----------------------------------------------------------
129 :
130 0 : SdStyleSheet* SdStyleFamily::GetValidNewSheet( const Any& rElement ) throw(IllegalArgumentException)
131 : {
132 0 : Reference< XStyle > xStyle( rElement, UNO_QUERY );
133 0 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( xStyle.get() );
134 :
135 0 : if( pStyle == 0 || (pStyle->GetFamily() != mnFamily) || (&pStyle->GetPool() != mxPool.get()) || (mxPool->Find( pStyle->GetName(), mnFamily) != 0) )
136 0 : throw IllegalArgumentException();
137 :
138 0 : return pStyle;
139 : }
140 :
141 : // ----------------------------------------------------------
142 :
143 243 : SdStyleSheet* SdStyleFamily::GetSheetByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException )
144 : {
145 243 : SdStyleSheet* pRet = 0;
146 243 : if( !rName.isEmpty() )
147 : {
148 243 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
149 : {
150 80 : PresStyleMap& rStyleMap = mpImpl->getStyleSheets();
151 80 : PresStyleMap::iterator iter( rStyleMap.find(rName) );
152 80 : if( iter != rStyleMap.end() )
153 80 : pRet = (*iter).second.get();
154 : }
155 : else
156 : {
157 163 : const SfxStyles& rStyles = mxPool->GetStyles();
158 1071 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
159 : {
160 1071 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
161 1071 : if( pStyle && (pStyle->GetFamily() == mnFamily) && (pStyle->GetApiName() == rName) )
162 : {
163 163 : pRet = pStyle;
164 163 : break;
165 : }
166 : }
167 : }
168 : }
169 243 : if( pRet )
170 486 : return pRet;
171 :
172 0 : throw NoSuchElementException();
173 : }
174 :
175 : // ----------------------------------------------------------
176 : // XServiceInfo
177 : // ----------------------------------------------------------
178 :
179 0 : OUString SAL_CALL SdStyleFamily::getImplementationName() throw(RuntimeException)
180 : {
181 0 : return OUString( "SdStyleFamily" );
182 : }
183 :
184 : // ----------------------------------------------------------
185 :
186 0 : sal_Bool SAL_CALL SdStyleFamily::supportsService( const OUString& ServiceName ) throw(RuntimeException)
187 : {
188 0 : return comphelper::ServiceInfoHelper::supportsService( ServiceName, getSupportedServiceNames() );
189 : }
190 :
191 : // ----------------------------------------------------------
192 :
193 0 : Sequence< OUString > SAL_CALL SdStyleFamily::getSupportedServiceNames() throw(RuntimeException)
194 : {
195 0 : OUString aServiceName( "com.sun.star.style.StyleFamily" );
196 0 : Sequence< OUString > aSeq( &aServiceName, 1 );
197 0 : return aSeq;
198 : }
199 :
200 : // ----------------------------------------------------------
201 : // XNamed
202 : // ----------------------------------------------------------
203 :
204 356 : OUString SAL_CALL SdStyleFamily::getName() throw (RuntimeException)
205 : {
206 356 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
207 : {
208 76 : SdPage* pPage = static_cast< SdPage* >( mpImpl->mxMasterPage.get() );
209 76 : if( pPage == 0 )
210 0 : throw DisposedException();
211 :
212 76 : String aLayoutName( pPage->GetLayoutName() );
213 76 : const String aSep( RTL_CONSTASCII_USTRINGPARAM( SD_LT_SEPARATOR ));
214 76 : aLayoutName.Erase(aLayoutName.Search(aSep));
215 :
216 76 : return OUString( aLayoutName );
217 : }
218 : else
219 : {
220 280 : return SdStyleSheet::GetFamilyString( mnFamily );
221 : }
222 : }
223 :
224 : // ----------------------------------------------------------
225 :
226 0 : void SAL_CALL SdStyleFamily::setName( const ::rtl::OUString& ) throw (RuntimeException)
227 : {
228 0 : }
229 :
230 : // ----------------------------------------------------------
231 : // XNameAccess
232 : // ----------------------------------------------------------
233 :
234 243 : Any SAL_CALL SdStyleFamily::getByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
235 : {
236 243 : SolarMutexGuard aGuard;
237 243 : throwIfDisposed();
238 243 : return Any( Reference< XStyle >( static_cast<SfxUnoStyleSheet*>(GetSheetByName( rName )) ) );
239 : }
240 :
241 : // ----------------------------------------------------------
242 :
243 0 : Sequence< OUString > SAL_CALL SdStyleFamily::getElementNames() throw(RuntimeException)
244 : {
245 0 : SolarMutexGuard aGuard;
246 :
247 0 : throwIfDisposed();
248 :
249 0 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
250 : {
251 0 : PresStyleMap& rStyleMap = mpImpl->getStyleSheets();
252 0 : Sequence< OUString > aNames( rStyleMap.size() );
253 :
254 0 : PresStyleMap::iterator iter( rStyleMap.begin() );
255 0 : OUString* pNames = aNames.getArray();
256 0 : while( iter != rStyleMap.end() )
257 : {
258 0 : rtl::Reference< SdStyleSheet > xStyle( (*iter++).second );
259 0 : if( xStyle.is() )
260 : {
261 0 : *pNames++ = xStyle->GetApiName();
262 : }
263 0 : }
264 :
265 0 : return aNames;
266 : }
267 : else
268 : {
269 0 : std::vector< OUString > aNames;
270 0 : const SfxStyles& rStyles = mxPool->GetStyles();
271 0 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
272 : {
273 0 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
274 0 : if( pStyle && (pStyle->GetFamily() == mnFamily) )
275 0 : aNames.push_back( pStyle->GetApiName() );
276 : }
277 0 : return Sequence< OUString >( &(*aNames.begin()), aNames.size() );
278 0 : }
279 : }
280 :
281 : // ----------------------------------------------------------
282 :
283 80 : sal_Bool SAL_CALL SdStyleFamily::hasByName( const OUString& aName ) throw(RuntimeException)
284 : {
285 80 : SolarMutexGuard aGuard;
286 80 : throwIfDisposed();
287 :
288 80 : if( !aName.isEmpty() )
289 : {
290 80 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
291 : {
292 46 : PresStyleMap& rStyleSheets = mpImpl->getStyleSheets();
293 46 : PresStyleMap::iterator iter( rStyleSheets.find(aName) );
294 46 : return ( iter != rStyleSheets.end() ) ? sal_True : sal_False;
295 : }
296 : else
297 : {
298 34 : const SfxStyles& rStyles = mxPool->GetStyles();
299 366 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
300 : {
301 366 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
302 366 : if( pStyle && (pStyle->GetFamily() == mnFamily) && ( pStyle->GetApiName() == aName ) )
303 34 : return sal_True;
304 : }
305 : }
306 : }
307 :
308 0 : return sal_False;
309 : }
310 :
311 : // ----------------------------------------------------------
312 : // XElementAccess
313 : // ----------------------------------------------------------
314 :
315 0 : Type SAL_CALL SdStyleFamily::getElementType() throw(RuntimeException)
316 : {
317 0 : return XStyle::static_type();
318 : }
319 :
320 : // ----------------------------------------------------------
321 :
322 0 : sal_Bool SAL_CALL SdStyleFamily::hasElements() throw(RuntimeException)
323 : {
324 0 : SolarMutexGuard aGuard;
325 0 : throwIfDisposed();
326 :
327 0 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
328 : {
329 0 : return sal_True;
330 : }
331 : else
332 : {
333 0 : const SfxStyles& rStyles = mxPool->GetStyles();
334 0 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
335 : {
336 0 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
337 0 : if( pStyle && (pStyle->GetFamily() == mnFamily) )
338 0 : return sal_True;
339 : }
340 : }
341 :
342 0 : return sal_False;
343 : }
344 :
345 : // ----------------------------------------------------------
346 : // XIndexAccess
347 : // ----------------------------------------------------------
348 :
349 0 : sal_Int32 SAL_CALL SdStyleFamily::getCount() throw(RuntimeException)
350 : {
351 0 : SolarMutexGuard aGuard;
352 0 : throwIfDisposed();
353 :
354 0 : sal_Int32 nCount = 0;
355 0 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
356 : {
357 0 : return mpImpl->getStyleSheets().size();
358 : }
359 : else
360 : {
361 0 : const SfxStyles& rStyles = mxPool->GetStyles();
362 0 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
363 : {
364 0 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
365 0 : if( pStyle && (pStyle->GetFamily() == mnFamily) )
366 0 : nCount++;
367 : }
368 : }
369 :
370 0 : return nCount;
371 : }
372 :
373 : // ----------------------------------------------------------
374 :
375 0 : Any SAL_CALL SdStyleFamily::getByIndex( sal_Int32 Index ) throw(IndexOutOfBoundsException, WrappedTargetException, RuntimeException)
376 : {
377 0 : SolarMutexGuard aGuard;
378 0 : throwIfDisposed();
379 :
380 0 : if( Index >= 0 )
381 : {
382 0 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
383 : {
384 0 : PresStyleMap& rStyleSheets = mpImpl->getStyleSheets();
385 0 : if( !rStyleSheets.empty() )
386 : {
387 0 : PresStyleMap::iterator iter( rStyleSheets.begin() );
388 0 : while( Index-- && (iter != rStyleSheets.end()) )
389 0 : ++iter;
390 :
391 0 : if( (Index==-1) && (iter != rStyleSheets.end()) )
392 0 : return Any( Reference< XStyle >( (*iter).second.get() ) );
393 : }
394 : }
395 : else
396 : {
397 0 : const SfxStyles& rStyles = mxPool->GetStyles();
398 0 : for( SfxStyles::const_iterator iter( rStyles.begin() ); iter != rStyles.end(); ++iter )
399 : {
400 0 : SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( (*iter).get() );
401 0 : if( pStyle && (pStyle->GetFamily() == mnFamily) )
402 : {
403 0 : if( Index-- == 0 )
404 0 : return Any( Reference< XStyle >( pStyle ) );
405 : }
406 : }
407 : }
408 : }
409 :
410 0 : throw IndexOutOfBoundsException();
411 : }
412 :
413 : // ----------------------------------------------------------
414 : // XNameContainer
415 : // ----------------------------------------------------------
416 :
417 0 : void SAL_CALL SdStyleFamily::insertByName( const OUString& rName, const Any& rElement ) throw(IllegalArgumentException, ElementExistException, WrappedTargetException, RuntimeException)
418 : {
419 0 : SolarMutexGuard aGuard;
420 0 : throwIfDisposed();
421 :
422 0 : if(rName.isEmpty())
423 0 : throw IllegalArgumentException();
424 :
425 0 : SdStyleSheet* pStyle = GetValidNewSheet( rElement );
426 0 : if( !pStyle->SetName( rName ) )
427 0 : throw ElementExistException();
428 :
429 0 : pStyle->SetApiName( rName );
430 0 : mxPool->Insert( pStyle );
431 0 : }
432 :
433 : // ----------------------------------------------------------
434 :
435 0 : void SAL_CALL SdStyleFamily::removeByName( const OUString& rName ) throw(NoSuchElementException, WrappedTargetException, RuntimeException)
436 : {
437 0 : SolarMutexGuard aGuard;
438 0 : throwIfDisposed();
439 :
440 0 : SdStyleSheet* pStyle = GetSheetByName( rName );
441 :
442 0 : if( !pStyle->IsUserDefined() )
443 0 : throw WrappedTargetException();
444 :
445 0 : mxPool->Remove( pStyle );
446 0 : }
447 :
448 : // ----------------------------------------------------------
449 : // XNameReplace
450 : // ----------------------------------------------------------
451 :
452 0 : void SAL_CALL SdStyleFamily::replaceByName( const OUString& rName, const Any& aElement ) throw(IllegalArgumentException, NoSuchElementException, WrappedTargetException, RuntimeException)
453 : {
454 0 : SolarMutexGuard aGuard;
455 0 : throwIfDisposed();
456 :
457 0 : SdStyleSheet* pOldStyle = GetSheetByName( rName );
458 0 : SdStyleSheet* pNewStyle = GetValidNewSheet( aElement );
459 :
460 0 : mxPool->Remove( pOldStyle );
461 0 : mxPool->Insert( pNewStyle );
462 0 : }
463 :
464 : // ----------------------------------------------------------
465 : // XSingleServiceFactory
466 : // ----------------------------------------------------------
467 :
468 0 : Reference< XInterface > SAL_CALL SdStyleFamily::createInstance() throw(Exception, RuntimeException)
469 : {
470 0 : SolarMutexGuard aGuard;
471 0 : throwIfDisposed();
472 :
473 0 : if( mnFamily == SD_STYLE_FAMILY_MASTERPAGE )
474 : {
475 0 : throw IllegalAccessException();
476 : }
477 : else
478 : {
479 0 : return Reference< XInterface >( static_cast< XStyle* >( SdStyleSheet::CreateEmptyUserStyle( *mxPool.get(), mnFamily ) ) );
480 0 : }
481 : }
482 :
483 : // ----------------------------------------------------------
484 :
485 0 : Reference< XInterface > SAL_CALL SdStyleFamily::createInstanceWithArguments( const Sequence< Any >& ) throw(Exception, RuntimeException)
486 : {
487 0 : return createInstance();
488 : }
489 :
490 : // ----------------------------------------------------------
491 : // XComponent
492 : // ----------------------------------------------------------
493 :
494 51 : void SAL_CALL SdStyleFamily::dispose( ) throw (RuntimeException)
495 : {
496 51 : if( mxPool.is() )
497 51 : mxPool.clear();
498 :
499 51 : if( mpImpl )
500 : {
501 15 : delete mpImpl;
502 15 : mpImpl = 0;
503 : }
504 51 : }
505 :
506 : // ----------------------------------------------------------
507 :
508 0 : void SAL_CALL SdStyleFamily::addEventListener( const Reference< XEventListener >& ) throw (RuntimeException)
509 : {
510 0 : }
511 :
512 : // ----------------------------------------------------------
513 :
514 0 : void SAL_CALL SdStyleFamily::removeEventListener( const Reference< XEventListener >& ) throw (RuntimeException)
515 : {
516 0 : }
517 :
518 : // ----------------------------------------------------------
519 : // XPropertySet
520 : // ----------------------------------------------------------
521 :
522 0 : Reference<XPropertySetInfo> SdStyleFamily::getPropertySetInfo() throw (RuntimeException)
523 : {
524 : OSL_FAIL( "###unexpected!" );
525 0 : return Reference<XPropertySetInfo>();
526 : }
527 :
528 : // ----------------------------------------------------------
529 :
530 0 : void SdStyleFamily::setPropertyValue( const OUString& , const Any& ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
531 : {
532 : OSL_FAIL( "###unexpected!" );
533 0 : }
534 :
535 : // ----------------------------------------------------------
536 :
537 0 : Any SdStyleFamily::getPropertyValue( const OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
538 : {
539 0 : if ( PropertyName == "DisplayName" )
540 : {
541 0 : SolarMutexGuard aGuard;
542 0 : OUString sDisplayName;
543 0 : switch( mnFamily )
544 : {
545 0 : case SD_STYLE_FAMILY_MASTERPAGE: sDisplayName = getName(); break;
546 0 : case SD_STYLE_FAMILY_CELL: sDisplayName = String( SdResId(STR_CELL_STYLE_FAMILY) ); break;
547 0 : default: sDisplayName = String( SdResId(STR_GRAPHICS_STYLE_FAMILY) ); break;
548 : }
549 0 : return Any( sDisplayName );
550 : }
551 : else
552 : {
553 0 : throw UnknownPropertyException( "unknown property: " + PropertyName, static_cast<OWeakObject *>(this) );
554 : }
555 : }
556 :
557 : // ----------------------------------------------------------
558 :
559 0 : void SdStyleFamily::addPropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
560 : {
561 : OSL_FAIL( "###unexpected!" );
562 0 : }
563 :
564 : // ----------------------------------------------------------
565 :
566 0 : void SdStyleFamily::removePropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
567 : {
568 : OSL_FAIL( "###unexpected!" );
569 0 : }
570 :
571 : // ----------------------------------------------------------
572 :
573 0 : void SdStyleFamily::addVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
574 : {
575 : OSL_FAIL( "###unexpected!" );
576 0 : }
577 :
578 : // ----------------------------------------------------------
579 :
580 0 : void SdStyleFamily::removeVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
581 : {
582 : OSL_FAIL( "###unexpected!" );
583 0 : }
584 :
585 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|