Bump version to 6.4-15
[LibreOffice.git] / svx / source / table / tabledesign.cxx
blob0a4f81417f63dce54b4932534e7fc60f27b969e7
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 .
21 #include <com/sun/star/style/XStyle.hpp>
22 #include <com/sun/star/lang/IndexOutOfBoundsException.hpp>
23 #include <com/sun/star/lang/XServiceInfo.hpp>
24 #include <com/sun/star/lang/XComponent.hpp>
25 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
26 #include <com/sun/star/container/XIndexAccess.hpp>
27 #include <com/sun/star/container/XNameContainer.hpp>
28 #include <com/sun/star/beans/XPropertySet.hpp>
29 #include <com/sun/star/util/XModifyBroadcaster.hpp>
30 #include <com/sun/star/util/XModifyListener.hpp>
32 #include <osl/mutex.hxx>
33 #include <vcl/svapp.hxx>
35 #include <cppuhelper/basemutex.hxx>
36 #include <cppuhelper/compbase.hxx>
37 #include <cppuhelper/implbase.hxx>
38 #include <cppuhelper/interfacecontainer.h>
39 #include <cppuhelper/supportsservice.hxx>
40 #include <comphelper/sequence.hxx>
42 #include <svx/unoprov.hxx>
43 #include <svx/sdr/table/tabledesign.hxx>
44 #include <svx/dialmgr.hxx>
45 #include <svx/strings.hrc>
47 #include <celltypes.hxx>
49 #include <vector>
50 #include <map>
53 using namespace ::com::sun::star::uno;
54 using namespace ::com::sun::star::style;
55 using namespace ::com::sun::star::lang;
56 using namespace ::com::sun::star::beans;
57 using namespace ::com::sun::star::util;
58 using namespace ::com::sun::star::container;
60 using ::osl::MutexGuard;
61 using ::osl::ClearableMutexGuard;
62 using ::cppu::OInterfaceContainerHelper;
64 namespace sdr { namespace table {
66 typedef std::map< OUString, sal_Int32 > CellStyleNameMap;
68 typedef ::cppu::WeakComponentImplHelper< XStyle, XNameReplace, XServiceInfo, XIndexAccess, XModifyBroadcaster, XModifyListener > TableDesignStyleBase;
70 class TableDesignStyle : private ::cppu::BaseMutex, public TableDesignStyleBase
72 public:
73 TableDesignStyle();
75 // XServiceInfo
76 virtual OUString SAL_CALL getImplementationName() override;
77 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
78 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
80 // XStyle
81 virtual sal_Bool SAL_CALL isUserDefined() override;
82 virtual sal_Bool SAL_CALL isInUse() override;
83 virtual OUString SAL_CALL getParentStyle() override;
84 virtual void SAL_CALL setParentStyle( const OUString& aParentStyle ) override;
86 // XNamed
87 virtual OUString SAL_CALL getName() override;
88 virtual void SAL_CALL setName( const OUString& aName ) override;
90 // XNameAccess
91 virtual Any SAL_CALL getByName( const OUString& aName ) override;
92 virtual Sequence< OUString > SAL_CALL getElementNames() override;
93 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
95 // XElementAccess
96 virtual css::uno::Type SAL_CALL getElementType() override;
97 virtual sal_Bool SAL_CALL hasElements() override;
99 // XIndexAccess
100 virtual sal_Int32 SAL_CALL getCount() override ;
101 virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override;
103 // XNameReplace
104 virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement ) override;
106 // XModifyBroadcaster
107 virtual void SAL_CALL addModifyListener( const Reference< XModifyListener >& aListener ) override;
108 virtual void SAL_CALL removeModifyListener( const Reference< XModifyListener >& aListener ) override;
110 // XModifyListener
111 virtual void SAL_CALL modified( const css::lang::EventObject& aEvent ) override;
112 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
114 void notifyModifyListener();
116 // this function is called upon disposing the component
117 virtual void SAL_CALL disposing() override;
119 static const CellStyleNameMap& getCellStyleNameMap();
121 OUString msName;
122 Reference< XStyle > maCellStyles[style_count];
125 typedef std::vector< Reference< XStyle > > TableDesignStyleVector;
127 class TableDesignFamily : public ::cppu::WeakImplHelper< XNameContainer, XNamed, XIndexAccess, XSingleServiceFactory, XServiceInfo, XComponent, XPropertySet >
129 public:
130 // XServiceInfo
131 virtual OUString SAL_CALL getImplementationName() override;
132 virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) override;
133 virtual Sequence< OUString > SAL_CALL getSupportedServiceNames() override;
135 // XNamed
136 virtual OUString SAL_CALL getName( ) override;
137 virtual void SAL_CALL setName( const OUString& aName ) override;
139 // XNameAccess
140 virtual Any SAL_CALL getByName( const OUString& aName ) override;
141 virtual Sequence< OUString > SAL_CALL getElementNames() override;
142 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
144 // XElementAccess
145 virtual Type SAL_CALL getElementType() override;
146 virtual sal_Bool SAL_CALL hasElements() override;
148 // XIndexAccess
149 virtual sal_Int32 SAL_CALL getCount() override ;
150 virtual Any SAL_CALL getByIndex( sal_Int32 Index ) override;
152 // XNameContainer
153 virtual void SAL_CALL insertByName( const OUString& aName, const Any& aElement ) override;
154 virtual void SAL_CALL removeByName( const OUString& Name ) override;
156 // XNameReplace
157 virtual void SAL_CALL replaceByName( const OUString& aName, const Any& aElement ) override;
159 // XSingleServiceFactory
160 virtual Reference< XInterface > SAL_CALL createInstance( ) override;
161 virtual Reference< XInterface > SAL_CALL createInstanceWithArguments( const Sequence< Any >& aArguments ) override;
163 // XComponent
164 virtual void SAL_CALL dispose( ) override;
165 virtual void SAL_CALL addEventListener( const Reference< XEventListener >& xListener ) override;
166 virtual void SAL_CALL removeEventListener( const Reference< XEventListener >& aListener ) override;
168 // XPropertySet
169 virtual Reference<XPropertySetInfo> SAL_CALL getPropertySetInfo() override;
170 virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) override;
171 virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
172 virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference<XPropertyChangeListener>& xListener ) override;
173 virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference<XPropertyChangeListener>& aListener ) override;
174 virtual void SAL_CALL addVetoableChangeListener(const OUString& PropertyName, const Reference<XVetoableChangeListener>& aListener ) override;
175 virtual void SAL_CALL removeVetoableChangeListener(const OUString& PropertyName,const Reference<XVetoableChangeListener>&aListener ) override;
177 TableDesignStyleVector maDesigns;
180 TableDesignStyle::TableDesignStyle()
181 : TableDesignStyleBase(m_aMutex)
185 const CellStyleNameMap& TableDesignStyle::getCellStyleNameMap()
187 static CellStyleNameMap const aMap
189 { OUString( "first-row" ) , first_row_style },
190 { OUString( "last-row" ) , last_row_style },
191 { OUString( "first-column" ) , first_column_style },
192 { OUString( "last-column" ) , last_column_style },
193 { OUString( "body" ) , body_style },
194 { OUString( "even-rows" ) , even_rows_style },
195 { OUString( "odd-rows" ) , odd_rows_style },
196 { OUString( "even-columns" ) , even_columns_style },
197 { OUString( "odd-columns" ) , odd_columns_style },
198 { OUString( "background" ) , background_style },
201 return aMap;
204 // XServiceInfo
205 OUString SAL_CALL TableDesignStyle::getImplementationName()
207 return "TableDesignStyle";
210 sal_Bool SAL_CALL TableDesignStyle::supportsService( const OUString& ServiceName )
212 return cppu::supportsService( this, ServiceName );
215 Sequence< OUString > SAL_CALL TableDesignStyle::getSupportedServiceNames()
217 return { "com.sun.star.style.Style" };
220 // XStyle
221 sal_Bool SAL_CALL TableDesignStyle::isUserDefined()
223 return false;
226 sal_Bool SAL_CALL TableDesignStyle::isInUse()
228 ClearableMutexGuard aGuard( rBHelper.rMutex );
229 OInterfaceContainerHelper * pContainer = rBHelper.getContainer( cppu::UnoType<XModifyListener>::get() );
230 if( pContainer )
232 Sequence< Reference< XInterface > > aListener( pContainer->getElements() );
233 aGuard.clear();
235 sal_Int32 nIndex = aListener.getLength();
236 while( --nIndex >= 0 )
238 TableDesignUser* pUser = dynamic_cast< TableDesignUser* >( aListener[nIndex].get() );
239 if( pUser && pUser->isInUse() )
240 return true;
243 return false;
247 OUString SAL_CALL TableDesignStyle::getParentStyle()
249 return OUString();
253 void SAL_CALL TableDesignStyle::setParentStyle( const OUString& )
258 // XNamed
261 OUString SAL_CALL TableDesignStyle::getName()
263 return msName;
267 void SAL_CALL TableDesignStyle::setName( const OUString& rName )
269 msName = rName;
273 // XNameAccess
276 Any SAL_CALL TableDesignStyle::getByName( const OUString& rName )
278 SolarMutexGuard aGuard;
280 const CellStyleNameMap& rMap = getCellStyleNameMap();
282 CellStyleNameMap::const_iterator iter = rMap.find( rName );
283 if( iter == rMap.end() )
284 throw NoSuchElementException();
286 return Any( maCellStyles[(*iter).second] );
290 Sequence< OUString > SAL_CALL TableDesignStyle::getElementNames()
292 SolarMutexGuard aGuard;
294 return comphelper::mapKeysToSequence( getCellStyleNameMap() );
298 sal_Bool SAL_CALL TableDesignStyle::hasByName( const OUString& rName )
300 SolarMutexGuard aGuard;
302 const CellStyleNameMap& rMap = getCellStyleNameMap();
304 CellStyleNameMap::const_iterator iter = rMap.find( rName );
305 return iter != rMap.end();
309 // XElementAccess
312 Type SAL_CALL TableDesignStyle::getElementType()
314 return cppu::UnoType<XStyle>::get();
318 sal_Bool SAL_CALL TableDesignStyle::hasElements()
320 return true;
324 // XIndexAccess
327 sal_Int32 SAL_CALL TableDesignStyle::getCount()
329 return style_count;
333 Any SAL_CALL TableDesignStyle::getByIndex( sal_Int32 Index )
335 SolarMutexGuard aGuard;
337 if( (Index < 0) || (Index >= style_count) )
338 throw IndexOutOfBoundsException();
340 return Any( maCellStyles[Index] );
344 // XNameReplace
347 void SAL_CALL TableDesignStyle::replaceByName( const OUString& rName, const Any& aElement )
349 SolarMutexGuard aGuard;
351 const CellStyleNameMap& rMap = getCellStyleNameMap();
352 CellStyleNameMap::const_iterator iter = rMap.find( rName );
353 if( iter == rMap.end() )
354 throw NoSuchElementException();
357 Reference< XStyle > xNewStyle;
358 if( !(aElement >>= xNewStyle) )
359 throw IllegalArgumentException();
361 const sal_Int32 nIndex = (*iter).second;
363 Reference< XStyle > xOldStyle( maCellStyles[nIndex] );
365 if( xNewStyle != xOldStyle )
367 Reference< XModifyListener > xListener( this );
369 // end listening to old style, if possible
370 Reference< XModifyBroadcaster > xOldBroadcaster( xOldStyle, UNO_QUERY );
371 if( xOldBroadcaster.is() )
372 xOldBroadcaster->removeModifyListener( xListener );
374 // start listening to new style, if possible
375 Reference< XModifyBroadcaster > xNewBroadcaster( xNewStyle, UNO_QUERY );
376 if( xNewBroadcaster.is() )
377 xNewBroadcaster->addModifyListener( xListener );
379 maCellStyles[nIndex] = xNewStyle;
384 // XComponent
387 void SAL_CALL TableDesignStyle::disposing()
389 for(Reference<XStyle> & rCellStyle : maCellStyles)
390 rCellStyle.clear();
394 // XModifyBroadcaster
397 void SAL_CALL TableDesignStyle::addModifyListener( const Reference< XModifyListener >& xListener )
399 ClearableMutexGuard aGuard( rBHelper.rMutex );
400 if (rBHelper.bDisposed || rBHelper.bInDispose)
402 aGuard.clear();
403 EventObject aEvt( static_cast< OWeakObject * >( this ) );
404 xListener->disposing( aEvt );
406 else
408 rBHelper.addListener( cppu::UnoType<XModifyListener>::get(), xListener );
413 void SAL_CALL TableDesignStyle::removeModifyListener( const Reference< XModifyListener >& xListener )
415 rBHelper.removeListener( cppu::UnoType<XModifyListener>::get(), xListener );
419 void TableDesignStyle::notifyModifyListener()
421 MutexGuard aGuard( rBHelper.rMutex );
423 OInterfaceContainerHelper * pContainer = rBHelper.getContainer( cppu::UnoType<XModifyListener>::get() );
424 if( pContainer )
426 EventObject aEvt( static_cast< OWeakObject * >( this ) );
427 pContainer->forEach<XModifyListener>(
428 [&] (Reference<XModifyListener> const& xListener)
429 { return xListener->modified(aEvt); });
434 // XModifyListener
437 // if we get a modify hint from a style, notify all registered XModifyListener
438 void SAL_CALL TableDesignStyle::modified( const css::lang::EventObject& )
440 notifyModifyListener();
444 void SAL_CALL TableDesignStyle::disposing( const css::lang::EventObject& )
449 // TableStyle
452 // XServiceInfo
453 OUString SAL_CALL TableDesignFamily::getImplementationName()
455 return "TableDesignFamily";
458 sal_Bool SAL_CALL TableDesignFamily::supportsService( const OUString& ServiceName )
460 return cppu::supportsService( this, ServiceName );
463 Sequence< OUString > SAL_CALL TableDesignFamily::getSupportedServiceNames()
465 return { "com.sun.star.style.StyleFamily" };
468 // XNamed
469 OUString SAL_CALL TableDesignFamily::getName()
471 return "table";
474 void SAL_CALL TableDesignFamily::setName( const OUString& )
478 // XNameAccess
479 Any SAL_CALL TableDesignFamily::getByName( const OUString& rName )
481 SolarMutexGuard aGuard;
483 auto iter = std::find_if(maDesigns.begin(), maDesigns.end(),
484 [&rName](const Reference<XStyle>& rpStyle) { return rpStyle->getName() == rName; });
485 if (iter != maDesigns.end())
486 return Any( (*iter) );
488 throw NoSuchElementException();
492 Sequence< OUString > SAL_CALL TableDesignFamily::getElementNames()
494 SolarMutexGuard aGuard;
496 Sequence< OUString > aRet( maDesigns.size() );
497 OUString* pNames = aRet.getArray();
499 for( const auto& rpStyle : maDesigns )
500 *pNames++ = rpStyle->getName();
502 return aRet;
506 sal_Bool SAL_CALL TableDesignFamily::hasByName( const OUString& aName )
508 SolarMutexGuard aGuard;
510 return std::any_of(maDesigns.begin(), maDesigns.end(),
511 [&aName](const Reference<XStyle>& rpStyle) { return rpStyle->getName() == aName; });
515 // XElementAccess
518 Type SAL_CALL TableDesignFamily::getElementType()
520 return cppu::UnoType<XStyle>::get();
524 sal_Bool SAL_CALL TableDesignFamily::hasElements()
526 SolarMutexGuard aGuard;
528 return !maDesigns.empty();
532 // XIndexAccess
535 sal_Int32 SAL_CALL TableDesignFamily::getCount()
537 SolarMutexGuard aGuard;
539 return sal::static_int_cast< sal_Int32 >( maDesigns.size() );
543 Any SAL_CALL TableDesignFamily::getByIndex( sal_Int32 Index )
545 SolarMutexGuard aGuard;
547 if( (Index >= 0) && (Index < sal::static_int_cast< sal_Int32 >( maDesigns.size() ) ) )
548 return Any( maDesigns[Index] );
550 throw IndexOutOfBoundsException();
554 // XNameContainer
557 void SAL_CALL TableDesignFamily::insertByName( const OUString& rName, const Any& rElement )
559 SolarMutexGuard aGuard;
561 Reference< XStyle > xStyle( rElement, UNO_QUERY );
562 if( !xStyle.is() )
563 throw IllegalArgumentException();
565 xStyle->setName( rName );
566 if (std::any_of(maDesigns.begin(), maDesigns.end(),
567 [&rName](const Reference<XStyle>& rpStyle) { return rpStyle->getName() == rName; }))
568 throw ElementExistException();
570 maDesigns.push_back( xStyle );
574 void SAL_CALL TableDesignFamily::removeByName( const OUString& rName )
576 SolarMutexGuard aGuard;
578 auto iter = std::find_if(maDesigns.begin(), maDesigns.end(),
579 [&rName](const Reference<XStyle>& rpStyle) { return rpStyle->getName() == rName; });
580 if (iter != maDesigns.end())
582 maDesigns.erase( iter );
583 return;
586 throw NoSuchElementException();
590 // XNameReplace
593 void SAL_CALL TableDesignFamily::replaceByName( const OUString& rName, const Any& aElement )
595 SolarMutexGuard aGuard;
597 Reference< XStyle > xStyle( aElement, UNO_QUERY );
598 if( !xStyle.is() )
599 throw IllegalArgumentException();
601 auto iter = std::find_if(maDesigns.begin(), maDesigns.end(),
602 [&rName](const Reference<XStyle>& rpStyle) { return rpStyle->getName() == rName; });
603 if (iter != maDesigns.end())
605 (*iter) = xStyle;
606 xStyle->setName( rName );
607 return;
610 throw NoSuchElementException();
614 // XSingleServiceFactory
617 Reference< XInterface > SAL_CALL TableDesignFamily::createInstance()
619 SolarMutexGuard aGuard;
621 return Reference< XInterface >( static_cast< XStyle* >( new TableDesignStyle ) );
625 Reference< XInterface > SAL_CALL TableDesignFamily::createInstanceWithArguments( const Sequence< Any >& )
627 return createInstance();
631 // XComponent
634 void SAL_CALL TableDesignFamily::dispose( )
636 TableDesignStyleVector aDesigns;
637 aDesigns.swap( maDesigns );
639 for( const auto& rStyle : aDesigns )
641 Reference< XComponent > xComp( rStyle, UNO_QUERY );
642 if( xComp.is() )
643 xComp->dispose();
648 void SAL_CALL TableDesignFamily::addEventListener( const Reference< XEventListener >& )
653 void SAL_CALL TableDesignFamily::removeEventListener( const Reference< XEventListener >& )
658 // XPropertySet
661 Reference<XPropertySetInfo> TableDesignFamily::getPropertySetInfo()
663 OSL_FAIL( "###unexpected!" );
664 return Reference<XPropertySetInfo>();
668 void TableDesignFamily::setPropertyValue( const OUString& , const Any& )
670 OSL_FAIL( "###unexpected!" );
674 Any TableDesignFamily::getPropertyValue( const OUString& PropertyName )
676 if ( PropertyName != "DisplayName" )
678 throw UnknownPropertyException( "unknown property: " + PropertyName, static_cast<OWeakObject *>(this) );
681 OUString sDisplayName( SvxResId( RID_SVXSTR_STYLEFAMILY_TABLEDESIGN ) );
682 return Any( sDisplayName );
686 void TableDesignFamily::addPropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& )
688 OSL_FAIL( "###unexpected!" );
692 void TableDesignFamily::removePropertyChangeListener( const OUString& , const Reference<XPropertyChangeListener>& )
694 OSL_FAIL( "###unexpected!" );
698 void TableDesignFamily::addVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& )
700 OSL_FAIL( "###unexpected!" );
704 void TableDesignFamily::removeVetoableChangeListener( const OUString& , const Reference<XVetoableChangeListener>& )
706 OSL_FAIL( "###unexpected!" );
710 Reference< XNameAccess > CreateTableDesignFamily()
712 return new TableDesignFamily;
717 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */