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