1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 <PageMasterImportContext.hxx>
21 #include <xmloff/xmlimppr.hxx>
22 #include <xmloff/xmlnamespace.hxx>
23 #include <xmloff/xmlprmap.hxx>
24 #include <xmloff/xmltoken.hxx>
25 #include "PageMasterPropHdl.hxx"
26 #include "PagePropertySetContext.hxx"
27 #include "PageHeaderFooterContext.hxx"
28 #include <PageMasterStyleMap.hxx>
29 #include <com/sun/star/frame/XModel.hpp>
30 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31 #include <osl/diagnose.h>
34 #include <com/sun/star/beans/XPropertySet.hpp>
35 #include <com/sun/star/beans/XPropertySetInfo.hpp>
36 #include <com/sun/star/drawing/FillStyle.hpp>
37 #include <com/sun/star/drawing/BitmapMode.hpp>
38 #include <xmloff/xmlerror.hxx>
39 #include <xmloff/XMLTextMasterPageContext.hxx>
41 using namespace ::com::sun::star
;
42 using namespace ::xmloff::token
;
43 using namespace ::com::sun::star::uno
;
44 using namespace ::com::sun::star::lang
;
47 using namespace ::com::sun::star::beans
;
49 void PageStyleContext::SetAttribute( sal_Int32 nElement
,
50 const OUString
& rValue
)
52 if( nElement
== XML_ELEMENT(STYLE
, XML_PAGE_USAGE
) )
58 XMLPropStyleContext::SetAttribute( nElement
, rValue
);
63 PageStyleContext::PageStyleContext( SvXMLImport
& rImport
,
64 SvXMLStylesContext
& rStyles
,
66 XMLPropStyleContext( rImport
, rStyles
, XmlStyleFamily::PAGE_MASTER
, bDefaultStyle
),
67 m_bIsFillStyleAlreadyConverted(false) //
71 PageStyleContext::~PageStyleContext()
75 css::uno::Reference
< css::xml::sax::XFastContextHandler
> PageStyleContext::createFastChildContext(
77 const css::uno::Reference
< css::xml::sax::XFastAttributeList
>& xAttrList
)
79 if( nElement
== XML_ELEMENT(STYLE
, XML_HEADER_STYLE
) ||
80 nElement
== XML_ELEMENT(STYLE
, XML_FOOTER_STYLE
) )
82 bool bHeader
= nElement
== XML_ELEMENT(STYLE
, XML_HEADER_STYLE
);
83 rtl::Reference
< SvXMLImportPropertyMapper
> xImpPrMap
=
84 GetStyles()->GetImportPropertyMapper( GetFamily() );
87 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
= xImpPrMap
->getPropertySetMapper();
90 nFlag
= CTF_PM_HEADERFLAG
;
92 nFlag
= CTF_PM_FOOTERFLAG
;
93 sal_Int32
nStartIndex (-1);
94 sal_Int32
nEndIndex (-1);
98 while ( nIndex
< rMapper
->GetEntryCount() && !bEnd
)
100 if ((rMapper
->GetEntryContextId( nIndex
) & CTF_PM_FLAGMASK
) == nFlag
)
105 nStartIndex
= nIndex
;
117 return new PageHeaderFooterContext(GetImport(),
118 GetProperties(), xImpPrMap
, nStartIndex
, nEndIndex
, bHeader
);
122 if( nElement
== XML_ELEMENT(STYLE
, XML_PAGE_LAYOUT_PROPERTIES
) )
124 rtl::Reference
< SvXMLImportPropertyMapper
> xImpPrMap
=
125 GetStyles()->GetImportPropertyMapper( GetFamily() );
128 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
= xImpPrMap
->getPropertySetMapper();
129 sal_Int32
nEndIndex (-1);
131 sal_Int32 nIndex
= 0;
132 sal_Int16 nContextID
;
133 while ( nIndex
< rMapper
->GetEntryCount() && !bEnd
)
135 nContextID
= rMapper
->GetEntryContextId( nIndex
);
136 if (nContextID
&& ((nContextID
& CTF_PM_FLAGMASK
) != XML_PM_CTF_START
))
145 return new PagePropertySetContext( GetImport(), nElement
,
147 XML_TYPE_PROP_PAGE_LAYOUT
,
149 xImpPrMap
, 0, nEndIndex
, Page
);
153 return XMLPropStyleContext::createFastChildContext(nElement
, xAttrList
);
156 void PageStyleContext::FillPropertySet(const uno::Reference
<beans::XPropertySet
> &)
158 assert(false); // don't call this virtual, call function below
161 void PageStyleContext::FillPropertySet_PageStyle(
162 const uno::Reference
<beans::XPropertySet
> & xPropSet
,
163 XMLPropStyleContext
*const pDrawingPageStyle
)
165 // need to filter out old fill definitions when the new ones are used. The new
166 // ones are used when a FillStyle is defined
167 if(!m_bIsFillStyleAlreadyConverted
&& !GetProperties().empty())
169 static constexpr OUStringLiteral
s_FillStyle(u
"FillStyle");
170 static constexpr OUStringLiteral
s_HeaderFillStyle(u
"HeaderFillStyle");
171 static constexpr OUStringLiteral
s_FooterFillStyle(u
"FooterFillStyle");
173 // note: the function must only check by property name, not any id/flag!
174 if (doNewDrawingLayerFillStyleDefinitionsExist(s_FillStyle
)
175 || (pDrawingPageStyle
&& pDrawingPageStyle
->doNewDrawingLayerFillStyleDefinitionsExist(s_FillStyle
)))
177 deactivateOldFillStyleDefinitions(getStandardSet());
180 if(doNewDrawingLayerFillStyleDefinitionsExist(s_HeaderFillStyle
))
182 deactivateOldFillStyleDefinitions(getHeaderSet());
185 if(doNewDrawingLayerFillStyleDefinitionsExist(s_FooterFillStyle
))
187 deactivateOldFillStyleDefinitions(getFooterSet());
190 m_bIsFillStyleAlreadyConverted
= true;
193 // do not use XMLPropStyleContext::FillPropertySet, we need to handle this ourselves since
194 // we have properties which use the MID_FLAG_NO_PROPERTY_IMPORT flag since they need some special
196 rtl::Reference
< SvXMLImportPropertyMapper
> xImpPrMap
= GetStyles()->GetImportPropertyMapper(GetFamily());
200 // properties that need special handling because they need the used name to be translated first
201 struct ContextID_Index_Pair aContextIDs
[] =
203 { CTF_PM_FILLGRADIENTNAME
, -1, drawing::FillStyle::FillStyle_GRADIENT
},
204 { CTF_PM_FILLTRANSNAME
, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
},
205 { CTF_PM_FILLHATCHNAME
, -1, drawing::FillStyle::FillStyle_HATCH
},
206 { CTF_PM_FILLBITMAPNAME
, -1, drawing::FillStyle::FillStyle_BITMAP
},
208 // also need to special handling for header entries
209 { CTF_PM_HEADERFILLGRADIENTNAME
, -1, drawing::FillStyle::FillStyle_GRADIENT
},
210 { CTF_PM_HEADERFILLTRANSNAME
, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
},
211 { CTF_PM_HEADERFILLHATCHNAME
, -1, drawing::FillStyle::FillStyle_HATCH
},
212 { CTF_PM_HEADERFILLBITMAPNAME
, -1, drawing::FillStyle::FillStyle_BITMAP
},
214 // also need to special handling for footer entries
215 { CTF_PM_FOOTERFILLGRADIENTNAME
, -1, drawing::FillStyle::FillStyle_GRADIENT
},
216 { CTF_PM_FOOTERFILLTRANSNAME
, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
},
217 { CTF_PM_FOOTERFILLHATCHNAME
, -1, drawing::FillStyle::FillStyle_HATCH
},
218 { CTF_PM_FOOTERFILLBITMAPNAME
, -1, drawing::FillStyle::FillStyle_BITMAP
},
220 {-1, -1, drawing::FillStyle::FillStyle_GRADIENT
}
223 // the style families associated with the same index modulo 4
224 static const XmlStyleFamily aFamilies
[] =
226 XmlStyleFamily::SD_GRADIENT_ID
,
227 XmlStyleFamily::SD_GRADIENT_ID
,
228 XmlStyleFamily::SD_HATCH_ID
,
229 XmlStyleFamily::SD_FILL_IMAGE_ID
232 // Fill PropertySet, but let it handle special properties not itself
233 xImpPrMap
->FillPropertySet(GetProperties(), xPropSet
, aContextIDs
);
235 // get property set mapper
236 const rtl::Reference
< XMLPropertySetMapper
>& rMapper
= xImpPrMap
->getPropertySetMapper();
237 Reference
<XPropertySetInfo
> const xInfo(xPropSet
->getPropertySetInfo());
239 // don't look at the attributes, look at the property, could
240 // theoretically be inherited and we don't want to delete erroneously
241 drawing::FillStyle fillStyle
{drawing::FillStyle_NONE
};
242 drawing::FillStyle fillStyleHeader
{drawing::FillStyle_NONE
};
243 drawing::FillStyle fillStyleFooter
{drawing::FillStyle_NONE
};
244 if (xInfo
->hasPropertyByName("FillStyle")) // SwXTextDefaults lacks it?
246 xPropSet
->getPropertyValue("FillStyle") >>= fillStyle
;
247 xPropSet
->getPropertyValue("HeaderFillStyle") >>= fillStyleHeader
;
248 xPropSet
->getPropertyValue("FooterFillStyle") >>= fillStyleFooter
;
251 // handle special attributes which have MID_FLAG_NO_PROPERTY_IMPORT set
252 for(sal_uInt16 i
= 0; aContextIDs
[i
].nContextID
!= -1; i
++)
254 sal_Int32 nIndex
= aContextIDs
[i
].nIndex
;
258 drawing::FillStyle
const* pFillStyle(nullptr);
259 switch(aContextIDs
[i
].nContextID
)
261 case CTF_PM_FILLGRADIENTNAME
:
262 case CTF_PM_FILLTRANSNAME
:
263 case CTF_PM_FILLHATCHNAME
:
264 case CTF_PM_FILLBITMAPNAME
:
265 pFillStyle
= &fillStyle
;
267 case CTF_PM_HEADERFILLGRADIENTNAME
:
268 case CTF_PM_HEADERFILLTRANSNAME
:
269 case CTF_PM_HEADERFILLHATCHNAME
:
270 case CTF_PM_HEADERFILLBITMAPNAME
:
271 if (!pFillStyle
) { pFillStyle
= &fillStyleHeader
; }
273 case CTF_PM_FOOTERFILLGRADIENTNAME
:
274 case CTF_PM_FOOTERFILLTRANSNAME
:
275 case CTF_PM_FOOTERFILLHATCHNAME
:
276 case CTF_PM_FOOTERFILLBITMAPNAME
:
278 if (!pFillStyle
) { pFillStyle
= &fillStyleFooter
; }
279 struct XMLPropertyState
& rState
= GetProperties()[nIndex
];
281 rState
.maValue
>>= sStyleName
;
283 if (aContextIDs
[i
].nExpectedFillStyle
!= drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
284 && aContextIDs
[i
].nExpectedFillStyle
!= *pFillStyle
)
286 SAL_INFO("xmloff.style", "PageStyleContext: dropping fill named item: " << sStyleName
);
287 break; // ignore it, it's not used
289 // translate the used name from ODF intern to the name used in the Model
290 sStyleName
= GetImport().GetStyleDisplayName(aFamilies
[i
%4], sStyleName
);
295 const OUString
& rPropertyName
= rMapper
->GetEntryAPIName(rState
.mnIndex
);
297 if(xInfo
->hasPropertyByName(rPropertyName
))
299 xPropSet
->setPropertyValue(rPropertyName
,Any(sStyleName
));
302 catch(css::lang::IllegalArgumentException
& e
)
304 Sequence
<OUString
> aSeq
{ sStyleName
};
305 GetImport().SetError(
306 XMLERROR_STYLE_PROP_VALUE
| XMLERROR_FLAG_WARNING
,
307 aSeq
,e
.Message
,nullptr);
317 OSL_ENSURE(xImpPrMap
.is(), "Got no SvXMLImportPropertyMapper (!)");
320 // pDrawingPageStyle overrides this
321 if (pDrawingPageStyle
)
323 pDrawingPageStyle
->FillPropertySet(xPropSet
);
325 // horrible heuristic to guess BackgroundFullSize for Writer < 7.0
326 else if (!IsDefaultStyle() // ignore pool default, only fix existing styles
327 && (GetImport().isGeneratorVersionOlderThan(SvXMLImport::AOO_4x
, SvXMLImport::LO_7x
)
328 // also for AOO 4.x, assume there won't ever be a 4.2
329 || GetImport().getGeneratorVersion() == SvXMLImport::AOO_4x
))
331 bool isFullSize(true); // default is current LO default
332 drawing::FillStyle fillStyle
{drawing::FillStyle_NONE
};
333 xPropSet
->getPropertyValue("FillStyle") >>= fillStyle
;
334 if (GetImport().isGeneratorVersionOlderThan(SvXMLImport::AOO_4x
, SvXMLImport::LO_63x
)
335 // also for AOO 4.x, assume there won't ever be a 4.2
336 || GetImport().getGeneratorVersion() == SvXMLImport::AOO_4x
)
338 // before LO 6.3, always inside the margins (but ignore it if NONE)
339 if (fillStyle
!= drawing::FillStyle_NONE
)
346 // LO 6.3/6.4: guess depending on fill style/bitmap mode
347 // this should work even if the document doesn't contain fill style
348 // but only old background attributes
349 // (can't use the aContextIDs stuff above because that requires
350 // re-routing through handleSpecialItem())
353 case drawing::FillStyle_NONE
:
355 case drawing::FillStyle_SOLID
:
356 case drawing::FillStyle_GRADIENT
:
357 case drawing::FillStyle_HATCH
:
360 case drawing::FillStyle_BITMAP
:
362 drawing::BitmapMode bitmapMode
{};
363 xPropSet
->getPropertyValue("FillBitmapMode") >>= bitmapMode
;
366 case drawing::BitmapMode_REPEAT
:
369 case drawing::BitmapMode_STRETCH
:
370 case drawing::BitmapMode_NO_REPEAT
:
382 // set it explicitly if it's not the default
385 SAL_INFO("xmloff.style", "FillPropertySet_PageStyle: Heuristically resetting BackgroundFullSize");
386 xPropSet
->setPropertyValue("BackgroundFullSize", uno::Any(isFullSize
));
390 // old code, replaced by above stuff
391 // XMLPropStyleContext::FillPropertySet(rPropSet);
393 if (!sPageUsage
.isEmpty())
396 XMLPMPropHdl_PageStyleLayout aPageUsageHdl
;
397 if (aPageUsageHdl
.importXML(sPageUsage
, aPageUsage
, GetImport().GetMM100UnitConverter()))
398 xPropSet
->setPropertyValue("PageStyleLayout", aPageUsage
);
402 extern ContextID_Index_Pair
const g_MasterPageContextIDs
[] =
404 { CTF_PM_FILLGRADIENTNAME
, -1, drawing::FillStyle::FillStyle_GRADIENT
},
405 { CTF_PM_FILLTRANSNAME
, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
},
406 { CTF_PM_FILLHATCHNAME
, -1, drawing::FillStyle::FillStyle_HATCH
},
407 { CTF_PM_FILLBITMAPNAME
, -1, drawing::FillStyle::FillStyle_BITMAP
},
409 {-1, -1, drawing::FillStyle::FillStyle_MAKE_FIXED_SIZE
}
412 extern XmlStyleFamily
const g_MasterPageFamilies
[] =
414 XmlStyleFamily::SD_GRADIENT_ID
,
415 XmlStyleFamily::SD_GRADIENT_ID
,
416 XmlStyleFamily::SD_HATCH_ID
,
417 XmlStyleFamily::SD_FILL_IMAGE_ID
420 // text grid enhancement for better CJK support
421 //set default page layout style
422 void PageStyleContext::SetDefaults( )
424 Reference
< XMultiServiceFactory
> xFactory ( GetImport().GetModel(), UNO_QUERY
);
427 Reference
< XInterface
> xInt
= xFactory
->createInstance( "com.sun.star.text.Defaults" );
428 Reference
< beans::XPropertySet
> xProperties ( xInt
, UNO_QUERY
);
429 if ( xProperties
.is() )
430 FillPropertySet_PageStyle(xProperties
, nullptr);
434 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */