xref: /trunk/main/xmloff/source/draw/XMLShapeStyleContext.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
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