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