fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / xmloff / source / text / txtstyli.cxx
blob4f30fa5890c41b5efdc0fccbd6c45e1a96da34b3
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 .
21 #include "XMLTextPropertySetContext.hxx"
22 #include "xmloff/xmlnmspe.hxx"
23 #include "xmloff/XMLEventsImportContext.hxx"
24 #include "xmloff/attrlist.hxx"
25 #include "xmloff/families.hxx"
26 #include "xmloff/txtprmap.hxx"
27 #include "xmloff/txtstyli.hxx"
28 #include "xmloff/xmlimp.hxx"
29 #include "xmloff/xmltkmap.hxx"
30 #include "xmloff/xmltoken.hxx"
31 #include "xmloff/xmluconv.hxx"
33 #include <com/sun/star/beans/XMultiPropertySet.hpp>
34 #include <com/sun/star/container/XNameContainer.hpp>
35 #include <com/sun/star/document/XEventsSupplier.hpp>
36 #include <com/sun/star/frame/XModel.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 #include <com/sun/star/style/ParagraphStyleCategory.hpp>
39 #include <com/sun/star/style/XStyle.hpp>
41 #include <sax/tools/converter.hxx>
43 #include <tools/debug.hxx>
44 #include <tools/diagnose_ex.h>
46 // STL includes
47 #include <algorithm>
48 #include <functional>
49 #include <utility>
50 #include <vector>
53 using namespace ::std;
54 using namespace ::com::sun::star;
55 using namespace ::com::sun::star::uno;
56 using namespace ::com::sun::star::xml::sax;
57 using namespace ::com::sun::star::style;
58 using namespace ::com::sun::star::frame;
59 using namespace ::com::sun::star::beans;
60 using namespace ::com::sun::star::lang;
61 using namespace ::com::sun::star::container;
62 using namespace ::xmloff::token;
64 static SvXMLEnumMapEntry aCategoryMap[] =
66 { XML_TEXT, ParagraphStyleCategory::TEXT },
67 { XML_CHAPTER, ParagraphStyleCategory::CHAPTER },
68 { XML_LIST, ParagraphStyleCategory::LIST },
69 { XML_INDEX, ParagraphStyleCategory::INDEX },
70 { XML_EXTRA, ParagraphStyleCategory::EXTRA },
71 { XML_HTML, ParagraphStyleCategory::HTML },
72 { XML_TOKEN_INVALID, 0 }
75 void XMLTextStyleContext::SetAttribute( sal_uInt16 nPrefixKey,
76 const OUString& rLocalName,
77 const OUString& rValue )
79 if( XML_NAMESPACE_STYLE == nPrefixKey )
81 // TODO: use a map here
82 if( IsXMLToken( rLocalName, XML_AUTO_UPDATE ) )
84 if( IsXMLToken( rValue, XML_TRUE ) )
85 bAutoUpdate = sal_True;
87 else if( IsXMLToken( rLocalName, XML_LIST_STYLE_NAME ) )
89 sListStyleName = rValue;
90 // Inherited paragraph style lost information about unset numbering (#i69523#)
91 mbListStyleSet = sal_True;
93 else if( IsXMLToken( rLocalName, XML_MASTER_PAGE_NAME ) )
95 sMasterPageName = rValue;
96 bHasMasterPageName = sal_True;
98 else if( IsXMLToken( rLocalName, XML_DATA_STYLE_NAME ) )
100 sDataStyleName = rValue;
102 else if( IsXMLToken( rLocalName, XML_CLASS ) )
104 sCategoryVal = rValue;
106 else if( IsXMLToken( rLocalName, XML_DEFAULT_OUTLINE_LEVEL ) )
108 sal_Int32 nTmp;
109 if (::sax::Converter::convertNumber( nTmp, rValue ) &&
110 0 <= nTmp && nTmp <= 10 )
111 nOutlineLevel = static_cast< sal_Int8 >( nTmp );
113 else
115 XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
118 else
120 XMLPropStyleContext::SetAttribute( nPrefixKey, rLocalName, rValue );
124 TYPEINIT1( XMLTextStyleContext, XMLPropStyleContext );
126 XMLTextStyleContext::XMLTextStyleContext( SvXMLImport& rImport,
127 sal_uInt16 nPrfx, const OUString& rLName,
128 const Reference< XAttributeList > & xAttrList,
129 SvXMLStylesContext& rStyles, sal_uInt16 nFamily,
130 sal_Bool bDefaultStyle )
131 : XMLPropStyleContext( rImport, nPrfx, rLName, xAttrList, rStyles, nFamily, bDefaultStyle )
132 , sIsAutoUpdate( "IsAutoUpdate" )
133 , sCategory( "Category" )
134 , sNumberingStyleName( "NumberingStyleName" )
135 , sOutlineLevel("OutlineLevel" )
136 , sDropCapCharStyleName( "DropCapCharStyleName" )
137 , sPageDescName( "PageDescName" )
138 , nOutlineLevel( -1 )
139 , bAutoUpdate( sal_False )
140 , bHasMasterPageName( sal_False )
141 , bHasCombinedCharactersLetter( sal_False )
142 // Inherited paragraph style lost information about unset numbering (#i69523#)
143 , mbListStyleSet( sal_False )
144 , pEventContext( NULL )
148 XMLTextStyleContext::~XMLTextStyleContext()
152 SvXMLImportContext *XMLTextStyleContext::CreateChildContext(
153 sal_uInt16 nPrefix,
154 const OUString& rLocalName,
155 const Reference< XAttributeList > & xAttrList )
157 SvXMLImportContext *pContext = 0;
159 if( XML_NAMESPACE_STYLE == nPrefix )
161 sal_uInt32 nFamily = 0;
162 if( IsXMLToken( rLocalName, XML_TEXT_PROPERTIES ) )
163 nFamily = XML_TYPE_PROP_TEXT;
164 else if( IsXMLToken( rLocalName, XML_PARAGRAPH_PROPERTIES ) )
165 nFamily = XML_TYPE_PROP_PARAGRAPH;
166 else if( IsXMLToken( rLocalName, XML_SECTION_PROPERTIES ) )
167 nFamily = XML_TYPE_PROP_SECTION;
168 else if( IsDefaultStyle() && IsXMLToken( rLocalName, XML_TABLE_PROPERTIES ) )
169 nFamily = XML_TYPE_PROP_TABLE;
170 else if( IsDefaultStyle() && IsXMLToken( rLocalName, XML_TABLE_ROW_PROPERTIES ) )
171 nFamily = XML_TYPE_PROP_TABLE_ROW;
172 if( nFamily )
174 UniReference < SvXMLImportPropertyMapper > xImpPrMap =
175 GetStyles()->GetImportPropertyMapper( GetFamily() );
176 if( xImpPrMap.is() )
177 pContext = new XMLTextPropertySetContext( GetImport(), nPrefix,
178 rLocalName, xAttrList,
179 nFamily,
180 GetProperties(),
181 xImpPrMap,
182 sDropCapTextStyleName );
185 else if ( (XML_NAMESPACE_OFFICE == nPrefix) &&
186 IsXMLToken( rLocalName, XML_EVENT_LISTENERS ) )
188 // create and remember events import context
189 // (for delayed processing of events)
190 pEventContext = new XMLEventsImportContext( GetImport(), nPrefix,
191 rLocalName);
192 pEventContext->AddRef();
193 pContext = pEventContext;
196 if( !pContext )
197 pContext = XMLPropStyleContext::CreateChildContext( nPrefix, rLocalName,
198 xAttrList );
200 return pContext;
203 void XMLTextStyleContext::CreateAndInsert( sal_Bool bOverwrite )
205 XMLPropStyleContext::CreateAndInsert( bOverwrite );
206 Reference < XStyle > xStyle = GetStyle();
207 if( !xStyle.is() || !(bOverwrite || IsNew()) )
208 return;
210 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
211 Reference< XPropertySetInfo > xPropSetInfo =
212 xPropSet->getPropertySetInfo();
213 if( xPropSetInfo->hasPropertyByName( sIsAutoUpdate ) )
215 Any aAny;
216 sal_Bool bTmp = bAutoUpdate;
217 aAny.setValue( &bTmp, ::getBooleanCppuType() );
218 xPropSet->setPropertyValue( sIsAutoUpdate, aAny );
221 sal_uInt16 nCategory = ParagraphStyleCategory::TEXT;
222 if( XML_STYLE_FAMILY_TEXT_PARAGRAPH == GetFamily() &&
223 !sCategoryVal.isEmpty() && xStyle->isUserDefined() &&
224 xPropSetInfo->hasPropertyByName( sCategory ) &&
225 SvXMLUnitConverter::convertEnum( nCategory, sCategoryVal, aCategoryMap ) )
227 Any aAny;
228 aAny <<= (sal_Int16)nCategory;
229 xPropSet->setPropertyValue( sCategory, aAny );
232 // tell the style about it's events (if applicable)
233 if (NULL != pEventContext)
235 // set event suppplier and release reference to context
236 Reference<document::XEventsSupplier> xEventsSupplier(xStyle,UNO_QUERY);
237 pEventContext->SetEvents(xEventsSupplier);
238 pEventContext->ReleaseRef();
241 // XML import: reconstrution of assignment of paragraph style to outline levels (#i69629#)
242 if ( nOutlineLevel > 0 )
244 GetImport().GetTextImport()->AddOutlineStyleCandidate( nOutlineLevel,
245 GetDisplayName() );
249 void XMLTextStyleContext::SetDefaults( )
251 if( ( GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) ||
252 ( GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE ) ||
253 ( GetFamily() == XML_STYLE_FAMILY_TABLE_ROW ) )
255 Reference < XMultiServiceFactory > xFactory ( GetImport().GetModel(), UNO_QUERY);
256 if (xFactory.is())
258 Reference < XInterface > xInt = xFactory->createInstance (
259 OUString ( "com.sun.star.text.Defaults" ) );
260 Reference < XPropertySet > xProperties ( xInt, UNO_QUERY );
261 if ( xProperties.is() )
262 FillPropertySet ( xProperties );
267 void XMLTextStyleContext::Finish( sal_Bool bOverwrite )
269 XMLPropStyleContext::Finish( bOverwrite );
271 Reference < XStyle > xStyle = GetStyle();
272 // Consider set empty list style (#i69523#)
273 if ( !( mbListStyleSet ||
274 nOutlineLevel >= 0 ||
275 !sDropCapTextStyleName.isEmpty() ||
276 bHasMasterPageName ) ||
277 !xStyle.is() ||
278 !( bOverwrite || IsNew() ) )
279 return;
281 Reference < XPropertySet > xPropSet( xStyle, UNO_QUERY );
282 Reference< XPropertySetInfo > xPropSetInfo =
283 xPropSet->getPropertySetInfo();
285 if( xPropSetInfo->hasPropertyByName( sOutlineLevel ))
287 Any aAny;
288 if( nOutlineLevel >= 0 )
290 aAny <<= nOutlineLevel;
291 xPropSet->setPropertyValue( sOutlineLevel, aAny );
295 // Consider set empty list style (#i69523#)
296 if ( mbListStyleSet &&
297 xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
299 /* Only for text document from version prior OOo 2.1 resp. SO 8 PU5:
300 - Do not apply list style, if paragraph style has a default outline
301 level > 0 and thus, will be assigned to the corresponding list
302 level of the outline style. (#i70223#)
304 bool bApplyListStyle( true );
305 if ( nOutlineLevel > 0 )
307 if ( GetImport().IsTextDocInOOoFileFormat() )
309 bApplyListStyle = false;
311 else
313 sal_Int32 nUPD( 0 );
314 sal_Int32 nBuild( 0 );
315 // Check explicitly on certain versions (#i86058#)
316 if ( GetImport().getBuildIds( nUPD, nBuild ) &&
317 ( ( nUPD == 641 ) || ( nUPD == 645 ) || // prior OOo 2.0
318 ( nUPD == 680 && nBuild <= 9073 ) ) ) // OOo 2.0 - OOo 2.0.4
320 bApplyListStyle = false;
325 if ( bApplyListStyle )
327 if ( sListStyleName.isEmpty() )
329 Any aAny;
330 aAny <<= sListStyleName /* empty string */;
331 xPropSet->setPropertyValue( sNumberingStyleName, aAny );
333 else
335 // change list style name to display name
336 OUString sDisplayListStyleName(
337 GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TEXT_LIST,
338 sListStyleName ) );
339 // The families container must exist
340 const Reference < XNameContainer >& rNumStyles =
341 GetImport().GetTextImport()->GetNumberingStyles();
342 // if( rNumStyles.is() && rNumStyles->hasByName( sDisplayListStyleName ) &&
343 // xPropSetInfo->hasPropertyByName( sNumberingStyleName ) )
344 if ( rNumStyles.is() &&
345 rNumStyles->hasByName( sDisplayListStyleName ) )
347 Any aAny;
348 aAny <<= sDisplayListStyleName;
349 xPropSet->setPropertyValue( sNumberingStyleName, aAny );
355 if( !sDropCapTextStyleName.isEmpty() )
357 // change list style name to display name
358 OUString sDisplayDropCapTextStyleName(
359 GetImport().GetStyleDisplayName( XML_STYLE_FAMILY_TEXT_TEXT,
360 sDropCapTextStyleName ) );
361 // The families cointaner must exist
362 const Reference < XNameContainer >& rTextStyles =
363 GetImport().GetTextImport()->GetTextStyles();
364 if( rTextStyles.is() &&
365 rTextStyles->hasByName( sDisplayDropCapTextStyleName ) &&
366 xPropSetInfo->hasPropertyByName( sDropCapCharStyleName ) )
368 Any aAny;
369 aAny <<= sDisplayDropCapTextStyleName;
370 xPropSet->setPropertyValue( sDropCapCharStyleName, aAny );
374 if( bHasMasterPageName )
376 OUString sDisplayName(
377 GetImport().GetStyleDisplayName(
378 XML_STYLE_FAMILY_MASTER_PAGE, sMasterPageName ) );
379 // The families cointaner must exist
380 const Reference < XNameContainer >& rPageStyles =
381 GetImport().GetTextImport()->GetPageStyles();
382 if( ( sDisplayName.isEmpty() ||
383 (rPageStyles.is() &&
384 rPageStyles->hasByName( sDisplayName )) ) &&
385 xPropSetInfo->hasPropertyByName( sPageDescName ) )
387 Any aAny;
388 aAny <<= sDisplayName;
389 xPropSet->setPropertyValue( sPageDescName, aAny );
394 void XMLTextStyleContext::FillPropertySet(
395 const Reference<XPropertySet > & rPropSet )
397 // imitate the FillPropertySet of the super class, so we get a chance to
398 // catch the combined characters attribute
400 // imitate XMLPropStyleContext::FillPropertySet(...)
401 UniReference < SvXMLImportPropertyMapper > xImpPrMap =
402 ((SvXMLStylesContext *)GetStyles())->GetImportPropertyMapper(GetFamily());
403 DBG_ASSERT( xImpPrMap.is(), "Where is the import prop mapper?" );
404 if( xImpPrMap.is() )
407 // imitate SvXMLImportPropertyMapper::FillPropertySet(...)
409 // The reason for this is that we have no other way to
410 // efficiently intercept the value of combined characters. To
411 // get that value, we could iterate through the map once more,
412 // but instead we chose to insert the code into this
413 // iteration. I haven't been able to come up with a much more
414 // intelligent solution.
417 struct _ContextID_Index_Pair aContextIDs[] =
419 { CTF_COMBINED_CHARACTERS_FIELD, -1 },
420 { CTF_KEEP_TOGETHER, -1 },
421 { CTF_BORDER_MODEL, -1 },
422 { CTF_TEXT_DISPLAY, -1 },
423 { CTF_FONTFAMILYNAME, -1 },
424 { CTF_FONTFAMILYNAME_CJK, -1 },
425 { CTF_FONTFAMILYNAME_CTL, -1 },
426 { -1, -1 }
429 // get property set info
430 Reference< XPropertySetInfo > xInfo( rPropSet->getPropertySetInfo(), UNO_SET_THROW );
432 bool bAutomatic = false;
433 if( ((SvXMLStylesContext *)GetStyles())->IsAutomaticStyle() &&
434 ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT || GetFamily() == XML_STYLE_FAMILY_TEXT_PARAGRAPH ) )
436 bAutomatic = true;
437 if( !GetAutoName().isEmpty() )
439 OUString sAutoProp = ( GetFamily() == XML_STYLE_FAMILY_TEXT_TEXT ) ?
440 OUString( "CharAutoStyleName" ):
441 OUString( "ParaAutoStyleName" );
444 if ( xInfo->hasPropertyByName( sAutoProp ) )
445 rPropSet->setPropertyValue( sAutoProp, makeAny(GetAutoName()) );
446 else
447 bAutomatic = false;
449 catch( const RuntimeException& ) { throw; }
450 catch( const Exception& )
452 DBG_UNHANDLED_EXCEPTION();
453 bAutomatic = false;
457 if( bAutomatic )
458 xImpPrMap->CheckSpecialContext( GetProperties(), rPropSet, aContextIDs );
459 else
460 xImpPrMap->FillPropertySet( GetProperties(), rPropSet, aContextIDs );
462 // have we found a combined characters
463 sal_Int32 nIndex = aContextIDs[0].nIndex;
464 if ( nIndex != -1 )
466 Any& rAny = GetProperties()[nIndex].maValue;
467 sal_Bool bVal = *(sal_Bool*)rAny.getValue();
468 bHasCombinedCharactersLetter = bVal;
471 // keep-together: the application default is different from
472 // the file format default. Hence, if we always set this
473 // value; if we didn't find one, we'll set to false, the file
474 // format default.
475 // border-model: same
476 if( IsDefaultStyle() && GetFamily() == XML_STYLE_FAMILY_TABLE_ROW )
478 OUString sIsSplitAllowed( "IsSplitAllowed" );
479 DBG_ASSERT( rPropSet->getPropertySetInfo()->hasPropertyByName( sIsSplitAllowed ),
480 "property missing?" );
481 rPropSet->setPropertyValue( sIsSplitAllowed,
482 (aContextIDs[1].nIndex == -1)
483 ? makeAny( false )
484 : GetProperties()[aContextIDs[1].nIndex].maValue );
487 if( IsDefaultStyle() && GetFamily() == XML_STYLE_FAMILY_TABLE_TABLE )
489 OUString sCollapsingBorders("CollapsingBorders");
490 DBG_ASSERT( rPropSet->getPropertySetInfo()->hasPropertyByName( sCollapsingBorders ),
491 "property missing?" );
492 rPropSet->setPropertyValue( sCollapsingBorders,
493 (aContextIDs[2].nIndex == -1)
494 ? makeAny( false )
495 : GetProperties()[aContextIDs[2].nIndex].maValue );
499 // check for StarBats and StarMath fonts
501 // iterate over aContextIDs entries 3..6
502 for ( sal_Int32 i = 3; i < 7; i++ )
504 nIndex = aContextIDs[i].nIndex;
505 if ( nIndex != -1 )
507 // Found!
508 struct XMLPropertyState& rState = GetProperties()[nIndex];
509 Any rAny = rState.maValue;
510 sal_Int32 nMapperIndex = rState.mnIndex;
512 // Now check for font name in rState and set corrected value,
513 // if necessary.
514 OUString sFontName;
515 rAny >>= sFontName;
516 if ( !sFontName.isEmpty() )
518 OUString sStarBats( "StarBats" );
519 OUString sStarMath( "StarMath" );
520 if ( sFontName.equalsIgnoreAsciiCase( sStarBats ) ||
521 sFontName.equalsIgnoreAsciiCase( sStarMath ) )
523 // construct new value
524 sFontName = OUString("StarSymbol");
525 Any aAny( rAny );
526 aAny <<= sFontName;
528 // get property set mapper
529 UniReference<XMLPropertySetMapper> rPropMapper =
530 xImpPrMap->getPropertySetMapper();
532 // set property
533 OUString rPropertyName(
534 rPropMapper->GetEntryAPIName(nMapperIndex) );
535 if ( xInfo->hasPropertyByName( rPropertyName ) )
537 rPropSet->setPropertyValue( rPropertyName, aAny );
540 // else: "normal" style name -> no correction is necessary
542 // else: no style name found -> illegal value -> ignore
548 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */