1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 #include "gridcolumnproptranslator.hxx"
27 
28 /** === begin UNO includes === **/
29 #include <com/sun/star/beans/XPropertySetInfo.hpp>
30 #include <com/sun/star/awt/TextAlign.hpp>
31 #include <com/sun/star/style/ParagraphAdjust.hpp>
32 /** === end UNO includes === **/
33 #include <osl/diagnose.h>
34 #include <cppuhelper/implbase1.hxx>
35 
36 #include <algorithm>
37 
38 //........................................................................
39 namespace xmloff
40 {
41 //........................................................................
42 
43     using namespace ::com::sun::star::uno;
44     using namespace ::com::sun::star::awt;
45     using namespace ::com::sun::star::lang;
46     using namespace ::com::sun::star::beans;
47     using namespace ::com::sun::star::style;
48 
49     namespace
50     {
51 	    //----------------------------------------------------------------
getParaAlignProperty()52         ::rtl::OUString getParaAlignProperty()
53         {
54             return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "ParaAdjust" ) );
55         }
56 
57 	    //----------------------------------------------------------------
getAlignProperty()58         ::rtl::OUString getAlignProperty()
59         {
60             return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Align" ) );
61         }
62 
63 	    //----------------------------------------------------------------
findStringElement(const Sequence<::rtl::OUString> & _rNames,const::rtl::OUString & _rName)64         sal_Int32 findStringElement( const Sequence< ::rtl::OUString >& _rNames, const ::rtl::OUString& _rName )
65         {
66             const ::rtl::OUString* pStart = _rNames.getConstArray();
67             const ::rtl::OUString* pEnd = _rNames.getConstArray() + _rNames.getLength();
68             const ::rtl::OUString* pPos = ::std::find( pStart, pEnd, _rName );
69             if ( pPos != pEnd )
70                 return pPos - pStart;
71             return -1;
72         }
73 
74 	    //----------------------------------------------------------------
75         struct AlignmentTranslationEntry
76         {
77             ParagraphAdjust nParagraphValue;
78             sal_Int16       nControlValue;
79         }
80         AlignmentTranslations[] =
81         {
82             // note that order matters:
83             // valueAlignToParaAdjust and valueParaAdjustToAlign search this map from the _beginning_
84             // and use the first matching entry
85             { ParagraphAdjust_LEFT,             TextAlign::LEFT     },
86             { ParagraphAdjust_CENTER,           TextAlign::CENTER   },
87             { ParagraphAdjust_RIGHT,            TextAlign::RIGHT    },
88             { ParagraphAdjust_BLOCK,            TextAlign::RIGHT    },
89             { ParagraphAdjust_STRETCH,          TextAlign::LEFT     },
90             { ParagraphAdjust_MAKE_FIXED_SIZE,  TextAlign::LEFT     },
91             { ParagraphAdjust_MAKE_FIXED_SIZE,  -1 }
92         };
93 
94 	    //----------------------------------------------------------------
valueAlignToParaAdjust(Any & rValue)95         void valueAlignToParaAdjust(Any& rValue)
96         {
97             sal_Int16 nValue = 0;
98             rValue >>= nValue;
99             const AlignmentTranslationEntry* pTranslation = AlignmentTranslations;
100             while (-1 != pTranslation->nControlValue)
101             {
102                 if ( nValue == pTranslation->nControlValue )
103                 {
104                     rValue <<= pTranslation->nParagraphValue;
105                     return;
106                 }
107                 ++pTranslation;
108             }
109             OSL_ENSURE( sal_False, "valueAlignToParaAdjust: unreachable!" );
110         }
111 
112 	    //----------------------------------------------------------------
valueParaAdjustToAlign(Any & rValue)113         void valueParaAdjustToAlign(Any& rValue)
114         {
115             sal_Int32 nValue = 0;
116             rValue >>= nValue;
117             const AlignmentTranslationEntry* pTranslation = AlignmentTranslations;
118             while ( ParagraphAdjust_MAKE_FIXED_SIZE != pTranslation->nParagraphValue)
119             {
120                 if ( nValue == pTranslation->nParagraphValue)
121                 {
122                     rValue <<= pTranslation->nControlValue;
123                     return;
124                 }
125                 ++pTranslation;
126             }
127             OSL_ENSURE( sal_False, "valueParaAdjustToAlign: unreachable!" );
128         }
129 
130         //====================================================================
131 	    //= OMergedPropertySetInfo
132 	    //====================================================================
133         typedef ::cppu::WeakAggImplHelper1  <   XPropertySetInfo
134                                             >   OMergedPropertySetInfo_Base;
135         class OMergedPropertySetInfo : public OMergedPropertySetInfo_Base
136         {
137         private:
138             Reference< XPropertySetInfo >   m_xMasterInfo;
139 
140         public:
141             OMergedPropertySetInfo( const Reference< XPropertySetInfo >& _rxMasterInfo );
142 
143         protected:
144             virtual ~OMergedPropertySetInfo();
145 
146             // XPropertySetInfo
147             virtual ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property > SAL_CALL getProperties(  ) throw (::com::sun::star::uno::RuntimeException);
148             virtual ::com::sun::star::beans::Property SAL_CALL getPropertyByName( const ::rtl::OUString& aName ) throw (::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::uno::RuntimeException);
149             virtual ::sal_Bool SAL_CALL hasPropertyByName( const ::rtl::OUString& Name ) throw (::com::sun::star::uno::RuntimeException);
150         };
151 
152         //----------------------------------------------------------------
OMergedPropertySetInfo(const Reference<XPropertySetInfo> & _rxMasterInfo)153         OMergedPropertySetInfo::OMergedPropertySetInfo( const Reference< XPropertySetInfo >& _rxMasterInfo )
154             :m_xMasterInfo( _rxMasterInfo )
155         {
156             OSL_ENSURE( m_xMasterInfo.is(), "OMergedPropertySetInfo::OMergedPropertySetInfo: hmm?" );
157         }
158 
159         //----------------------------------------------------------------
~OMergedPropertySetInfo()160         OMergedPropertySetInfo::~OMergedPropertySetInfo()
161         {
162         }
163 
164         //----------------------------------------------------------------
getProperties()165         Sequence< Property > SAL_CALL OMergedPropertySetInfo::getProperties(  ) throw (RuntimeException)
166         {
167             // add a "ParaAdjust" property to the master properties
168             Sequence< Property > aProperties;
169             if ( m_xMasterInfo.is() )
170                 aProperties = m_xMasterInfo->getProperties();
171 
172             sal_Int32 nOldLength = aProperties.getLength();
173             aProperties.realloc( nOldLength + 1 );
174             aProperties[ nOldLength ] = getPropertyByName( getParaAlignProperty() );
175 
176             return aProperties;
177         }
178 
179         //----------------------------------------------------------------
getPropertyByName(const::rtl::OUString & aName)180         Property SAL_CALL OMergedPropertySetInfo::getPropertyByName( const ::rtl::OUString& aName ) throw (UnknownPropertyException, RuntimeException)
181         {
182             if ( aName == getParaAlignProperty() )
183                 return Property( getParaAlignProperty(), -1,
184                     ::getCppuType( static_cast< const ParagraphAdjust* >( NULL ) ), 0 );
185 
186             if ( !m_xMasterInfo.is() )
187                 return Property();
188 
189             return m_xMasterInfo->getPropertyByName( aName );
190         }
191 
192         //----------------------------------------------------------------
hasPropertyByName(const::rtl::OUString & Name)193         ::sal_Bool SAL_CALL OMergedPropertySetInfo::hasPropertyByName( const ::rtl::OUString& Name ) throw (RuntimeException)
194         {
195             if ( Name == getParaAlignProperty() )
196                 return sal_True;
197 
198             if ( !m_xMasterInfo.is() )
199                 return sal_False;
200 
201             return m_xMasterInfo->hasPropertyByName( Name );
202         }
203     }
204 
205 
206 	//====================================================================
207 	//= OGridColumnPropertyTranslator
208 	//====================================================================
209 	//--------------------------------------------------------------------
OGridColumnPropertyTranslator(const Reference<XMultiPropertySet> & _rxGridColumn)210     OGridColumnPropertyTranslator::OGridColumnPropertyTranslator( const Reference< XMultiPropertySet >& _rxGridColumn )
211         :m_xGridColumn( _rxGridColumn )
212     {
213         OSL_ENSURE( m_xGridColumn.is(), "OGridColumnPropertyTranslator: invalid grid column!" );
214     }
215 
216 	//--------------------------------------------------------------------
~OGridColumnPropertyTranslator()217     OGridColumnPropertyTranslator::~OGridColumnPropertyTranslator()
218     {
219     }
220 
221     //--------------------------------------------------------------------
getPropertySetInfo()222     Reference< XPropertySetInfo > SAL_CALL OGridColumnPropertyTranslator::getPropertySetInfo(  ) throw (RuntimeException)
223     {
224         Reference< XPropertySetInfo > xColumnPropInfo;
225         if ( m_xGridColumn.is() )
226             xColumnPropInfo = m_xGridColumn->getPropertySetInfo();
227         return new OMergedPropertySetInfo( xColumnPropInfo );
228     }
229 
230     //--------------------------------------------------------------------
setPropertyValue(const::rtl::OUString & _rPropertyName,const Any & aValue)231     void SAL_CALL OGridColumnPropertyTranslator::setPropertyValue( const ::rtl::OUString& _rPropertyName, const Any& aValue ) throw (UnknownPropertyException, PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
232     {
233         // we implement this by delegating it to setPropertyValues, which is to ignore unknown properties. On the other hand, our
234         // contract requires us to throw a UnknownPropertyException for unknown properties, so check this first.
235 
236         if ( !getPropertySetInfo()->hasPropertyByName( _rPropertyName ) )
237             throw UnknownPropertyException( _rPropertyName, *this );
238 
239         Sequence< ::rtl::OUString > aNames( &_rPropertyName, 1 );
240         Sequence< Any >             aValues( &aValue, 1 );
241         setPropertyValues( aNames, aValues );
242     }
243 
244     //--------------------------------------------------------------------
getPropertyValue(const::rtl::OUString & PropertyName)245     Any SAL_CALL OGridColumnPropertyTranslator::getPropertyValue( const ::rtl::OUString& PropertyName ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
246     {
247         Sequence< ::rtl::OUString > aNames( &PropertyName, 1 );
248         Sequence< Any > aValues = getPropertyValues( aNames );
249         OSL_ENSURE( aValues.getLength() == 1, "OGridColumnPropertyTranslator::getPropertyValue: nonsense!" );
250         if ( aValues.getLength() == 1 )
251             return aValues[0];
252         return Any();
253     }
254 
255     //--------------------------------------------------------------------
addPropertyChangeListener(const::rtl::OUString &,const Reference<XPropertyChangeListener> &)256     void SAL_CALL OGridColumnPropertyTranslator::addPropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
257     {
258         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::addPropertyChangeListener: not implemented - this should not be needed!" );
259     }
260 
261     //--------------------------------------------------------------------
removePropertyChangeListener(const::rtl::OUString &,const Reference<XPropertyChangeListener> &)262     void SAL_CALL OGridColumnPropertyTranslator::removePropertyChangeListener( const ::rtl::OUString&, const Reference< XPropertyChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
263     {
264         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::removePropertyChangeListener: not implemented - this should not be needed!" );
265     }
266 
267     //--------------------------------------------------------------------
addVetoableChangeListener(const::rtl::OUString &,const Reference<XVetoableChangeListener> &)268     void SAL_CALL OGridColumnPropertyTranslator::addVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
269     {
270         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::addVetoableChangeListener: not implemented - this should not be needed!" );
271     }
272 
273     //--------------------------------------------------------------------
removeVetoableChangeListener(const::rtl::OUString &,const Reference<XVetoableChangeListener> &)274     void SAL_CALL OGridColumnPropertyTranslator::removeVetoableChangeListener( const ::rtl::OUString&, const Reference< XVetoableChangeListener >& ) throw (UnknownPropertyException, WrappedTargetException, RuntimeException)
275     {
276         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::removeVetoableChangeListener: not implemented - this should not be needed!" );
277     }
278 
279     //--------------------------------------------------------------------
setPropertyValues(const Sequence<::rtl::OUString> & aPropertyNames,const Sequence<Any> & aValues)280     void SAL_CALL OGridColumnPropertyTranslator::setPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames, const Sequence< Any >& aValues ) throw (PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException)
281     {
282         if ( !m_xGridColumn.is() )
283             return;
284 
285         // if there's ever the need for more than one property being translated, then we should
286         // certainly have a more clever implementation than this ...
287 
288         Sequence< ::rtl::OUString > aTranslatedNames( aPropertyNames );
289         Sequence< Any >             aTranslatedValues( aValues );
290 
291         sal_Int32 nParaAlignPos = findStringElement( aTranslatedNames, getParaAlignProperty() );
292         if ( nParaAlignPos != -1 )
293         {
294             aTranslatedNames[ nParaAlignPos ] = getAlignProperty();
295             valueParaAdjustToAlign( aTranslatedValues[ nParaAlignPos ] );
296         }
297 
298         m_xGridColumn->setPropertyValues( aTranslatedNames, aTranslatedValues );
299     }
300 
301     //--------------------------------------------------------------------
getPropertyValues(const Sequence<::rtl::OUString> & aPropertyNames)302     Sequence< Any > SAL_CALL OGridColumnPropertyTranslator::getPropertyValues( const Sequence< ::rtl::OUString >& aPropertyNames ) throw (RuntimeException)
303     {
304         Sequence< Any > aValues( aPropertyNames.getLength() );
305         if ( !m_xGridColumn.is() )
306             return aValues;
307 
308         Sequence< ::rtl::OUString > aTranslatedNames( aPropertyNames );
309         sal_Int32 nAlignPos = findStringElement( aTranslatedNames, getParaAlignProperty() );
310         if ( nAlignPos != -1 )
311             aTranslatedNames[ nAlignPos ] = getAlignProperty();
312 
313         aValues = m_xGridColumn->getPropertyValues( aPropertyNames );
314         if ( nAlignPos != -1 )
315             valueAlignToParaAdjust( aValues[ nAlignPos ] );
316 
317         return aValues;
318     }
319 
320     //--------------------------------------------------------------------
addPropertiesChangeListener(const Sequence<::rtl::OUString> &,const Reference<XPropertiesChangeListener> &)321     void SAL_CALL OGridColumnPropertyTranslator::addPropertiesChangeListener( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
322     {
323         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::addPropertiesChangeListener: not implemented - this should not be needed!" );
324     }
325 
326     //--------------------------------------------------------------------
removePropertiesChangeListener(const Reference<XPropertiesChangeListener> &)327     void SAL_CALL OGridColumnPropertyTranslator::removePropertiesChangeListener( const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
328     {
329         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::removePropertiesChangeListener: not implemented - this should not be needed!" );
330     }
331 
332     //--------------------------------------------------------------------
firePropertiesChangeEvent(const Sequence<::rtl::OUString> &,const Reference<XPropertiesChangeListener> &)333     void SAL_CALL OGridColumnPropertyTranslator::firePropertiesChangeEvent( const Sequence< ::rtl::OUString >&, const Reference< XPropertiesChangeListener >& ) throw (RuntimeException)
334     {
335         OSL_ENSURE( sal_False, "OGridColumnPropertyTranslator::firePropertiesChangeEvent: not implemented - this should not be needed!" );
336     }
337 
338 //........................................................................
339 } // namespace xmloff
340 //........................................................................
341 
342