fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / xmloff / source / style / styleexp.cxx
blob58991dff96b7b85da224c6c809734d93aa94400a
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <tools/debug.hxx>
21 #include <xmloff/nmspmap.hxx>
22 #include "xmloff/xmlnmspe.hxx"
23 #include <xmloff/xmltoken.hxx>
24 #include <xmloff/xmluconv.hxx>
25 #include <xmloff/attrlist.hxx>
26 #include <xmloff/xmlprmap.hxx>
27 #include <xmloff/xmlexppr.hxx>
28 #include <com/sun/star/xml/sax/XExtendedDocumentHandler.hpp>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
31 #include <com/sun/star/style/XStyle.hpp>
32 #include <com/sun/star/container/XNameContainer.hpp>
33 #include <com/sun/star/beans/XPropertySet.hpp>
34 #include <com/sun/star/beans/XPropertyState.hpp>
35 #include <com/sun/star/document/XEventsSupplier.hpp>
36 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
37 #include <xmloff/xmlaustp.hxx>
38 #include <xmloff/styleexp.hxx>
39 #include <xmloff/xmlexp.hxx>
40 #include <xmloff/XMLEventExport.hxx>
41 #include <set>
42 #include <boost/scoped_ptr.hpp>
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::style;
47 using namespace ::com::sun::star::container;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::text;
50 using namespace ::xmloff::token;
52 using ::com::sun::star::document::XEventsSupplier;
54 XMLStyleExport::XMLStyleExport(
55 SvXMLExport& rExp,
56 const OUString& rPoolStyleName,
57 SvXMLAutoStylePoolP *pAutoStyleP ) :
58 rExport( rExp ),
59 sIsPhysical( "IsPhysical" ),
60 sIsAutoUpdate( "IsAutoUpdate" ),
61 sFollowStyle( "FollowStyle" ),
62 sNumberingStyleName( "NumberingStyleName" ),
63 sOutlineLevel( "OutlineLevel" ),
64 sPoolStyleName( rPoolStyleName ),
65 pAutoStylePool( pAutoStyleP )
69 XMLStyleExport::~XMLStyleExport()
73 void XMLStyleExport::exportStyleAttributes( const Reference< XStyle >& )
77 void XMLStyleExport::exportStyleContent( const Reference< XStyle >& )
81 sal_Bool XMLStyleExport::exportStyle(
82 const Reference< XStyle >& rStyle,
83 const OUString& rXMLFamily,
84 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
85 const Reference< XNameAccess >& xStyles,
86 const OUString* pPrefix )
88 Reference< XPropertySet > xPropSet( rStyle, UNO_QUERY );
89 Reference< XPropertySetInfo > xPropSetInfo =
90 xPropSet->getPropertySetInfo();
91 Any aAny;
93 // Don't export styles that aren't existing really. This may be the
94 // case for StarOffice Writer's pool styles.
95 if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
97 aAny = xPropSet->getPropertyValue( sIsPhysical );
98 if( !*(sal_Bool *)aAny.getValue() )
99 return sal_False;
102 // <style:style ...>
103 GetExport().CheckAttrList();
105 // style:name="..."
106 OUString sName;
108 if(pPrefix)
109 sName = *pPrefix;
110 sName += rStyle->getName();
112 sal_Bool bEncoded = sal_False;
113 const OUString sEncodedStyleName(GetExport().EncodeStyleName( sName, &bEncoded ));
114 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NAME, sEncodedStyleName );
116 if( bEncoded )
117 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_DISPLAY_NAME,
118 sName);
120 // style:family="..."
121 if( !rXMLFamily.isEmpty() )
122 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY, rXMLFamily);
124 if ( xPropSetInfo->hasPropertyByName( "Hidden" ) )
126 aAny = xPropSet->getPropertyValue( "Hidden" );
127 sal_Bool bHidden = sal_False;
128 if ( ( aAny >>= bHidden ) && bHidden && GetExport( ).getDefaultVersion( ) == SvtSaveOptions::ODFVER_LATEST )
129 GetExport( ).AddAttribute( XML_NAMESPACE_STYLE, XML_HIDDEN, "true" );
132 // style:parent-style-name="..."
133 OUString sParentString(rStyle->getParentStyle());
134 OUString sParent;
136 if(!sParentString.isEmpty())
138 if(pPrefix)
139 sParent = *pPrefix;
140 sParent += sParentString;
142 else
143 sParent = sPoolStyleName;
145 if( !sParent.isEmpty() )
146 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_PARENT_STYLE_NAME,
147 GetExport().EncodeStyleName( sParent ) );
149 // style:next-style-name="..." (paragraph styles only)
150 if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
152 aAny = xPropSet->getPropertyValue( sFollowStyle );
153 OUString sNextName;
154 aAny >>= sNextName;
155 if( sName != sNextName )
157 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_NEXT_STYLE_NAME,
158 GetExport().EncodeStyleName( sNextName ) );
162 // style:auto-update="..." (SW only)
163 if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) )
165 aAny = xPropSet->getPropertyValue( sIsAutoUpdate );
166 if( *(sal_Bool *)aAny.getValue() )
167 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_AUTO_UPDATE,
168 XML_TRUE );
171 // style:default-outline-level"..."
172 sal_Int32 nOutlineLevel = 0;
173 if( xPropSetInfo->hasPropertyByName( sOutlineLevel ) )
175 Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
176 if( PropertyState_DIRECT_VALUE == xPropState->getPropertyState( sOutlineLevel ) )
178 aAny = xPropSet->getPropertyValue( sOutlineLevel );
179 aAny >>= nOutlineLevel;
180 if( nOutlineLevel > 0 )
182 OUStringBuffer sTmp;
183 sTmp.append( static_cast<sal_Int32>(nOutlineLevel));
184 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
185 XML_DEFAULT_OUTLINE_LEVEL,
186 sTmp.makeStringAndClear() );
188 else
190 /* Empty value for style:default-outline-level does exist
191 since ODF 1.2. Thus, suppress its export for former versions. (#i104889#)
193 if ( ( GetExport().getExportFlags() & EXPORT_OASIS ) != 0 &&
194 GetExport().getDefaultVersion() >= SvtSaveOptions::ODFVER_012 )
196 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
197 XML_DEFAULT_OUTLINE_LEVEL,
198 OUString( "" ));
204 // style:list-style-name="..." (SW paragarph styles only)
205 if( xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
207 Reference< XPropertyState > xPropState( xPropSet, uno::UNO_QUERY );
208 if( PropertyState_DIRECT_VALUE ==
209 xPropState->getPropertyState( sNumberingStyleName ) )
211 aAny = xPropSet->getPropertyValue( sNumberingStyleName );
212 if( aAny.hasValue() )
214 OUString sListName;
215 aAny >>= sListName;
217 /* An direct set empty list style has to be written. Otherwise,
218 this information is lost and causes an error, if the parent
219 style has a list style set. (#i69523#)
221 if ( sListName.isEmpty() )
223 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
224 XML_LIST_STYLE_NAME,
225 sListName /* empty string */);
227 else
229 // Written OpenDocument file format doesn't fit to the created text document (#i69627#)
230 bool bSuppressListStyle( false );
232 if ( !GetExport().writeOutlineStyleAsNormalListStyle() )
234 Reference< XChapterNumberingSupplier > xCNSupplier
235 (GetExport().GetModel(), UNO_QUERY);
237 OUString sOutlineName;
238 if (xCNSupplier.is())
240 Reference< XIndexReplace > xNumRule
241 ( xCNSupplier->getChapterNumberingRules() );
242 DBG_ASSERT( xNumRule.is(), "no chapter numbering rules" );
244 if (xNumRule.is())
246 Reference< XPropertySet > xNumRulePropSet
247 (xNumRule, UNO_QUERY);
248 xNumRulePropSet->getPropertyValue(
249 OUString("Name") )
250 >>= sOutlineName;
251 bSuppressListStyle = ( sListName == sOutlineName );
257 if ( !sListName.isEmpty() && !bSuppressListStyle )
259 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
260 XML_LIST_STYLE_NAME,
261 GetExport().EncodeStyleName( sListName ) );
266 else if( nOutlineLevel > 0 )
269 bool bNoInheritedListStyle( true );
271 /////////////////////////////////////////////////
272 Reference<XStyle> xStyle( xPropState, UNO_QUERY );
273 while ( xStyle.is() )
275 OUString aParentStyle( xStyle->getParentStyle() );
276 if ( aParentStyle.isEmpty() || !xStyles->hasByName( aParentStyle ) )
278 break;
280 else
282 xPropState = Reference< XPropertyState >( xStyles->getByName( aParentStyle ), UNO_QUERY );
283 if ( !xPropState.is() )
285 break;
287 if ( xPropState->getPropertyState( sNumberingStyleName ) == PropertyState_DIRECT_VALUE )
289 bNoInheritedListStyle = false;
290 break;
292 else
294 xStyle = Reference<XStyle>( xPropState, UNO_QUERY );
298 /////////////////////////////////////////////////
299 if ( bNoInheritedListStyle )
300 GetExport().AddAttribute( XML_NAMESPACE_STYLE,
301 XML_LIST_STYLE_NAME,
302 OUString( "" ));
306 // style:pool-id="..." is not required any longer since we use
307 // english style names only
308 exportStyleAttributes( rStyle );
310 // TODO: style:help-file-name="..." and style:help-id="..." can neither
311 // be modified by UI nor by API and that for, have not to be exported
312 // currently.
315 // <style:style>
316 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE, XML_STYLE,
317 sal_True, sal_True );
319 rPropMapper->SetStyleName( sName );
321 // <style:properties>
322 ::std::vector< XMLPropertyState > xPropStates =
323 rPropMapper->Filter( xPropSet, true );
324 rPropMapper->exportXML( GetExport(), xPropStates,
325 XML_EXPORT_FLAG_IGN_WS );
327 rPropMapper->SetStyleName( OUString() );
329 exportStyleContent( rStyle );
331 // <script:events>, if they are supported by this style
332 Reference<XEventsSupplier> xEventsSupp(rStyle, UNO_QUERY);
333 GetExport().GetEventExport().Export(xEventsSupp);
335 return sal_True;
338 sal_Bool XMLStyleExport::exportDefaultStyle(
339 const Reference< XPropertySet >& xPropSet,
340 const OUString& rXMLFamily,
341 const UniReference < SvXMLExportPropertyMapper >& rPropMapper )
343 Reference< XPropertySetInfo > xPropSetInfo =
344 xPropSet->getPropertySetInfo();
346 Any aAny;
348 // <style:default-style ...>
349 GetExport().CheckAttrList();
352 // style:family="..."
353 if( !rXMLFamily.isEmpty() )
354 GetExport().AddAttribute( XML_NAMESPACE_STYLE, XML_FAMILY,
355 rXMLFamily );
356 // <style:style>
357 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_STYLE,
358 XML_DEFAULT_STYLE,
359 sal_True, sal_True );
360 // <style:properties>
361 ::std::vector< XMLPropertyState > xPropStates =
362 rPropMapper->FilterDefaults( xPropSet );
363 rPropMapper->exportXML( GetExport(), xPropStates,
364 XML_EXPORT_FLAG_IGN_WS );
366 return sal_True;
369 void XMLStyleExport::exportStyleFamily(
370 const sal_Char *pFamily,
371 const OUString& rXMLFamily,
372 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
373 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
375 const OUString sFamily(OUString::createFromAscii(pFamily ));
376 exportStyleFamily( sFamily, rXMLFamily, rPropMapper, bUsed, nFamily,
377 pPrefix);
380 void XMLStyleExport::exportStyleFamily(
381 const OUString& rFamily, const OUString& rXMLFamily,
382 const UniReference < SvXMLExportPropertyMapper >& rPropMapper,
383 sal_Bool bUsed, sal_uInt16 nFamily, const OUString* pPrefix)
385 DBG_ASSERT( GetExport().GetModel().is(), "There is the model?" );
386 Reference< XStyleFamiliesSupplier > xFamiliesSupp( GetExport().GetModel(), UNO_QUERY );
387 if( !xFamiliesSupp.is() )
388 return; // family not available in current model
390 Reference< XNameAccess > xStyleCont;
392 Reference< XNameAccess > xFamilies( xFamiliesSupp->getStyleFamilies() );
393 if( xFamilies->hasByName( rFamily ) )
394 xFamilies->getByName( rFamily ) >>= xStyleCont;
396 if( !xStyleCont.is() )
397 return;
399 Reference< XNameAccess > xStyles( xStyleCont, UNO_QUERY );
400 // If next styles are supported and used styles should be exported only,
401 // the next style may be unused but has to be exported, too. In this case
402 // the names of all exported styles are remembered.
403 boost::scoped_ptr<std::set<OUString> > pExportedStyles(0);
404 sal_Bool bFirstStyle = sal_True;
406 const uno::Sequence< OUString> aSeq = xStyles->getElementNames();
407 const OUString* pIter = aSeq.getConstArray();
408 const OUString* pEnd = pIter + aSeq.getLength();
409 for(;pIter != pEnd;++pIter)
411 Reference< XStyle > xStyle;
414 xStyles->getByName( *pIter ) >>= xStyle;
416 catch(const lang::IndexOutOfBoundsException&)
418 // due to bugs in prior versions it is possible that
419 // a binary file is missing some critical styles.
420 // The only possible way to deal with this is to
421 // not export them here and remain silent.
422 continue;
425 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
426 if( xStyle.is() )
428 if( !bUsed || xStyle->isInUse() )
430 sal_Bool bExported = exportStyle( xStyle, rXMLFamily, rPropMapper,
431 xStyles,pPrefix );
432 if( bUsed && bFirstStyle && bExported )
434 // If this is the first style, find out whether next styles
435 // are supported.
436 Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
437 Reference< XPropertySetInfo > xPropSetInfo =
438 xPropSet->getPropertySetInfo();
440 if( xPropSetInfo->hasPropertyByName( sFollowStyle ) )
441 pExportedStyles.reset(new std::set<OUString>());
442 bFirstStyle = sal_False;
445 if( pExportedStyles && bExported )
447 // If next styles are supported, remember this style's name.
448 pExportedStyles->insert( xStyle->getName() );
452 // if an auto style pool is given, remember this style's name as a
453 // style name that must not be used by automatic styles.
454 if( pAutoStylePool )
455 pAutoStylePool->RegisterName( nFamily, xStyle->getName() );
459 if( pExportedStyles )
461 // if next styles are supported, export all next styles that are
462 // unused and that for, haven't been exported in the first loop.
463 pIter = aSeq.getConstArray();
464 for(;pIter != pEnd;++pIter)
466 Reference< XStyle > xStyle;
467 xStyles->getByName( *pIter ) >>= xStyle;
469 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
470 if( xStyle.is() )
472 Reference< XPropertySet > xPropSet( xStyle, UNO_QUERY );
473 Reference< XPropertySetInfo > xPropSetInfo( xPropSet->getPropertySetInfo() );
475 // styles that aren't existing realy are ignored.
476 if( xPropSetInfo->hasPropertyByName( sIsPhysical ) )
478 Any aAny( xPropSet->getPropertyValue( sIsPhysical ) );
479 if( !*(sal_Bool *)aAny.getValue() )
480 continue;
483 if( !xStyle->isInUse() )
484 continue;
486 if( !xPropSetInfo->hasPropertyByName( sFollowStyle ) )
488 DBG_ASSERT( sFollowStyle.isEmpty(), "no follow style???" );
489 continue;
492 OUString sNextName;
493 xPropSet->getPropertyValue( sFollowStyle ) >>= sNextName;
494 OUString sTmp( sNextName );
495 // if the next style hasn't been exported by now, export it now
496 // and remember its name.
497 if( xStyle->getName() != sNextName &&
498 0 == pExportedStyles->count( sTmp ) )
500 xStyleCont->getByName( sNextName ) >>= xStyle;
501 DBG_ASSERT( xStyle.is(), "Style not found for export!" );
503 if( xStyle.is() && exportStyle( xStyle, rXMLFamily, rPropMapper, xStyles,pPrefix ) )
504 pExportedStyles->insert( sTmp );
512 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */