nss: upgrade to release 3.73
[LibreOffice.git] / sd / source / core / stlfamily.cxx
blob0f03615c88f3771506d5e102a68442b371372107
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <com/sun/star/lang/DisposedException.hpp>
21 #include <com/sun/star/lang/IllegalAccessException.hpp>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <cppuhelper/supportsservice.hxx>
25 #include <vcl/svapp.hxx>
27 #include <svl/style.hxx>
29 #include <tools/debug.hxx>
30 #include <tools/weakbase.hxx>
32 #include <strings.hrc>
33 #include <stlfamily.hxx>
34 #include <stlsheet.hxx>
35 #include <sdresid.hxx>
36 #include <sdpage.hxx>
37 #include <glob.hxx>
39 #include <map>
40 #include <memory>
42 using namespace ::com::sun::star::uno;
43 using namespace ::com::sun::star::lang;
44 using namespace ::com::sun::star::container;
45 using namespace ::com::sun::star::style;
46 using namespace ::com::sun::star::beans;
48 typedef std::map< OUString, rtl::Reference< SdStyleSheet > > PresStyleMap;
50 struct SdStyleFamilyImpl
52 tools::WeakReference<SdPage> mxMasterPage;
53 OUString maLayoutName;
55 PresStyleMap& getStyleSheets();
56 rtl::Reference< SfxStyleSheetPool > mxPool;
58 private:
59 PresStyleMap maStyleSheets;
62 PresStyleMap& SdStyleFamilyImpl::getStyleSheets()
64 if( mxMasterPage.is() && (mxMasterPage->GetLayoutName() != maLayoutName) )
66 maLayoutName = mxMasterPage->GetLayoutName();
68 OUString aLayoutName( maLayoutName );
69 const sal_Int32 nLen = aLayoutName.indexOf(SD_LT_SEPARATOR ) + 4;
70 aLayoutName = aLayoutName.copy(0, nLen );
72 if( (maStyleSheets.empty()) || !(*maStyleSheets.begin()).second->GetName().startsWith( aLayoutName) )
74 maStyleSheets.clear();
76 // The iterator will return only style sheets of family master page
77 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), SfxStyleFamily::Page);
78 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
79 pStyle = aSSSIterator->Next() )
81 // we assume that we have only SdStyleSheets
82 SdStyleSheet* pSdStyle = static_cast< SdStyleSheet* >( pStyle );
83 if (pSdStyle->GetName().startsWith(aLayoutName))
85 maStyleSheets[ pSdStyle->GetApiName() ].set( pSdStyle );
91 return maStyleSheets;
94 SdStyleFamily::SdStyleFamily( const rtl::Reference< SfxStyleSheetPool >& xPool, SfxStyleFamily nFamily )
95 : mnFamily( nFamily )
96 , mxPool( xPool )
100 SdStyleFamily::SdStyleFamily( const rtl::Reference< SfxStyleSheetPool >& xPool, const SdPage* pMasterPage )
101 : mnFamily( SfxStyleFamily::Page )
102 , mxPool( xPool )
103 , mpImpl( new SdStyleFamilyImpl )
105 mpImpl->mxMasterPage.reset( const_cast< SdPage* >( pMasterPage ) );
106 mpImpl->mxPool = xPool;
109 SdStyleFamily::~SdStyleFamily()
111 DBG_ASSERT( !mxPool.is(), "SdStyleFamily::~SdStyleFamily(), dispose me first!" );
114 void SdStyleFamily::throwIfDisposed() const
116 if( !mxPool.is() )
117 throw DisposedException();
120 SdStyleSheet* SdStyleFamily::GetValidNewSheet( const Any& rElement )
122 Reference< XStyle > xStyle( rElement, UNO_QUERY );
123 SdStyleSheet* pStyle = static_cast< SdStyleSheet* >( xStyle.get() );
125 if( pStyle == nullptr || (pStyle->GetFamily() != mnFamily) || (pStyle->GetPool() != mxPool.get()) || (mxPool->Find( pStyle->GetName(), mnFamily) != nullptr) )
126 throw IllegalArgumentException();
128 return pStyle;
131 SdStyleSheet* SdStyleFamily::GetSheetByName( const OUString& rName )
133 SdStyleSheet* pRet = nullptr;
134 if( !rName.isEmpty() )
136 if( mnFamily == SfxStyleFamily::Page )
138 PresStyleMap& rStyleMap = mpImpl->getStyleSheets();
139 PresStyleMap::iterator iter( rStyleMap.find(rName) );
140 if( iter != rStyleMap.end() )
141 pRet = (*iter).second.get();
143 else
145 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
146 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
147 pStyle = aSSSIterator->Next() )
149 // we assume that we have only SdStyleSheets
150 SdStyleSheet* pSdStyle = static_cast< SdStyleSheet* >( pStyle );
151 if (pSdStyle->GetApiName() == rName)
153 pRet = pSdStyle;
154 break;
159 if( pRet )
160 return pRet;
162 throw NoSuchElementException();
165 // XServiceInfo
166 OUString SAL_CALL SdStyleFamily::getImplementationName()
168 return "SdStyleFamily";
171 sal_Bool SAL_CALL SdStyleFamily::supportsService( const OUString& ServiceName )
173 return cppu::supportsService( this, ServiceName );
176 Sequence< OUString > SAL_CALL SdStyleFamily::getSupportedServiceNames()
178 return { "com.sun.star.style.StyleFamily" };
181 // XNamed
182 OUString SAL_CALL SdStyleFamily::getName()
184 if( mnFamily == SfxStyleFamily::Page )
186 SdPage* pPage = mpImpl->mxMasterPage.get();
187 if( pPage == nullptr )
188 throw DisposedException();
190 OUString aLayoutName( pPage->GetLayoutName() );
191 sal_Int32 nIndex = aLayoutName.indexOf(SD_LT_SEPARATOR);
192 if( nIndex != -1 )
193 aLayoutName = aLayoutName.copy(0, nIndex);
195 return aLayoutName;
197 else
199 return SdStyleSheet::GetFamilyString( mnFamily );
203 void SAL_CALL SdStyleFamily::setName( const OUString& )
207 // XNameAccess
209 Any SAL_CALL SdStyleFamily::getByName( const OUString& rName )
211 SolarMutexGuard aGuard;
212 throwIfDisposed();
213 return Any( Reference< XStyle >( static_cast<SfxUnoStyleSheet*>(GetSheetByName( rName )) ) );
216 Sequence< OUString > SAL_CALL SdStyleFamily::getElementNames()
218 SolarMutexGuard aGuard;
220 throwIfDisposed();
222 if( mnFamily == SfxStyleFamily::Page )
224 PresStyleMap& rStyleMap = mpImpl->getStyleSheets();
225 Sequence< OUString > aNames( rStyleMap.size() );
227 OUString* pNames = aNames.getArray();
228 for( const auto& rEntry : rStyleMap )
230 rtl::Reference< SdStyleSheet > xStyle( rEntry.second );
231 if( xStyle.is() )
233 *pNames++ = xStyle->GetApiName();
237 return aNames;
239 else
241 std::vector< OUString > aNames;
242 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
243 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
244 pStyle = aSSSIterator->Next() )
246 // we assume that we have only SdStyleSheets
247 SdStyleSheet* pSdStyle = static_cast< SdStyleSheet* >( pStyle );
248 aNames.push_back(pSdStyle->GetApiName());
250 return Sequence< OUString >( &(*aNames.begin()), aNames.size() );
254 sal_Bool SAL_CALL SdStyleFamily::hasByName( const OUString& aName )
256 SolarMutexGuard aGuard;
257 throwIfDisposed();
259 if( !aName.isEmpty() )
261 if( mnFamily == SfxStyleFamily::Page )
263 PresStyleMap& rStyleSheets = mpImpl->getStyleSheets();
264 PresStyleMap::iterator iter( rStyleSheets.find(aName) );
265 return iter != rStyleSheets.end();
267 else
269 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
270 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
271 pStyle = aSSSIterator->Next() )
273 // we assume that we have only SdStyleSheets
274 SdStyleSheet* pSdStyle = static_cast< SdStyleSheet* >( pStyle );
275 if (pSdStyle->GetApiName() == aName)
277 return true;
283 return false;
286 // XElementAccess
288 Type SAL_CALL SdStyleFamily::getElementType()
290 return cppu::UnoType<XStyle>::get();
293 sal_Bool SAL_CALL SdStyleFamily::hasElements()
295 SolarMutexGuard aGuard;
296 throwIfDisposed();
298 if( mnFamily == SfxStyleFamily::Page )
300 return true;
302 else
304 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
305 if (aSSSIterator->First())
307 return true;
311 return false;
314 // XIndexAccess
316 sal_Int32 SAL_CALL SdStyleFamily::getCount()
318 SolarMutexGuard aGuard;
319 throwIfDisposed();
321 sal_Int32 nCount = 0;
322 if( mnFamily == SfxStyleFamily::Page )
324 return mpImpl->getStyleSheets().size();
326 else
328 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
329 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
330 pStyle = aSSSIterator->Next() )
332 nCount++;
336 return nCount;
339 Any SAL_CALL SdStyleFamily::getByIndex( sal_Int32 Index )
341 SolarMutexGuard aGuard;
342 throwIfDisposed();
344 if( Index >= 0 )
346 if( mnFamily == SfxStyleFamily::Page )
348 PresStyleMap& rStyleSheets = mpImpl->getStyleSheets();
349 if( Index < static_cast<sal_Int32>(rStyleSheets.size()) )
351 PresStyleMap::iterator iter( rStyleSheets.begin() );
352 std::advance(iter, Index);
353 return Any( Reference< XStyle >( (*iter).second.get() ) );
356 else
358 std::shared_ptr<SfxStyleSheetIterator> aSSSIterator = std::make_shared<SfxStyleSheetIterator>(mxPool.get(), mnFamily);
359 for ( SfxStyleSheetBase* pStyle = aSSSIterator->First(); pStyle;
360 pStyle = aSSSIterator->Next() )
362 // we assume that we have only SdStyleSheets
363 SdStyleSheet* pSdStyle = static_cast< SdStyleSheet* >( pStyle );
364 if( Index-- == 0 )
366 return Any( Reference< XStyle >( pSdStyle ) );
372 throw IndexOutOfBoundsException();
375 // XNameContainer
377 void SAL_CALL SdStyleFamily::insertByName( const OUString& rName, const Any& rElement )
379 SolarMutexGuard aGuard;
380 throwIfDisposed();
382 if(rName.isEmpty())
383 throw IllegalArgumentException();
385 SdStyleSheet* pStyle = GetValidNewSheet( rElement );
386 if( !pStyle->SetName( rName ) )
387 throw ElementExistException();
389 pStyle->SetApiName( rName );
390 mxPool->Insert( pStyle );
393 void SAL_CALL SdStyleFamily::removeByName( const OUString& rName )
395 SolarMutexGuard aGuard;
396 throwIfDisposed();
398 SdStyleSheet* pStyle = GetSheetByName( rName );
400 if( !pStyle->IsUserDefined() )
401 throw WrappedTargetException();
403 mxPool->Remove( pStyle );
406 // XNameReplace
408 void SAL_CALL SdStyleFamily::replaceByName( const OUString& rName, const Any& aElement )
410 SolarMutexGuard aGuard;
411 throwIfDisposed();
413 SdStyleSheet* pOldStyle = GetSheetByName( rName );
414 SdStyleSheet* pNewStyle = GetValidNewSheet( aElement );
416 mxPool->Remove( pOldStyle );
417 mxPool->Insert( pNewStyle );
420 // XSingleServiceFactory
422 Reference< XInterface > SAL_CALL SdStyleFamily::createInstance()
424 SolarMutexGuard aGuard;
425 throwIfDisposed();
427 if( mnFamily == SfxStyleFamily::Page )
429 throw IllegalAccessException();
431 return Reference<XInterface>(
432 static_cast<XStyle*>(SdStyleSheet::CreateEmptyUserStyle(*mxPool, mnFamily)));
435 Reference< XInterface > SAL_CALL SdStyleFamily::createInstanceWithArguments( const Sequence< Any >& )
437 return createInstance();
440 // XComponent
442 void SAL_CALL SdStyleFamily::dispose( )
444 if( mxPool.is() )
445 mxPool.clear();
447 mpImpl.reset();
450 void SAL_CALL SdStyleFamily::addEventListener( const Reference< XEventListener >& )
454 void SAL_CALL SdStyleFamily::removeEventListener( const Reference< XEventListener >& )
458 // XPropertySet
460 Reference<XPropertySetInfo> SdStyleFamily::getPropertySetInfo()
462 OSL_FAIL( "###unexpected!" );
463 return Reference<XPropertySetInfo>();
466 void SdStyleFamily::setPropertyValue( const OUString& , const Any& )
468 OSL_FAIL( "###unexpected!" );
471 Any SdStyleFamily::getPropertyValue( const OUString& PropertyName )
473 if ( PropertyName != "DisplayName" )
475 throw UnknownPropertyException( "unknown property: " + PropertyName, static_cast<OWeakObject *>(this) );
478 SolarMutexGuard aGuard;
479 OUString sDisplayName;
480 switch( mnFamily )
482 case SfxStyleFamily::Page: sDisplayName = getName(); break;
483 case SfxStyleFamily::Frame: sDisplayName = SdResId(STR_CELL_STYLE_FAMILY); break;
484 default: sDisplayName = SdResId(STR_GRAPHICS_STYLE_FAMILY); break;
486 return Any( sDisplayName );
489 void SdStyleFamily::addPropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& )
491 OSL_FAIL( "###unexpected!" );
494 void SdStyleFamily::removePropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& )
496 OSL_FAIL( "###unexpected!" );
499 void SdStyleFamily::addVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& )
501 OSL_FAIL( "###unexpected!" );
504 void SdStyleFamily::removeVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& )
506 OSL_FAIL( "###unexpected!" );
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */