Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include <tools/debug.hxx>
30 : : #include <set>
31 : : #include "xmloff/xmlnmspe.hxx"
32 : : #include <xmloff/xmltoken.hxx>
33 : : #include <xmloff/xmlprcon.hxx>
34 : : #include <com/sun/star/style/XStyle.hpp>
35 : : #include <com/sun/star/style/XAutoStyleFamily.hpp>
36 : : #include <com/sun/star/container/XNameContainer.hpp>
37 : : #include <com/sun/star/beans/XPropertySet.hpp>
38 : : #include <com/sun/star/beans/XPropertyState.hpp>
39 : : #include <com/sun/star/beans/XMultiPropertyStates.hpp>
40 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
41 : : #include <xmloff/xmlimp.hxx>
42 : :
43 : : #include <xmloff/prstylei.hxx>
44 : : #include <xmloff/attrlist.hxx>
45 : : #include "xmloff/xmlerror.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::xml::sax;
53 : : using namespace ::com::sun::star::style;
54 : : using namespace ::com::sun::star::container;
55 : : using namespace ::com::sun::star::beans;
56 : : using namespace ::com::sun::star::lang;
57 : : using namespace ::xmloff::token;
58 : :
59 : :
60 : 8982 : void XMLPropStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
61 : : const OUString& rLocalName,
62 : : const OUString& rValue )
63 : : {
64 [ + - ][ + + ]: 8982 : if( XML_NAMESPACE_STYLE == nPrefixKey && IsXMLToken( rLocalName, XML_FAMILY ) )
[ + + ]
65 : : {
66 : : DBG_ASSERT( GetFamily() == ((SvXMLStylesContext *)&mxStyles)->GetFamily( rValue ), "unexpected style family" );
67 : : }
68 : : else
69 : : {
70 : 5627 : SvXMLStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
71 : : }
72 : 8982 : }
73 : :
74 [ + + ][ - + ]: 3467 : TYPEINIT1( XMLPropStyleContext, SvXMLStyleContext );
75 : :
76 : 3652 : XMLPropStyleContext::XMLPropStyleContext( SvXMLImport& rImport,
77 : : sal_uInt16 nPrfx, const OUString& rLName,
78 : : const Reference< XAttributeList > & xAttrList,
79 : : SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
80 : : sal_Bool bDefault )
81 : : : SvXMLStyleContext( rImport, nPrfx, rLName, xAttrList, nFamily, bDefault )
82 : : , msIsPhysical( "IsPhysical" )
83 : : , msFollowStyle( "FollowStyle" )
84 [ + - ]: 3652 : , mxStyles( &rStyles )
85 : : {
86 : 3652 : }
87 : :
88 [ + - ]: 3652 : XMLPropStyleContext::~XMLPropStyleContext()
89 : : {
90 [ - + ]: 3666 : }
91 : :
92 : 1663 : SvXMLImportContext *XMLPropStyleContext::CreateChildContext(
93 : : sal_uInt16 nPrefix,
94 : : const OUString& rLocalName,
95 : : const Reference< XAttributeList > & xAttrList )
96 : : {
97 : 1663 : SvXMLImportContext *pContext = 0;
98 : :
99 : 1663 : sal_uInt32 nFamily = 0;
100 [ + - ]: 1663 : if( XML_NAMESPACE_STYLE == nPrefix )
101 : : {
102 [ - + ]: 1663 : if( IsXMLToken( rLocalName, XML_GRAPHIC_PROPERTIES ) )
103 : 0 : nFamily = XML_TYPE_PROP_GRAPHIC;
104 [ - + ]: 1663 : else if( IsXMLToken( rLocalName, XML_DRAWING_PAGE_PROPERTIES ) )
105 : 0 : nFamily = XML_TYPE_PROP_DRAWING_PAGE;
106 [ + + ]: 1663 : else if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
107 : 434 : nFamily = XML_TYPE_PROP_TEXT;
108 [ + + ]: 1229 : else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
109 : 217 : nFamily = XML_TYPE_PROP_PARAGRAPH;
110 [ + + ]: 1012 : else if( IsXMLToken( rLocalName, XML_RUBY_PROPERTIES ) )
111 : 14 : nFamily = XML_TYPE_PROP_RUBY;
112 [ - + ]: 998 : else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
113 : 0 : nFamily = XML_TYPE_PROP_SECTION;
114 [ + + ]: 998 : else if( IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
115 : 97 : nFamily = XML_TYPE_PROP_TABLE;
116 [ + + ]: 901 : else if( IsXMLToken( rLocalName, XML_TABLE_COLUMN_PROPERTIES ) )
117 : 315 : nFamily = XML_TYPE_PROP_TABLE_COLUMN;
118 [ + + ]: 586 : else if( IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
119 : 133 : nFamily = XML_TYPE_PROP_TABLE_ROW;
120 [ + - ]: 453 : else if( IsXMLToken( rLocalName, XML_TABLE_CELL_PROPERTIES ) )
121 : 453 : nFamily = XML_TYPE_PROP_TABLE_CELL;
122 [ # # ]: 0 : else if( IsXMLToken( rLocalName, XML_CHART_PROPERTIES ) )
123 : 0 : nFamily = XML_TYPE_PROP_CHART;
124 : : }
125 [ + - ]: 1663 : if( nFamily )
126 : : {
127 : : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
128 : 1663 : ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper(
129 [ + - ]: 1663 : GetFamily() );
130 [ + - ]: 1663 : if( xImpPrMap.is() )
131 : 1663 : pContext = new SvXMLPropertySetContext( GetImport(), nPrefix,
132 : : rLocalName, xAttrList,
133 : : nFamily,
134 : : maProperties,
135 [ + - ][ + - ]: 1663 : xImpPrMap );
[ + - ]
136 : : }
137 : :
138 [ - + ]: 1663 : if( !pContext )
139 : : pContext = SvXMLStyleContext::CreateChildContext( nPrefix, rLocalName,
140 : 0 : xAttrList );
141 : :
142 : 1663 : return pContext;
143 : : }
144 : :
145 : 7417 : void XMLPropStyleContext::FillPropertySet(
146 : : const Reference< XPropertySet > & rPropSet )
147 : : {
148 : : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
149 : 7417 : ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper(
150 [ + - ]: 7417 : GetFamily() );
151 : : DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" );
152 [ + - ]: 7417 : if( xImpPrMap.is() )
153 [ + - ][ + - ]: 7417 : xImpPrMap->FillPropertySet( maProperties, rPropSet );
[ + - ]
154 : 7417 : }
155 : :
156 : 0 : void XMLPropStyleContext::SetDefaults()
157 : : {
158 : 0 : }
159 : :
160 : 262 : Reference < XStyle > XMLPropStyleContext::Create()
161 : : {
162 : 262 : Reference < XStyle > xNewStyle;
163 : :
164 : : OUString sServiceName(
165 [ + - ]: 262 : ((SvXMLStylesContext *)&mxStyles)->GetServiceName( GetFamily() ) );
166 [ + - ]: 262 : if( !sServiceName.isEmpty() )
167 : : {
168 : 262 : Reference< XMultiServiceFactory > xFactory( GetImport().GetModel(),
169 [ + - ]: 262 : UNO_QUERY );
170 [ + - ]: 262 : if( xFactory.is() )
171 : : {
172 : : Reference < XInterface > xIfc =
173 [ + - ][ + - ]: 262 : xFactory->createInstance( sServiceName );
174 [ + - ]: 262 : if( xIfc.is() )
175 [ + - ][ + - ]: 262 : xNewStyle = Reference < XStyle >( xIfc, UNO_QUERY );
176 : 262 : }
177 : : }
178 : :
179 : 262 : return xNewStyle;
180 : : }
181 : :
182 : : typedef ::std::set < OUString, ::comphelper::UStringLess > PropertyNameSet;
183 : :
184 : 1448 : void XMLPropStyleContext::CreateAndInsert( sal_Bool bOverwrite )
185 : : {
186 [ + + + + : 1691 : if( ((SvXMLStylesContext *)&mxStyles)->IsAutomaticStyle()
+ - ][ + + ]
187 : 243 : && ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT || GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) )
188 : : {
189 : : Reference < XAutoStyleFamily > xAutoFamily =
190 [ + - ]: 128 : ((SvXMLStylesContext *)&mxStyles)->GetAutoStyles( GetFamily() );
191 [ - + ]: 128 : if( !xAutoFamily.is() )
192 : : return;
193 : : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
194 [ + - ]: 128 : ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper( GetFamily() );
195 : : DBG_ASSERT( xImpPrMap.is(), "There is no import prop mapper" );
196 [ + - ]: 128 : if( xImpPrMap.is() )
197 : : {
198 [ + - ]: 128 : Sequence< PropertyValue > aValues;
199 [ + - ][ + - ]: 128 : xImpPrMap->FillPropertySequence( maProperties, aValues );
200 : :
201 : 128 : sal_Int32 nLen = aValues.getLength();
202 [ + + ]: 128 : if( nLen )
203 : : {
204 [ + + ]: 75 : if( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH )
205 : : {
206 [ + - ]: 62 : aValues.realloc( nLen + 2 );
207 [ + - ]: 62 : PropertyValue *pProps = aValues.getArray() + nLen;
208 : 62 : pProps->Name = rtl::OUString("ParaStyleName");
209 : 62 : OUString sParent( GetParentName() );
210 [ + + ]: 62 : if( !sParent.isEmpty() )
211 [ + - ]: 49 : sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent );
212 : : else
213 : 13 : sParent = rtl::OUString("Standard");
214 [ + - ]: 62 : pProps->Value <<= sParent;
215 : 62 : ++pProps;
216 : 62 : pProps->Name = rtl::OUString("ParaConditionalStyleName");
217 [ + - ]: 62 : pProps->Value <<= sParent;
218 : : }
219 : :
220 [ + - ][ + - ]: 75 : Reference < XAutoStyle > xAutoStyle = xAutoFamily->insertStyle( aValues );
221 [ + - ]: 75 : if( xAutoStyle.is() )
222 : : {
223 [ + - ]: 75 : Sequence< OUString > aPropNames(1);
224 [ + - ]: 150 : aPropNames[0] = GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ?
225 : : rtl::OUString("ParaAutoStyleName") :
226 [ + + ][ + + ]: 150 : rtl::OUString("CharAutoStyleName");
[ # # # # ]
[ + + ]
227 [ + - ][ + - ]: 75 : Sequence< Any > aAny = xAutoStyle->getPropertyValues( aPropNames );
228 [ + - ]: 75 : if( aAny.hasElements() )
229 : : {
230 : 75 : OUString aName;
231 [ + - ]: 75 : aAny[0] >>= aName;
232 : 75 : SetAutoName( aName );
233 [ + - ][ + - ]: 75 : }
234 : 75 : }
235 [ + - ]: 128 : }
236 [ + - ][ + - ]: 128 : }
237 : : }
238 : : else
239 : : {
240 : 1320 : const OUString& rName = GetDisplayName();
241 [ - + ][ + - ]: 1320 : if( rName.isEmpty() || IsDefaultStyle() )
[ + - ]
242 : : return;
243 : :
244 : : Reference < XNameContainer > xFamilies =
245 [ + - ]: 1320 : ((SvXMLStylesContext *)&mxStyles)->GetStylesContainer( GetFamily() );
246 [ - + ]: 1320 : if( !xFamilies.is() )
247 : : return;
248 : :
249 : 1320 : sal_Bool bNew = sal_False;
250 [ + - ][ + - ]: 1320 : if( xFamilies->hasByName( rName ) )
[ + + ]
251 : : {
252 [ + - ][ + - ]: 1058 : Any aAny = xFamilies->getByName( rName );
253 [ + - ]: 1058 : aAny >>= mxStyle;
254 : : }
255 : : else
256 : : {
257 [ + - ][ + - ]: 262 : mxStyle = Create();
258 [ + - ]: 262 : if( !mxStyle.is() )
259 : : return;
260 : :
261 : 262 : Any aAny;
262 [ + - ]: 262 : aAny <<= mxStyle;
263 [ + - ][ + - ]: 262 : xFamilies->insertByName( rName, aAny );
264 : 262 : bNew = sal_True;
265 : : }
266 : :
267 [ + - ]: 1320 : Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY );
268 : : Reference< XPropertySetInfo > xPropSetInfo =
269 [ + - ][ + - ]: 1320 : xPropSet->getPropertySetInfo();
270 [ + + ][ + - ]: 1320 : if( !bNew && xPropSetInfo->hasPropertyByName( msIsPhysical ) )
[ + - ][ + + ]
[ + + ]
271 : : {
272 [ + - ][ + - ]: 593 : Any aAny = xPropSet->getPropertyValue( msIsPhysical );
273 : 593 : bNew = !*(sal_Bool *)aAny.getValue();
274 : : }
275 : 1320 : SetNew( bNew );
276 [ + + ]: 1320 : if( rName != GetName() )
277 [ + - ]: 415 : GetImport().AddStyleDisplayName( GetFamily(), GetName(), rName );
278 : :
279 [ - + ][ # # ]: 1320 : if( bOverwrite || bNew )
280 : : {
281 [ + - ]: 1320 : Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
282 : :
283 : 1320 : UniReference < XMLPropertySetMapper > xPrMap;
284 : : UniReference < SvXMLImportPropertyMapper > xImpPrMap =
285 : 1320 : ((SvXMLStylesContext *)&mxStyles)->GetImportPropertyMapper(
286 [ + - ]: 1320 : GetFamily() );
287 : : DBG_ASSERT( xImpPrMap.is(), "There is the import prop mapper" );
288 [ + - ]: 1320 : if( xImpPrMap.is() )
289 [ + - ][ + - ]: 1320 : xPrMap = xImpPrMap->getPropertySetMapper();
290 [ + - ]: 1320 : if( xPrMap.is() )
291 : : {
292 : : Reference < XMultiPropertyStates > xMultiStates( xPropSet,
293 [ + - ]: 1320 : UNO_QUERY );
294 [ + - ]: 1320 : if( xMultiStates.is() )
295 : : {
296 [ + - ][ + - ]: 1320 : xMultiStates->setAllPropertiesToDefault();
297 : : }
298 : : else
299 : : {
300 [ # # ]: 0 : PropertyNameSet aNameSet;
301 [ # # ]: 0 : sal_Int32 nCount = xPrMap->GetEntryCount();
302 : : sal_Int32 i;
303 [ # # ]: 0 : for( i = 0; i < nCount; i++ )
304 : : {
305 [ # # ][ # # ]: 0 : const OUString& rPrName = xPrMap->GetEntryAPIName( i );
306 [ # # ][ # # ]: 0 : if( xPropSetInfo->hasPropertyByName( rPrName ) )
[ # # ]
307 [ # # ]: 0 : aNameSet.insert( rPrName );
308 : : }
309 : :
310 : 0 : nCount = aNameSet.size();
311 [ # # ]: 0 : Sequence < OUString > aNames( nCount );
312 [ # # ]: 0 : OUString *pNames = aNames.getArray();
313 : 0 : PropertyNameSet::iterator aIter = aNameSet.begin();
314 [ # # ]: 0 : while( aIter != aNameSet.end() )
315 : 0 : *pNames++ = *aIter++;
316 : :
317 : : Sequence < PropertyState > aStates(
318 [ # # ][ # # ]: 0 : xPropState->getPropertyStates( aNames ) );
319 : 0 : const PropertyState *pStates = aStates.getConstArray();
320 [ # # ]: 0 : pNames = aNames.getArray();
321 : :
322 [ # # ]: 0 : for( i = 0; i < nCount; i++ )
323 : : {
324 [ # # ]: 0 : if( PropertyState_DIRECT_VALUE == *pStates++ )
325 [ # # ][ # # ]: 0 : xPropState->setPropertyToDefault( pNames[i] );
326 [ # # ][ # # ]: 0 : }
327 : 1320 : }
328 : : }
329 : :
330 [ + - ]: 1320 : if (mxStyle.is())
331 [ + - ][ + - ]: 1320 : mxStyle->setParentStyle(OUString());
332 : :
333 [ + - ][ + - ]: 1320 : FillPropertySet( xPropSet );
[ + - ]
334 : : }
335 : : else
336 : : {
337 : 0 : SetValid( sal_False );
338 [ + - ]: 1448 : }
339 : : }
340 : : }
341 : :
342 : 1386 : void XMLPropStyleContext::Finish( sal_Bool bOverwrite )
343 : : {
344 [ + + ][ + + ]: 1386 : if( mxStyle.is() && (IsNew() || bOverwrite) )
[ + - ][ + + ]
345 : : {
346 : : // The families cintaner must exist
347 : : Reference < XNameContainer > xFamilies =
348 [ + - ]: 1320 : ((SvXMLStylesContext *)&mxStyles)->GetStylesContainer( GetFamily() );
349 : : DBG_ASSERT( xFamilies.is(), "Families lost" );
350 [ - + ]: 1320 : if( !xFamilies.is() )
351 : 1386 : return;
352 : :
353 : : // connect parent
354 : 1320 : OUString sParent( GetParentName() );
355 [ + + ]: 1320 : if( !sParent.isEmpty() )
356 [ + - ]: 1026 : sParent = GetImport().GetStyleDisplayName( GetFamily(), sParent );
357 [ + + ][ + - ]: 1320 : if( !sParent.isEmpty() && !xFamilies->hasByName( sParent ) )
[ + - ][ - + ]
[ - + ]
358 : 0 : sParent = OUString();
359 : :
360 [ + - ][ + - ]: 1320 : if( sParent != mxStyle->getParentStyle() )
[ + + ]
361 : : {
362 : : // this may except if setting the parent style forms a
363 : : // circle in the style depencies; especially if the parent
364 : : // style is the same as the current style
365 : : try
366 : : {
367 [ + - ][ + - ]: 786 : mxStyle->setParentStyle( sParent );
368 : : }
369 [ # # # # ]: 0 : catch(const uno::Exception& e)
370 : : {
371 : : // according to the API definition, I would expect a
372 : : // container::NoSuchElementException. But it throws an
373 : : // uno::RuntimeException instead. I catch
374 : : // uno::Exception in order to process both of them.
375 : :
376 : : // We can't set the parent style. For a proper
377 : : // Error-Message, we should pass in the name of the
378 : : // style, as well as the desired parent style.
379 [ # # ]: 0 : Sequence<OUString> aSequence(2);
380 : :
381 : : // getName() throws no non-Runtime exception:
382 [ # # # # : 0 : aSequence[0] = mxStyle->getName();
# # ]
383 [ # # ]: 0 : aSequence[1] = sParent;
384 : :
385 : 0 : GetImport().SetError(
386 : : XMLERROR_FLAG_ERROR | XMLERROR_PARENT_STYLE_NOT_ALLOWED,
387 [ # # # # : 0 : aSequence, e.Message, NULL );
# # ]
388 : : }
389 : : }
390 : :
391 : : // connect follow
392 : 1320 : OUString sFollow( GetFollow() );
393 [ + + ]: 1320 : if( !sFollow.isEmpty() )
394 [ + - ]: 126 : sFollow = GetImport().GetStyleDisplayName( GetFamily(), sFollow );
395 [ + + ][ + - ]: 1320 : if( sFollow.isEmpty() || !xFamilies->hasByName( sFollow ) )
[ + - ][ - + ]
[ + + ]
396 [ + - ][ + - ]: 1194 : sFollow = mxStyle->getName();
397 : :
398 [ + - ]: 1320 : Reference < XPropertySet > xPropSet( mxStyle, UNO_QUERY );
399 : : Reference< XPropertySetInfo > xPropSetInfo =
400 [ + - ][ + - ]: 1320 : xPropSet->getPropertySetInfo();
401 [ + - ][ + - ]: 1320 : if( xPropSetInfo->hasPropertyByName( msFollowStyle ) )
[ + + ]
402 : : {
403 [ + - ][ + - ]: 611 : Any aAny = xPropSet->getPropertyValue( msFollowStyle );
404 : 611 : OUString sCurrFollow;
405 : 611 : aAny >>= sCurrFollow;
406 [ + + ]: 611 : if( sCurrFollow != sFollow )
407 : : {
408 [ + - ]: 24 : aAny <<= sFollow;
409 [ + - ][ + - ]: 24 : xPropSet->setPropertyValue( msFollowStyle, aAny );
410 : 611 : }
411 [ + - ]: 1320 : }
412 : : }
413 : : }
414 : :
415 : :
416 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|