xref: /AOO41X/main/xmloff/source/draw/XMLShapeStyleContext.cxx (revision 63bba73cc51e0afb45f8a8d578158724bb5afee8)
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 
27 #include <tools/debug.hxx>
28 #include <xmloff/XMLShapeStyleContext.hxx>
29 #include "XMLShapePropertySetContext.hxx"
30 #include <xmloff/contextid.hxx>
31 #include <com/sun/star/drawing/XControlShape.hpp>
32 #include "com/sun/star/beans/XPropertySetInfo.hpp"
33 #include <com/sun/star/lang/IllegalArgumentException.hpp>
34 #include <xmloff/xmlimp.hxx>
35 #include <xmloff/xmlnumi.hxx>
36 #include <xmloff/xmlnmspe.hxx>
37 #include <xmloff/xmltoken.hxx>
38 #include "xmloff/xmlerror.hxx"
39 #include <xmloff/maptype.hxx>
40 
41 #include "sdpropls.hxx"
42 
43 using ::rtl::OUString;
44 using ::rtl::OUStringBuffer;
45 
46 using namespace ::com::sun::star;
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::beans;
49 using ::xmloff::token::IsXMLToken;
50 using ::xmloff::token::XML_TEXT_PROPERTIES;
51 using ::xmloff::token::XML_GRAPHIC_PROPERTIES;
52 using ::xmloff::token::XML_PARAGRAPH_PROPERTIES;
53 
54 //////////////////////////////////////////////////////////////////////////////
55 
56 TYPEINIT1( XMLShapeStyleContext, XMLPropStyleContext );
57 
XMLShapeStyleContext(SvXMLImport & rImport,sal_uInt16 nPrfx,const OUString & rLName,const uno::Reference<xml::sax::XAttributeList> & xAttrList,SvXMLStylesContext & rStyles,sal_uInt16 nFamily)58 XMLShapeStyleContext::XMLShapeStyleContext(
59     SvXMLImport& rImport,
60     sal_uInt16 nPrfx,
61     const OUString& rLName,
62     const uno::Reference< xml::sax::XAttributeList >& xAttrList,
63     SvXMLStylesContext& rStyles,
64     sal_uInt16 nFamily)
65 :   XMLPropStyleContext(rImport, nPrfx, rLName, xAttrList, rStyles, nFamily ),
66     m_bIsNumRuleAlreadyConverted( sal_False )
67 {
68 }
69 
~XMLShapeStyleContext()70 XMLShapeStyleContext::~XMLShapeStyleContext()
71 {
72 }
73 
SetAttribute(sal_uInt16 nPrefixKey,const::rtl::OUString & rLocalName,const::rtl::OUString & rValue)74 void XMLShapeStyleContext::SetAttribute( sal_uInt16 nPrefixKey, const ::rtl::OUString& rLocalName, const ::rtl::OUString& rValue )
75 {
76     if ((0 == m_sControlDataStyleName.getLength()) && (::xmloff::token::GetXMLToken(::xmloff::token::XML_DATA_STYLE_NAME) == rLocalName))
77     {
78         m_sControlDataStyleName = rValue;
79     }
80     else if( (XML_NAMESPACE_STYLE == nPrefixKey) && IsXMLToken( rLocalName, ::xmloff::token::XML_LIST_STYLE_NAME ) )
81     {
82         m_sListStyleName = rValue;
83     }
84     else
85     {
86         XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
87 
88         if( (XML_NAMESPACE_STYLE == nPrefixKey) &&
89             ( IsXMLToken( rLocalName, ::xmloff::token::XML_NAME ) || IsXMLToken( rLocalName, ::xmloff::token::XML_DISPLAY_NAME ) ) )
90         {
91             if( GetName().getLength() && GetDisplayName().getLength() && GetName() != GetDisplayName() )
92             {
93                 const_cast< SvXMLImport&>( GetImport() ).
94                     AddStyleDisplayName( GetFamily(), GetName(), GetDisplayName() );
95             }
96         }
97     }
98 }
99 
CreateChildContext(sal_uInt16 nPrefix,const OUString & rLocalName,const Reference<xml::sax::XAttributeList> & xAttrList)100 SvXMLImportContext *XMLShapeStyleContext::CreateChildContext(
101         sal_uInt16 nPrefix,
102         const OUString& rLocalName,
103         const Reference< xml::sax::XAttributeList > & xAttrList )
104 {
105     SvXMLImportContext *pContext = 0;
106 
107     if( XML_NAMESPACE_STYLE == nPrefix )
108     {
109         sal_uInt32 nFamily = 0;
110         if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
111             nFamily = XML_TYPE_PROP_TEXT;
112         else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
113             nFamily = XML_TYPE_PROP_PARAGRAPH;
114         else if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
115             nFamily = XML_TYPE_PROP_GRAPHIC;
116         if( nFamily )
117         {
118             UniReference < SvXMLImportPropertyMapper > xImpPrMap =
119                 GetStyles()->GetImportPropertyMapper( GetFamily() );
120             if( xImpPrMap.is() )
121                 pContext = new XMLShapePropertySetContext( GetImport(), nPrefix,
122                                                         rLocalName, xAttrList,
123                                                         nFamily,
124                                                         GetProperties(),
125                                                         xImpPrMap );
126         }
127     }
128 
129     if( !pContext )
130         pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
131                                                           xAttrList );
132 
133     return pContext;
134 }
135 
FillPropertySet(const Reference<beans::XPropertySet> & rPropSet)136 void XMLShapeStyleContext::FillPropertySet( const Reference< beans::XPropertySet > & rPropSet )
137 {
138     if( !m_bIsNumRuleAlreadyConverted )
139     {
140         m_bIsNumRuleAlreadyConverted = sal_True;
141 
142         // for compatibility to beta files, search for CTF_SD_NUMBERINGRULES_NAME to
143         // import numbering rules from the style:properties element
144         const UniReference< XMLPropertySetMapper >&rMapper = GetStyles()->GetImportPropertyMapper( GetFamily() )->getPropertySetMapper();
145 
146         ::std::vector< XMLPropertyState > &rProperties = GetProperties();
147         ::std::vector< XMLPropertyState >::iterator end( rProperties.end() );
148         ::std::vector< XMLPropertyState >::iterator property;
149 
150         // first, look for the old format, where we had a text:list-style-name
151         // attribute in the style:properties element
152         for( property = rProperties.begin(); property != end; property++ )
153         {
154             // find properties with context
155             if( (property->mnIndex != -1) && (rMapper->GetEntryContextId( property->mnIndex ) == CTF_SD_NUMBERINGRULES_NAME) )
156                 break;
157         }
158 
159         // if we did not find an old list-style-name in the properties, and we need one
160         // because we got a style:list-style attribute in the style-style element
161         // we generate one
162         if( (property == end) && ( 0 != m_sListStyleName.getLength() ) )
163         {
164             sal_Int32 nIndex = rMapper->FindEntryIndex( CTF_SD_NUMBERINGRULES_NAME );
165             DBG_ASSERT( -1 != nIndex, "can't find numbering rules property entry, can't set numbering rule!" );
166 
167             XMLPropertyState aNewState( nIndex );
168             rProperties.push_back( aNewState );
169             end = rProperties.end();
170             property = end - 1;
171         }
172 
173         // so, if we have an old or a new list style name, we set its value to
174         // a numbering rule
175         if( property != end )
176         {
177             if( 0 == m_sListStyleName.getLength() )
178             {
179                 property->maValue >>= m_sListStyleName;
180             }
181 
182             const SvxXMLListStyleContext *pListStyle = GetImport().GetTextImport()->FindAutoListStyle( m_sListStyleName );
183 
184             DBG_ASSERT( pListStyle, "list-style not found for shape style" );
185             if( pListStyle )
186             {
187                 uno::Reference< container::XIndexReplace > xNumRule( pListStyle->CreateNumRule( GetImport().GetModel() ) );
188                 pListStyle->FillUnoNumRule(xNumRule, NULL /* const SvI18NMap * ??? */ );
189                 property->maValue <<= xNumRule;
190             }
191             else
192             {
193                 property->mnIndex = -1;
194             }
195         }
196     }
197 
198     struct _ContextID_Index_Pair aContextIDs[] =
199     {
200         { CTF_DASHNAME , -1 },
201         { CTF_LINESTARTNAME , -1 },
202         { CTF_LINEENDNAME , -1 },
203         { CTF_FILLGRADIENTNAME, -1 },
204         { CTF_FILLTRANSNAME , -1 },
205         { CTF_FILLHATCHNAME , -1 },
206         { CTF_FILLBITMAPNAME , -1 },
207         { CTF_SD_OLE_VIS_AREA_IMPORT_LEFT, -1 },
208         { CTF_SD_OLE_VIS_AREA_IMPORT_TOP, -1 },
209         { CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH, -1 },
210         { CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT, -1 },
211         { -1, -1 }
212     };
213     static sal_uInt16 aFamilies[] =
214     {
215         XML_STYLE_FAMILY_SD_STROKE_DASH_ID,
216         XML_STYLE_FAMILY_SD_MARKER_ID,
217         XML_STYLE_FAMILY_SD_MARKER_ID,
218         XML_STYLE_FAMILY_SD_GRADIENT_ID,
219         XML_STYLE_FAMILY_SD_GRADIENT_ID,
220         XML_STYLE_FAMILY_SD_HATCH_ID,
221         XML_STYLE_FAMILY_SD_FILL_IMAGE_ID
222     };
223 
224     UniReference < SvXMLImportPropertyMapper > xImpPrMap =
225         GetStyles()->GetImportPropertyMapper( GetFamily() );
226     DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" );
227     if( xImpPrMap.is() )
228         xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs );
229 
230     Reference< XPropertySetInfo > xInfo;
231     // get property set mapper
232     UniReference<XMLPropertySetMapper> xPropMapper( xImpPrMap->getPropertySetMapper() );
233 
234     for( sal_uInt16 i=0; aContextIDs[i].nContextID != -1; i++ )
235     {
236         sal_Int32 nIndex = aContextIDs[i].nIndex;
237         if( nIndex != -1 ) switch( aContextIDs[i].nContextID )
238         {
239         case CTF_DASHNAME:
240         case CTF_LINESTARTNAME:
241         case CTF_LINEENDNAME:
242         case CTF_FILLGRADIENTNAME:
243         case CTF_FILLTRANSNAME:
244         case CTF_FILLHATCHNAME:
245         case CTF_FILLBITMAPNAME:
246         {
247             struct XMLPropertyState& rState = GetProperties()[nIndex];
248             OUString sStyleName;
249             rState.maValue >>= sStyleName;
250             sStyleName = GetImport().GetStyleDisplayName( aFamilies[i], sStyleName );
251             try
252             {
253 
254                 // set property
255                 const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex);
256                 if( !xInfo.is() )
257                     xInfo = rPropSet->getPropertySetInfo();
258                 if ( xInfo->hasPropertyByName( rPropertyName ) )
259                 {
260                     rPropSet->setPropertyValue( rPropertyName, Any( sStyleName ) );
261                 }
262             }
263             catch ( ::com::sun::star::lang::IllegalArgumentException& e )
264             {
265                 Sequence<OUString> aSeq(1);
266                 aSeq[0] = sStyleName;
267                 GetImport().SetError(
268                     XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
269                     aSeq, e.Message, NULL );
270             }
271             break;
272         }
273         case CTF_SD_OLE_VIS_AREA_IMPORT_LEFT:
274         case CTF_SD_OLE_VIS_AREA_IMPORT_TOP:
275         case CTF_SD_OLE_VIS_AREA_IMPORT_WIDTH:
276         case CTF_SD_OLE_VIS_AREA_IMPORT_HEIGHT:
277         {
278             struct XMLPropertyState& rState = GetProperties()[nIndex];
279             const OUString& rPropertyName = xPropMapper->GetEntryAPIName(rState.mnIndex);
280             try
281             {
282                 if( !xInfo.is() )
283                     xInfo = rPropSet->getPropertySetInfo();
284                 if ( xInfo->hasPropertyByName( rPropertyName ) )
285                 {
286                     rPropSet->setPropertyValue( rPropertyName, rState.maValue );
287                 }
288             }
289             catch ( ::com::sun::star::lang::IllegalArgumentException& e )
290             {
291                 Sequence<OUString> aSeq;
292                 GetImport().SetError(
293                     XMLERROR_STYLE_PROP_VALUE | XMLERROR_FLAG_WARNING,
294                     aSeq, e.Message, NULL );
295             }
296             break;
297         }
298         }
299     }
300 
301     if (m_sControlDataStyleName.getLength())
302     {   // we had a data-style-name attribute
303 
304         // set the formatting on the control model of the control shape
305         uno::Reference< drawing::XControlShape > xControlShape(rPropSet, uno::UNO_QUERY);
306         DBG_ASSERT(xControlShape.is(), "XMLShapeStyleContext::FillPropertySet: data style for a non-control shape!");
307         if (xControlShape.is())
308         {
309             uno::Reference< beans::XPropertySet > xControlModel(xControlShape->getControl(), uno::UNO_QUERY);
310             DBG_ASSERT(xControlModel.is(), "XMLShapeStyleContext::FillPropertySet: no control model for the shape!");
311             if (xControlModel.is())
312             {
313                 GetImport().GetFormImport()->applyControlNumberStyle(xControlModel, m_sControlDataStyleName);
314             }
315         }
316     }
317 }
318 
Finish(sal_Bool)319 void XMLShapeStyleContext::Finish( sal_Bool /*bOverwrite*/ )
320 {
321 }
322 
323