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