1*cde9e8dcSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*cde9e8dcSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*cde9e8dcSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*cde9e8dcSAndrew Rist  * distributed with this work for additional information
6*cde9e8dcSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*cde9e8dcSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*cde9e8dcSAndrew Rist  * "License"); you may not use this file except in compliance
9*cde9e8dcSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*cde9e8dcSAndrew Rist  *
11*cde9e8dcSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*cde9e8dcSAndrew Rist  *
13*cde9e8dcSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*cde9e8dcSAndrew Rist  * software distributed under the License is distributed on an
15*cde9e8dcSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*cde9e8dcSAndrew Rist  * KIND, either express or implied.  See the License for the
17*cde9e8dcSAndrew Rist  * specific language governing permissions and limitations
18*cde9e8dcSAndrew Rist  * under the License.
19*cde9e8dcSAndrew Rist  *
20*cde9e8dcSAndrew Rist  *************************************************************/
21*cde9e8dcSAndrew Rist 
22*cde9e8dcSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_chart2.hxx"
26cdf0e10cSrcweir #include "PropertyHelper.hxx"
27cdf0e10cSrcweir #include "ContainerHelper.hxx"
28cdf0e10cSrcweir #include "macros.hxx"
29cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
30cdf0e10cSrcweir #include <com/sun/star/container/XNameContainer.hpp>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <vector>
33cdf0e10cSrcweir #include <algorithm>
34cdf0e10cSrcweir #include <functional>
35cdf0e10cSrcweir 
36cdf0e10cSrcweir using namespace ::com::sun::star;
37cdf0e10cSrcweir using namespace ::com::sun::star::beans;
38cdf0e10cSrcweir using ::rtl::OUString;
39cdf0e10cSrcweir using ::com::sun::star::uno::Any;
40cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
41cdf0e10cSrcweir using ::com::sun::star::uno::Sequence;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir namespace
44cdf0e10cSrcweir {
45cdf0e10cSrcweir struct lcl_EqualsElement : public ::std::unary_function< OUString, bool >
46cdf0e10cSrcweir {
47cdf0e10cSrcweir     explicit lcl_EqualsElement( const Any & rValue, const Reference< container::XNameAccess > & xAccess )
48cdf0e10cSrcweir             : m_aValue( rValue ), m_xAccess( xAccess )
49cdf0e10cSrcweir     {
50cdf0e10cSrcweir         OSL_ASSERT( m_xAccess.is());
51cdf0e10cSrcweir     }
52cdf0e10cSrcweir 
53cdf0e10cSrcweir     bool operator() ( const OUString & rName )
54cdf0e10cSrcweir     {
55cdf0e10cSrcweir         try
56cdf0e10cSrcweir         {
57cdf0e10cSrcweir             return (m_xAccess->getByName( rName ) == m_aValue);
58cdf0e10cSrcweir         }
59cdf0e10cSrcweir         catch( const uno::Exception & ex )
60cdf0e10cSrcweir         {
61cdf0e10cSrcweir             ASSERT_EXCEPTION( ex );
62cdf0e10cSrcweir         }
63cdf0e10cSrcweir         return false;
64cdf0e10cSrcweir     }
65cdf0e10cSrcweir 
66cdf0e10cSrcweir private:
67cdf0e10cSrcweir     Any m_aValue;
68cdf0e10cSrcweir     Reference< container::XNameAccess > m_xAccess;
69cdf0e10cSrcweir };
70cdf0e10cSrcweir 
71cdf0e10cSrcweir struct lcl_StringMatches : public ::std::unary_function< OUString ,bool >
72cdf0e10cSrcweir {
73cdf0e10cSrcweir     lcl_StringMatches( const OUString & rCmpStr ) :
74cdf0e10cSrcweir             m_aCmpStr( rCmpStr )
75cdf0e10cSrcweir     {}
76cdf0e10cSrcweir 
77cdf0e10cSrcweir     bool operator() ( const OUString & rStr )
78cdf0e10cSrcweir     {
79cdf0e10cSrcweir         return rStr.match( m_aCmpStr );
80cdf0e10cSrcweir     }
81cdf0e10cSrcweir 
82cdf0e10cSrcweir private:
83cdf0e10cSrcweir     OUString m_aCmpStr;
84cdf0e10cSrcweir };
85cdf0e10cSrcweir 
86cdf0e10cSrcweir struct lcl_OUStringRestToInt32 : public ::std::unary_function< OUString, sal_Int32 >
87cdf0e10cSrcweir {
88cdf0e10cSrcweir     lcl_OUStringRestToInt32( sal_Int32 nPrefixLength ) :
89cdf0e10cSrcweir             m_nPrefixLength( nPrefixLength )
90cdf0e10cSrcweir     {}
91cdf0e10cSrcweir     sal_Int32 operator() ( const OUString & rStr )
92cdf0e10cSrcweir     {
93cdf0e10cSrcweir         if( m_nPrefixLength > rStr.getLength() )
94cdf0e10cSrcweir             return 0;
95cdf0e10cSrcweir         return rStr.copy( m_nPrefixLength ).toInt32( 10 /* radix */ );
96cdf0e10cSrcweir     }
97cdf0e10cSrcweir private:
98cdf0e10cSrcweir     sal_Int32 m_nPrefixLength;
99cdf0e10cSrcweir };
100cdf0e10cSrcweir 
101cdf0e10cSrcweir /** adds a fill gradient, fill hatch, fill bitmap, fill transparency gradient,
102cdf0e10cSrcweir     line dash or line marker to the corresponding name container with a unique
103cdf0e10cSrcweir     name.
104cdf0e10cSrcweir 
105cdf0e10cSrcweir     @param rPrefix
106cdf0e10cSrcweir         The prefix used for automated name generation.
107cdf0e10cSrcweir 
108cdf0e10cSrcweir     @param rPreferredName
109cdf0e10cSrcweir         If this string is not empty it is used as name if it is unique in the
110cdf0e10cSrcweir         table. Otherwise a new name is generated using pPrefix.
111cdf0e10cSrcweir 
112cdf0e10cSrcweir     @return the new name under which the property was stored in the table
113cdf0e10cSrcweir */
114cdf0e10cSrcweir OUString lcl_addNamedPropertyUniqueNameToTable(
115cdf0e10cSrcweir     const Any & rValue,
116cdf0e10cSrcweir     const Reference< container::XNameContainer > & xNameContainer,
117cdf0e10cSrcweir     const OUString & rPrefix,
118cdf0e10cSrcweir     const OUString & rPreferredName )
119cdf0e10cSrcweir {
120cdf0e10cSrcweir     if( ! xNameContainer.is() ||
121cdf0e10cSrcweir         ! rValue.hasValue() ||
122cdf0e10cSrcweir         ( rValue.getValueType() != xNameContainer->getElementType()))
123cdf0e10cSrcweir         return rPreferredName;
124cdf0e10cSrcweir 
125cdf0e10cSrcweir     try
126cdf0e10cSrcweir     {
127cdf0e10cSrcweir         Reference< container::XNameAccess > xNameAccess( xNameContainer, uno::UNO_QUERY_THROW );
128cdf0e10cSrcweir         ::std::vector< OUString > aNames( ::chart::ContainerHelper::SequenceToVector( xNameAccess->getElementNames()));
129cdf0e10cSrcweir         ::std::vector< OUString >::const_iterator aIt(
130cdf0e10cSrcweir             ::std::find_if( aNames.begin(), aNames.end(), lcl_EqualsElement( rValue, xNameAccess )));
131cdf0e10cSrcweir 
132cdf0e10cSrcweir         // element not found in container
133cdf0e10cSrcweir         if( aIt == aNames.end())
134cdf0e10cSrcweir         {
135cdf0e10cSrcweir             OUString aUniqueName;
136cdf0e10cSrcweir 
137cdf0e10cSrcweir             // check if preferred name is already used
138cdf0e10cSrcweir             if( rPreferredName.getLength())
139cdf0e10cSrcweir             {
140cdf0e10cSrcweir                 aIt = ::std::find( aNames.begin(), aNames.end(), rPreferredName );
141cdf0e10cSrcweir                 if( aIt == aNames.end())
142cdf0e10cSrcweir                     aUniqueName = rPreferredName;
143cdf0e10cSrcweir             }
144cdf0e10cSrcweir 
145cdf0e10cSrcweir             if( ! aUniqueName.getLength())
146cdf0e10cSrcweir             {
147cdf0e10cSrcweir                 // create a unique id using the prefix plus a number
148cdf0e10cSrcweir                 ::std::vector< sal_Int32 > aNumbers;
149cdf0e10cSrcweir                 ::std::vector< OUString >::iterator aNonConstIt(
150cdf0e10cSrcweir                     ::std::partition( aNames.begin(), aNames.end(), lcl_StringMatches( rPrefix )));
151cdf0e10cSrcweir                 ::std::transform( aNames.begin(), aNonConstIt,
152cdf0e10cSrcweir                                   back_inserter( aNumbers ),
153cdf0e10cSrcweir                                   lcl_OUStringRestToInt32( rPrefix.getLength() ));
154cdf0e10cSrcweir                 ::std::vector< sal_Int32 >::const_iterator aMaxIt(
155cdf0e10cSrcweir                     ::std::max_element( aNumbers.begin(), aNumbers.end()));
156cdf0e10cSrcweir 
157cdf0e10cSrcweir                 sal_Int32 nIndex = 1;
158cdf0e10cSrcweir                 if( aMaxIt != aNumbers.end())
159cdf0e10cSrcweir                     nIndex = (*aMaxIt) + 1;
160cdf0e10cSrcweir 
161cdf0e10cSrcweir                 aUniqueName = rPrefix + OUString::valueOf( nIndex );
162cdf0e10cSrcweir             }
163cdf0e10cSrcweir 
164cdf0e10cSrcweir             OSL_ASSERT( aUniqueName.getLength());
165cdf0e10cSrcweir             xNameContainer->insertByName( aUniqueName, rValue );
166cdf0e10cSrcweir             return aUniqueName;
167cdf0e10cSrcweir         }
168cdf0e10cSrcweir         else
169cdf0e10cSrcweir             // element found => return name
170cdf0e10cSrcweir             return *aIt;
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir     catch( const uno::Exception & ex )
173cdf0e10cSrcweir     {
174cdf0e10cSrcweir         ASSERT_EXCEPTION( ex );
175cdf0e10cSrcweir     }
176cdf0e10cSrcweir 
177cdf0e10cSrcweir     return rPreferredName;
178cdf0e10cSrcweir }
179cdf0e10cSrcweir 
180cdf0e10cSrcweir } // anonymous namespace
181cdf0e10cSrcweir 
182cdf0e10cSrcweir namespace chart
183cdf0e10cSrcweir {
184cdf0e10cSrcweir namespace PropertyHelper
185cdf0e10cSrcweir {
186cdf0e10cSrcweir 
187cdf0e10cSrcweir OUString addLineDashUniqueNameToTable(
188cdf0e10cSrcweir     const Any & rValue,
189cdf0e10cSrcweir     const Reference< lang::XMultiServiceFactory > & xFact,
190cdf0e10cSrcweir     const OUString & rPreferredName )
191cdf0e10cSrcweir {
192cdf0e10cSrcweir     if( xFact.is())
193cdf0e10cSrcweir     {
194cdf0e10cSrcweir         Reference< container::XNameContainer > xNameCnt(
195cdf0e10cSrcweir             xFact->createInstance( C2U( "com.sun.star.drawing.DashTable" )),
196cdf0e10cSrcweir             uno::UNO_QUERY );
197cdf0e10cSrcweir         if( xNameCnt.is())
198cdf0e10cSrcweir             return lcl_addNamedPropertyUniqueNameToTable(
199cdf0e10cSrcweir                 rValue, xNameCnt, C2U( "ChartDash " ), rPreferredName );
200cdf0e10cSrcweir     }
201cdf0e10cSrcweir     return OUString();
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir OUString addGradientUniqueNameToTable(
205cdf0e10cSrcweir     const Any & rValue,
206cdf0e10cSrcweir     const Reference< lang::XMultiServiceFactory > & xFact,
207cdf0e10cSrcweir     const OUString & rPreferredName )
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     if( xFact.is())
210cdf0e10cSrcweir     {
211cdf0e10cSrcweir         Reference< container::XNameContainer > xNameCnt(
212cdf0e10cSrcweir             xFact->createInstance( C2U( "com.sun.star.drawing.GradientTable" )),
213cdf0e10cSrcweir             uno::UNO_QUERY );
214cdf0e10cSrcweir         if( xNameCnt.is())
215cdf0e10cSrcweir             return lcl_addNamedPropertyUniqueNameToTable(
216cdf0e10cSrcweir                 rValue, xNameCnt, C2U( "ChartGradient " ), rPreferredName );
217cdf0e10cSrcweir     }
218cdf0e10cSrcweir     return OUString();
219cdf0e10cSrcweir }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir 
222cdf0e10cSrcweir OUString addTransparencyGradientUniqueNameToTable(
223cdf0e10cSrcweir     const Any & rValue,
224cdf0e10cSrcweir     const Reference< lang::XMultiServiceFactory > & xFact,
225cdf0e10cSrcweir     const OUString & rPreferredName )
226cdf0e10cSrcweir {
227cdf0e10cSrcweir     if( xFact.is())
228cdf0e10cSrcweir     {
229cdf0e10cSrcweir         Reference< container::XNameContainer > xNameCnt(
230cdf0e10cSrcweir             xFact->createInstance( C2U( "com.sun.star.drawing.TransparencyGradientTable" )),
231cdf0e10cSrcweir             uno::UNO_QUERY );
232cdf0e10cSrcweir         if( xNameCnt.is())
233cdf0e10cSrcweir             return lcl_addNamedPropertyUniqueNameToTable(
234cdf0e10cSrcweir                 rValue, xNameCnt, C2U( "ChartTransparencyGradient " ), rPreferredName );
235cdf0e10cSrcweir     }
236cdf0e10cSrcweir     return OUString();
237cdf0e10cSrcweir }
238cdf0e10cSrcweir 
239cdf0e10cSrcweir OUString addHatchUniqueNameToTable(
240cdf0e10cSrcweir     const Any & rValue,
241cdf0e10cSrcweir     const Reference< lang::XMultiServiceFactory > & xFact,
242cdf0e10cSrcweir     const OUString & rPreferredName )
243cdf0e10cSrcweir {
244cdf0e10cSrcweir     if( xFact.is())
245cdf0e10cSrcweir     {
246cdf0e10cSrcweir         Reference< container::XNameContainer > xNameCnt(
247cdf0e10cSrcweir             xFact->createInstance( C2U( "com.sun.star.drawing.HatchTable" )),
248cdf0e10cSrcweir             uno::UNO_QUERY );
249cdf0e10cSrcweir         if( xNameCnt.is())
250cdf0e10cSrcweir             return lcl_addNamedPropertyUniqueNameToTable(
251cdf0e10cSrcweir                 rValue, xNameCnt, C2U( "ChartHatch " ), rPreferredName );
252cdf0e10cSrcweir     }
253cdf0e10cSrcweir     return OUString();
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
256cdf0e10cSrcweir OUString addBitmapUniqueNameToTable(
257cdf0e10cSrcweir     const Any & rValue,
258cdf0e10cSrcweir     const Reference< lang::XMultiServiceFactory > & xFact,
259cdf0e10cSrcweir     const OUString & rPreferredName )
260cdf0e10cSrcweir {
261cdf0e10cSrcweir     if( xFact.is())
262cdf0e10cSrcweir     {
263cdf0e10cSrcweir         Reference< container::XNameContainer > xNameCnt(
264cdf0e10cSrcweir             xFact->createInstance( C2U( "com.sun.star.drawing.BitmapTable" )),
265cdf0e10cSrcweir             uno::UNO_QUERY );
266cdf0e10cSrcweir         if( xNameCnt.is())
267cdf0e10cSrcweir             return lcl_addNamedPropertyUniqueNameToTable(
268cdf0e10cSrcweir                 rValue, xNameCnt, C2U( "ChartBitmap " ), rPreferredName );
269cdf0e10cSrcweir     }
270cdf0e10cSrcweir     return OUString();
271cdf0e10cSrcweir }
272cdf0e10cSrcweir 
273cdf0e10cSrcweir // ----------------------------------------
274cdf0e10cSrcweir 
275cdf0e10cSrcweir void setPropertyValueAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
276cdf0e10cSrcweir {
277cdf0e10cSrcweir     tPropertyValueMap::iterator aIt( rOutMap.find( key ));
278cdf0e10cSrcweir     if( aIt == rOutMap.end())
279cdf0e10cSrcweir         rOutMap.insert( tPropertyValueMap::value_type( key, rAny ));
280cdf0e10cSrcweir     else
281cdf0e10cSrcweir         (*aIt).second = rAny;
282cdf0e10cSrcweir }
283cdf0e10cSrcweir 
284cdf0e10cSrcweir template<>
285cdf0e10cSrcweir     void setPropertyValue< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
286cdf0e10cSrcweir {
287cdf0e10cSrcweir     setPropertyValueAny( rOutMap, key, rAny );
288cdf0e10cSrcweir }
289cdf0e10cSrcweir 
290cdf0e10cSrcweir void setPropertyValueDefaultAny( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const uno::Any & rAny )
291cdf0e10cSrcweir {
292cdf0e10cSrcweir     OSL_ENSURE( rOutMap.end() == rOutMap.find( key ), "Default already exists for property" );
293cdf0e10cSrcweir     setPropertyValue( rOutMap, key, rAny );
294cdf0e10cSrcweir }
295cdf0e10cSrcweir 
296cdf0e10cSrcweir template<>
297cdf0e10cSrcweir     void setPropertyValueDefault< ::com::sun::star::uno::Any >( tPropertyValueMap & rOutMap, tPropertyValueMapKey key, const ::com::sun::star::uno::Any & rAny )
298cdf0e10cSrcweir {
299cdf0e10cSrcweir     setPropertyValueDefaultAny( rOutMap, key, rAny );
300cdf0e10cSrcweir }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 
303cdf0e10cSrcweir void setEmptyPropertyValueDefault( tPropertyValueMap & rOutMap, tPropertyValueMapKey key )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir     setPropertyValueDefault( rOutMap, key, uno::Any());
306cdf0e10cSrcweir }
307cdf0e10cSrcweir 
308cdf0e10cSrcweir } // namespace PropertyHelper
309cdf0e10cSrcweir 
310cdf0e10cSrcweir } //  namespace chart
311