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/beans/XPropertyState.hpp>
21 #include <PropertySetMerger.hxx>
22 
23 using namespace ::com::sun::star;
24 using namespace ::com::sun::star::uno;
25 using namespace ::com::sun::star::beans;
26 using namespace ::com::sun::star::lang;
27 
28 #include <comphelper/sequence.hxx>
29 #include <cppuhelper/implbase3.hxx>
30 
31 class PropertySetMergerImpl : public ::cppu::WeakAggImplHelper3< XPropertySet, XPropertyState, XPropertySetInfo >
32 {
33 private:
34     Reference< XPropertySet > mxPropSet1;
35     Reference< XPropertyState > mxPropSet1State;
36     Reference< XPropertySetInfo > mxPropSet1Info;
37 
38     Reference< XPropertySet > mxPropSet2;
39     Reference< XPropertyState > mxPropSet2State;
40     Reference< XPropertySetInfo > mxPropSet2Info;
41 
42 public:
43     PropertySetMergerImpl( const Reference< XPropertySet > & rPropSet1, const Reference< XPropertySet > & rPropSet2 );
44 
45     // XPropertySet
46     virtual Reference< XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) override;
47     virtual void SAL_CALL setPropertyValue( const OUString& aPropertyName, const Any& aValue ) override;
48     virtual Any SAL_CALL getPropertyValue( const OUString& PropertyName ) override;
49     virtual void SAL_CALL addPropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& xListener ) override;
50     virtual void SAL_CALL removePropertyChangeListener( const OUString& aPropertyName, const Reference< XPropertyChangeListener >& aListener ) override;
51     virtual void SAL_CALL addVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override;
52     virtual void SAL_CALL removeVetoableChangeListener( const OUString& PropertyName, const Reference< XVetoableChangeListener >& aListener ) override;
53 
54     // XPropertyState
55     virtual PropertyState SAL_CALL getPropertyState( const OUString& PropertyName ) override;
56     virtual Sequence< PropertyState > SAL_CALL getPropertyStates( const Sequence< OUString >& aPropertyName ) override;
57     virtual void SAL_CALL setPropertyToDefault( const OUString& PropertyName ) override;
58     virtual Any SAL_CALL getPropertyDefault( const OUString& aPropertyName ) override;
59 
60     // XPropertySetInfo
61     virtual Sequence< Property > SAL_CALL getProperties(  ) override;
62     virtual Property SAL_CALL getPropertyByName( const OUString& aName ) override;
63     virtual sal_Bool SAL_CALL hasPropertyByName( const OUString& Name ) override;
64 };
65 
66 // Interface implementation
67 
PropertySetMergerImpl(Reference<XPropertySet> const & rPropSet1,Reference<XPropertySet> const & rPropSet2)68 PropertySetMergerImpl::PropertySetMergerImpl( Reference< XPropertySet > const & rPropSet1, Reference< XPropertySet > const & rPropSet2 )
69 : mxPropSet1( rPropSet1 )
70 , mxPropSet1State( rPropSet1, UNO_QUERY )
71 , mxPropSet1Info( rPropSet1->getPropertySetInfo() )
72 , mxPropSet2( rPropSet2 )
73 , mxPropSet2State( rPropSet2, UNO_QUERY )
74 , mxPropSet2Info( rPropSet2->getPropertySetInfo() )
75 {
76 }
77 
78 // XPropertySet
getPropertySetInfo()79 Reference< XPropertySetInfo > SAL_CALL PropertySetMergerImpl::getPropertySetInfo(  )
80 {
81     return this;
82 }
83 
setPropertyValue(const OUString & aPropertyName,const Any & aValue)84 void SAL_CALL PropertySetMergerImpl::setPropertyValue( const OUString& aPropertyName, const Any& aValue )
85 {
86     if( mxPropSet1Info->hasPropertyByName( aPropertyName ) )
87     {
88         mxPropSet1->setPropertyValue( aPropertyName, aValue );
89     }
90     else
91     {
92         mxPropSet2->setPropertyValue( aPropertyName, aValue );
93     }
94 }
95 
getPropertyValue(const OUString & PropertyName)96 Any SAL_CALL PropertySetMergerImpl::getPropertyValue( const OUString& PropertyName )
97 {
98     if( mxPropSet1Info->hasPropertyByName( PropertyName ) )
99     {
100         return mxPropSet1->getPropertyValue( PropertyName );
101     }
102     else
103     {
104         return mxPropSet2->getPropertyValue( PropertyName );
105     }
106 }
107 
addPropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)108 void SAL_CALL PropertySetMergerImpl::addPropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*xListener*/ )
109 {
110 }
111 
removePropertyChangeListener(const OUString &,const Reference<XPropertyChangeListener> &)112 void SAL_CALL PropertySetMergerImpl::removePropertyChangeListener( const OUString& /*aPropertyName*/, const Reference< XPropertyChangeListener >& /*aListener*/ )
113 {
114 }
115 
addVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)116 void SAL_CALL PropertySetMergerImpl::addVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
117 {
118 }
119 
removeVetoableChangeListener(const OUString &,const Reference<XVetoableChangeListener> &)120 void SAL_CALL PropertySetMergerImpl::removeVetoableChangeListener( const OUString& /*PropertyName*/, const Reference< XVetoableChangeListener >& /*aListener*/ )
121 {
122 }
123 
124 // XPropertyState
getPropertyState(const OUString & PropertyName)125 PropertyState SAL_CALL PropertySetMergerImpl::getPropertyState( const OUString& PropertyName )
126 {
127     if( mxPropSet1Info->hasPropertyByName( PropertyName ) )
128     {
129         if( mxPropSet1State.is() )
130         {
131             return mxPropSet1State->getPropertyState( PropertyName );
132         }
133         else
134         {
135             return PropertyState_DIRECT_VALUE;
136         }
137     }
138     else
139     {
140         if( mxPropSet2State.is() )
141         {
142             return mxPropSet2State->getPropertyState( PropertyName );
143         }
144         else
145         {
146             return PropertyState_DIRECT_VALUE;
147         }
148     }
149 }
150 
getPropertyStates(const Sequence<OUString> & aPropertyName)151 Sequence< PropertyState > SAL_CALL PropertySetMergerImpl::getPropertyStates( const Sequence< OUString >& aPropertyName )
152 {
153     const sal_Int32 nCount = aPropertyName.getLength();
154     Sequence< PropertyState > aPropStates( nCount );
155 
156     std::transform(aPropertyName.begin(), aPropertyName.end(), aPropStates.begin(),
157         [this](const OUString& rPropName) -> PropertyState { return getPropertyState(rPropName); });
158 
159     return aPropStates;
160 }
161 
setPropertyToDefault(const OUString & PropertyName)162 void SAL_CALL PropertySetMergerImpl::setPropertyToDefault( const OUString& PropertyName )
163 {
164     if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( PropertyName ) )
165     {
166         mxPropSet1State->setPropertyToDefault( PropertyName );
167     }
168     else
169     {
170         if( mxPropSet2State.is() )
171         {
172             mxPropSet2State->setPropertyToDefault( PropertyName );
173         }
174     }
175 }
176 
getPropertyDefault(const OUString & aPropertyName)177 Any SAL_CALL PropertySetMergerImpl::getPropertyDefault( const OUString& aPropertyName )
178 {
179     if( mxPropSet1State.is() && mxPropSet1Info->hasPropertyByName( aPropertyName ) )
180     {
181         return mxPropSet1State->getPropertyDefault( aPropertyName );
182     }
183     else
184     {
185         if( mxPropSet2State.is() )
186         {
187             return mxPropSet2State->getPropertyDefault( aPropertyName );
188         }
189         else
190         {
191             Any aAny;
192             return aAny;
193         }
194     }
195 }
196 
197 // XPropertySetInfo
getProperties()198 Sequence< Property > SAL_CALL PropertySetMergerImpl::getProperties()
199 {
200     Sequence< Property > aProps1( mxPropSet1Info->getProperties() );
201     Sequence< Property > aProps2( mxPropSet2Info->getProperties() );
202 
203     return comphelper::concatSequences(aProps1, aProps2);
204 }
205 
getPropertyByName(const OUString & aName)206 Property SAL_CALL PropertySetMergerImpl::getPropertyByName( const OUString& aName )
207 {
208     if( mxPropSet1Info->hasPropertyByName( aName ) )
209         return mxPropSet1Info->getPropertyByName( aName );
210 
211     return mxPropSet2Info->getPropertyByName( aName );
212 }
213 
hasPropertyByName(const OUString & Name)214 sal_Bool SAL_CALL PropertySetMergerImpl::hasPropertyByName( const OUString& Name )
215 {
216     if(mxPropSet1Info->hasPropertyByName( Name ) )
217         return true;
218 
219     return mxPropSet2Info->hasPropertyByName( Name );
220 }
221 
PropertySetMerger_CreateInstance(const Reference<XPropertySet> & rPropSet1,const Reference<XPropertySet> & rPropSet2)222 Reference< XPropertySet > PropertySetMerger_CreateInstance( const Reference< XPropertySet >& rPropSet1, const Reference< XPropertySet >& rPropSet2 ) throw()
223 {
224     return new PropertySetMergerImpl( rPropSet1, rPropSet2 );
225 }
226 
227 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
228