xref: /trunk/main/xmloff/source/text/txtftne.cxx (revision 63bba73c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_xmloff.hxx"
26 
27 
28 /** @#file
29  *
30  * This file implements XMLTextParagraphExport methods to export
31  * - footnotes
32  * - endnotes
33  * - footnote configuration elements
34  * - endnote configuration elements
35  */
36 #include <tools/debug.hxx>
37 #include <rtl/ustrbuf.hxx>
38 #include <com/sun/star/lang/XServiceInfo.hpp>
39 #include <com/sun/star/beans/XPropertySet.hpp>
40 #include <com/sun/star/beans/XPropertyState.hpp>
41 #include <com/sun/star/text/XTextDocument.hpp>
42 #include <com/sun/star/text/XText.hpp>
43 #include <com/sun/star/text/XTextContent.hpp>
44 #include <com/sun/star/text/XFootnote.hpp>
45 #include <com/sun/star/text/XFootnotesSupplier.hpp>
46 #include <com/sun/star/text/XEndnotesSupplier.hpp>
47 #include <com/sun/star/text/FootnoteNumbering.hpp>
48 #include <com/sun/star/container/XNameReplace.hpp>
49 #include <xmloff/xmltoken.hxx>
50 #include "xmloff/xmlnmspe.hxx"
51 #include <xmloff/xmlnumfe.hxx>
52 #include <xmloff/xmluconv.hxx>
53 #include <xmloff/nmspmap.hxx>
54 #include <xmloff/xmlexp.hxx>
55 #include <xmloff/families.hxx>
56 #include <xmloff/xmlnume.hxx>
57 #include "XMLTextCharStyleNamesElementExport.hxx"
58 #include <xmloff/XMLEventExport.hxx>
59 #ifndef _XMLOFF_TXTPARAE_HXX
60 #include <xmloff/txtparae.hxx>
61 #endif
62 
63 using ::rtl::OUString;
64 using ::rtl::OUStringBuffer;
65 
66 using namespace ::com::sun::star;
67 using namespace ::com::sun::star::uno;
68 using namespace ::com::sun::star::lang;
69 using namespace ::com::sun::star::beans;
70 using namespace ::com::sun::star::text;
71 using namespace ::com::sun::star::container;
72 using namespace ::xmloff::token;
73 
74 
exportTextFootnote(const Reference<XPropertySet> & rPropSet,const OUString & rText,sal_Bool bAutoStyles,sal_Bool bIsProgress)75 void XMLTextParagraphExport::exportTextFootnote(
76 	const Reference<XPropertySet> & rPropSet,
77 	const OUString& rText,
78 	sal_Bool bAutoStyles, sal_Bool bIsProgress )
79 {
80 	// get footnote and associated text
81 	Any aAny;
82 	aAny = rPropSet->getPropertyValue(sFootnote);
83 	Reference<XFootnote> xFootnote;
84 	aAny >>= xFootnote;
85 	Reference<XText> xText(xFootnote, UNO_QUERY);
86 
87 	// are we an endnote?
88 	Reference<XServiceInfo> xServiceInfo( xFootnote, UNO_QUERY );
89 	sal_Bool bIsEndnote = xServiceInfo->supportsService(sTextEndnoteService);
90 
91 	if (bAutoStyles)
92 	{
93 		// handle formatting of citation mark
94 		Add( XML_STYLE_FAMILY_TEXT_TEXT, rPropSet );
95 
96 		// handle formatting within footnote
97         exportTextFootnoteHelper(xFootnote, xText, rText,
98                                  bAutoStyles, bIsEndnote, bIsProgress );
99     }
100 	else
101 	{
102 		// create span (for citation mark) if necessary; footnote content
103 		// wil be handled via exportTextFootnoteHelper, exportText
104     	sal_Bool bHasHyperlink;
105 		sal_Bool bIsUICharStyle = sal_False;
106         sal_Bool bHasAutoStyle = sal_False;
107 
108 		OUString sStyle = FindTextStyleAndHyperlink( rPropSet, bHasHyperlink,
109                                                      bIsUICharStyle, bHasAutoStyle );
110 
111         // export hyperlink (if we have one)
112 		Reference < XPropertySetInfo > xPropSetInfo;
113 		if( bHasHyperlink )
114 		{
115 			Reference<XPropertyState> xPropState( rPropSet, UNO_QUERY );
116 			xPropSetInfo = rPropSet->getPropertySetInfo();
117 			bHasHyperlink =
118 				addHyperlinkAttributes( rPropSet, xPropState, xPropSetInfo );
119 		}
120 		SvXMLElementExport aHyperlink( GetExport(), bHasHyperlink,
121 									   XML_NAMESPACE_TEXT, XML_A,
122 									   sal_False, sal_False );
123 
124 		if( bHasHyperlink )
125 		{
126 			// export events (if supported)
127 			OUString sHyperLinkEvents(RTL_CONSTASCII_USTRINGPARAM(
128 				"HyperLinkEvents"));
129 			if (xPropSetInfo->hasPropertyByName(sHyperLinkEvents))
130 			{
131 				Any a = rPropSet->getPropertyValue(sHyperLinkEvents);
132 				Reference<XNameReplace> xName;
133 				a >>= xName;
134 				GetExport().GetEventExport().Export(xName, sal_False);
135 			}
136 		}
137 
138 		{
139 			XMLTextCharStyleNamesElementExport aCharStylesExport(
140 				GetExport(), bIsUICharStyle &&
141 							 aCharStyleNamesPropInfoCache.hasProperty(
142                                                     rPropSet ), bHasAutoStyle,
143 				rPropSet, sCharStyleNames );
144 			if( sStyle.getLength() )
145 			{
146 				GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
147 										  GetExport().EncodeStyleName( sStyle ) );
148 				SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT,
149 										  XML_SPAN, sal_False, sal_False );
150                 exportTextFootnoteHelper(xFootnote, xText, rText,
151 										 bAutoStyles, bIsEndnote, bIsProgress );
152             }
153 			else
154 			{
155                 exportTextFootnoteHelper(xFootnote, xText, rText,
156 										 bAutoStyles, bIsEndnote, bIsProgress );
157             }
158 		}
159 	}
160 }
161 
162 
exportTextFootnoteHelper(const Reference<XFootnote> & rFootnote,const Reference<XText> & rText,const OUString & rTextString,sal_Bool bAutoStyles,sal_Bool bIsEndnote,sal_Bool bIsProgress)163 void XMLTextParagraphExport::exportTextFootnoteHelper(
164 	const Reference<XFootnote> & rFootnote,
165 	const Reference<XText> & rText,
166 	const OUString& rTextString,
167 	sal_Bool bAutoStyles,
168 	sal_Bool bIsEndnote,
169 	sal_Bool bIsProgress )
170 {
171 	if (bAutoStyles)
172 	{
173 		exportText(rText, bAutoStyles, bIsProgress, sal_True );
174 	}
175 	else
176 	{
177 		// export reference Id (for reference fields)
178 		Reference<XPropertySet> xPropSet(rFootnote, UNO_QUERY);
179 		Any aAny = xPropSet->getPropertyValue(sReferenceId);
180 		sal_Int32 nNumber = 0;
181 		aAny >>= nNumber;
182 		OUStringBuffer aBuf;
183 		aBuf.appendAscii("ftn");
184 		aBuf.append(nNumber);
185 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_ID,
186 								 aBuf.makeStringAndClear());
187 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NOTE_CLASS,
188 								 GetXMLToken( bIsEndnote ? XML_ENDNOTE
189 									 					 : XML_FOOTNOTE ) );
190 
191 		SvXMLElementExport aNote(GetExport(), XML_NAMESPACE_TEXT,
192 								 XML_NOTE, sal_False, sal_False);
193 		{
194 			// handle label vs. automatic numbering
195 			OUString sLabel = rFootnote->getLabel();
196 			if (sLabel.getLength()>0)
197 			{
198 				GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_LABEL,
199 										 sLabel);
200 			}
201 			// else: automatic numbering -> no attribute
202 
203 			SvXMLElementExport aCite(GetExport(), XML_NAMESPACE_TEXT,
204 									 XML_NOTE_CITATION, sal_False, sal_False);
205 			GetExport().Characters(rTextString);
206 		}
207 
208 		{
209 			SvXMLElementExport aBody(GetExport(), XML_NAMESPACE_TEXT,
210 									 XML_NOTE_BODY, sal_False, sal_False);
211 			exportText(rText, bAutoStyles, bIsProgress, sal_True );
212 		}
213 	}
214 }
215 
216 
exportTextFootnoteConfiguration()217 void XMLTextParagraphExport::exportTextFootnoteConfiguration()
218 {
219 	// footnote settings
220 	Reference<XFootnotesSupplier> aFootnotesSupplier(GetExport().GetModel(),
221 													 UNO_QUERY);
222 	Reference<XPropertySet> aFootnoteConfiguration(
223 		aFootnotesSupplier->getFootnoteSettings());
224 	exportTextFootnoteConfigurationHelper(aFootnoteConfiguration, sal_False);
225 
226 	// endnote settings
227 	Reference<XEndnotesSupplier> aEndnotesSupplier(GetExport().GetModel(),
228 												   UNO_QUERY);
229 	Reference<XPropertySet> aEndnoteConfiguration(
230 		aEndnotesSupplier->getEndnoteSettings());
231 	exportTextFootnoteConfigurationHelper(aEndnoteConfiguration, sal_True);
232 }
233 
234 
lcl_exportString(SvXMLExport & rExport,const Reference<XPropertySet> & rPropSet,const OUString & sProperty,sal_uInt16 nPrefix,enum XMLTokenEnum eElement,sal_Bool bEncodeName,sal_Bool bOmitIfEmpty)235 void lcl_exportString(
236 	SvXMLExport& rExport,
237 	const Reference<XPropertySet> & rPropSet,
238 	const OUString& sProperty,
239 	sal_uInt16 nPrefix,
240 	enum XMLTokenEnum eElement,
241 	sal_Bool bEncodeName,
242 	sal_Bool bOmitIfEmpty)
243 {
244 	DBG_ASSERT( eElement != XML_TOKEN_INVALID, "need element token");
245 
246 	Any aAny = rPropSet->getPropertyValue(sProperty);
247 	OUString sTmp;
248 	aAny >>= sTmp;
249 	if (!bOmitIfEmpty || (sTmp.getLength() > 0))
250 	{
251 		if( bEncodeName )
252 			sTmp = rExport.EncodeStyleName( sTmp );
253 		rExport.AddAttribute(nPrefix, eElement, sTmp);
254 	}
255 }
256 
exportTextFootnoteConfigurationHelper(const Reference<XPropertySet> & rFootnoteConfig,sal_Bool bIsEndnote)257 void XMLTextParagraphExport::exportTextFootnoteConfigurationHelper(
258 	const Reference<XPropertySet> & rFootnoteConfig,
259 	sal_Bool bIsEndnote)
260 {
261 	GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NOTE_CLASS,
262 							 GetXMLToken( bIsEndnote ? XML_ENDNOTE
263 													 : XML_FOOTNOTE ) );
264 	// default/paragraph style
265 	lcl_exportString( GetExport(), rFootnoteConfig,
266 					  sParaStyleName,
267 					  XML_NAMESPACE_TEXT, XML_DEFAULT_STYLE_NAME,
268 					  sal_True, sal_True);
269 
270 	// citation style
271 	lcl_exportString( GetExport(), rFootnoteConfig,
272 					  sCharStyleName,
273 					  XML_NAMESPACE_TEXT, XML_CITATION_STYLE_NAME,
274 					  sal_True, sal_True);
275 
276 	// citation body style
277 	lcl_exportString( GetExport(), rFootnoteConfig,
278 					  sAnchorCharStyleName,
279 					  XML_NAMESPACE_TEXT, XML_CITATION_BODY_STYLE_NAME,
280 					  sal_True, sal_True);
281 
282 	// page style
283 	lcl_exportString( GetExport(), rFootnoteConfig,
284 					  sPageStyleName,
285 					  XML_NAMESPACE_TEXT, XML_MASTER_PAGE_NAME,
286 					  sal_True, sal_True );
287 
288 	// prefix
289 	lcl_exportString( GetExport(), rFootnoteConfig, sPrefix,
290 					  XML_NAMESPACE_STYLE, XML_NUM_PREFIX, sal_False, sal_True);
291 
292 	// suffix
293 	lcl_exportString( GetExport(), rFootnoteConfig, sSuffix,
294 					  XML_NAMESPACE_STYLE, XML_NUM_SUFFIX, sal_False, sal_True);
295 
296 
297 
298 	Any aAny;
299 
300 	// numbering style
301 	OUStringBuffer sBuffer;
302 	aAny = rFootnoteConfig->getPropertyValue(sNumberingType);
303 	sal_Int16 nNumbering = 0;
304 	aAny >>= nNumbering;
305 	GetExport().GetMM100UnitConverter().convertNumFormat( sBuffer, nNumbering);
306 	GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_FORMAT,
307 							 sBuffer.makeStringAndClear() );
308 	GetExport().GetMM100UnitConverter().convertNumLetterSync( sBuffer, nNumbering);
309 	if (sBuffer.getLength() )
310 	{
311 		GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_NUM_LETTER_SYNC,
312                                  sBuffer.makeStringAndClear());
313 	}
314 
315 	// StartAt / start-value
316 	aAny = rFootnoteConfig->getPropertyValue(sStartAt);
317 	sal_Int16 nOffset = 0;
318 	aAny >>= nOffset;
319 	SvXMLUnitConverter::convertNumber(sBuffer, (sal_Int32)nOffset);
320 	GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_START_VALUE,
321 							 sBuffer.makeStringAndClear());
322 
323 	// some properties are for footnotes only
324 	if (!bIsEndnote)
325 	{
326 		// footnotes position
327 		aAny = rFootnoteConfig->getPropertyValue(
328 			sPositionEndOfDoc);
329 		GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_FOOTNOTES_POSITION,
330                                  ( (*(sal_Bool *)aAny.getValue()) ?
331 										XML_DOCUMENT : XML_PAGE ) );
332 
333 		aAny = rFootnoteConfig->getPropertyValue(sFootnoteCounting);
334 		sal_Int16 nTmp = 0;
335 		aAny >>= nTmp;
336 		enum XMLTokenEnum eElement;
337 		switch (nTmp)
338 		{
339 			case FootnoteNumbering::PER_PAGE:
340 				eElement = XML_PAGE;
341 				break;
342 			case FootnoteNumbering::PER_CHAPTER:
343 				eElement = XML_CHAPTER;
344 				break;
345 			case FootnoteNumbering::PER_DOCUMENT:
346 			default:
347 				eElement = XML_DOCUMENT;
348 				break;
349 		}
350 		GetExport().AddAttribute(XML_NAMESPACE_TEXT,
351                                  XML_START_NUMBERING_AT, eElement);
352 	}
353 
354 	// element
355 	SvXMLElementExport aFootnoteConfigElement(
356         GetExport(), XML_NAMESPACE_TEXT,
357         XML_NOTES_CONFIGURATION,
358         sal_True, sal_True);
359 
360 	// two element for footnote content
361 	if (!bIsEndnote)
362 	{
363 		OUString sTmp;
364 
365 		// end notice / quo vadis
366 		aAny = rFootnoteConfig->getPropertyValue(sEndNotice);
367 		aAny >>= sTmp;
368 
369 		if (sTmp.getLength() > 0)
370 		{
371 			SvXMLElementExport aElem(GetExport(), XML_NAMESPACE_TEXT,
372 									 XML_FOOTNOTE_CONTINUATION_NOTICE_FORWARD,
373 									 sal_True, sal_False);
374 			GetExport().Characters(sTmp);
375 		}
376 
377 		// begin notice / ergo sum
378 		aAny = rFootnoteConfig->getPropertyValue(sBeginNotice);
379 		aAny >>= sTmp;
380 
381 		if (sTmp.getLength() > 0)
382 		{
383 			SvXMLElementExport aElem(GetExport(), XML_NAMESPACE_TEXT,
384 									 XML_FOOTNOTE_CONTINUATION_NOTICE_BACKWARD,
385 									 sal_True, sal_False);
386 			GetExport().Characters(sTmp);
387 		}
388 	}
389 }
390