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