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 #include "XMLSectionExport.hxx"
27 #include <rtl/ustring.hxx>
28 #include <rtl/ustrbuf.hxx>
29
30 #include <vector>
31
32
33 #include <com/sun/star/lang/XServiceInfo.hpp>
34 #include <com/sun/star/lang/Locale.hpp>
35 #include <com/sun/star/container/XIndexReplace.hpp>
36 #include <com/sun/star/beans/XPropertySet.hpp>
37 #include <com/sun/star/beans/PropertyValue.hpp>
38 #include <com/sun/star/beans/PropertyValues.hpp>
39 #include <com/sun/star/beans/PropertyState.hpp>
40 #include <com/sun/star/text/XText.hpp>
41 #include <com/sun/star/text/XTextSection.hpp>
42 #include <com/sun/star/text/SectionFileLink.hpp>
43 #include <com/sun/star/container/XNamed.hpp>
44 #include <com/sun/star/container/XNameAccess.hpp>
45 #include <com/sun/star/text/XDocumentIndex.hpp>
46 #include <com/sun/star/uno/XInterface.hpp>
47 #include <com/sun/star/text/BibliographyDataField.hpp>
48 #include <com/sun/star/text/XTextFieldsSupplier.hpp>
49 #include <com/sun/star/text/XChapterNumberingSupplier.hpp>
50 #include <com/sun/star/text/ChapterFormat.hpp> //i90246
51 #include <xmloff/xmltoken.hxx>
52 #include "xmloff/xmlnmspe.hxx"
53 #include <xmloff/families.hxx>
54 #include <xmloff/xmluconv.hxx>
55 #include <xmloff/nmspmap.hxx>
56 #include <xmloff/xmlexp.hxx>
57 #include <xmloff/xmltkmap.hxx>
58 #include "txtflde.hxx"
59 #include <svl/PasswordHelper.hxx>
60 #include <unotools/saveopt.hxx>
61
62
63
64 using namespace ::com::sun::star;
65 using namespace ::com::sun::star::text;
66 using namespace ::com::sun::star::uno;
67 using namespace ::std;
68 using namespace ::xmloff::token;
69
70 using ::rtl::OUString;
71 using ::rtl::OUStringBuffer;
72 using ::com::sun::star::beans::XPropertySet;
73 using ::com::sun::star::beans::PropertyValue;
74 using ::com::sun::star::beans::PropertyValues;
75 using ::com::sun::star::beans::PropertyState;
76 using ::com::sun::star::container::XIndexReplace;
77 using ::com::sun::star::container::XNameAccess;
78 using ::com::sun::star::container::XNamed;
79 using ::com::sun::star::lang::XServiceInfo;
80 using ::com::sun::star::lang::Locale;
81 using ::com::sun::star::uno::XInterface;
82
83
XMLSectionExport(SvXMLExport & rExp,XMLTextParagraphExport & rParaExp)84 XMLSectionExport::XMLSectionExport(
85 SvXMLExport& rExp,
86 XMLTextParagraphExport& rParaExp)
87 : sCondition(RTL_CONSTASCII_USTRINGPARAM("Condition"))
88 , sCreateFromChapter(RTL_CONSTASCII_USTRINGPARAM("CreateFromChapter"))
89 , sCreateFromEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromEmbeddedObjects"))
90 , sCreateFromGraphicObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromGraphicObjects"))
91 , sCreateFromLabels(RTL_CONSTASCII_USTRINGPARAM("CreateFromLabels"))
92 , sCreateFromMarks(RTL_CONSTASCII_USTRINGPARAM("CreateFromMarks"))
93 , sCreateFromOtherEmbeddedObjects(RTL_CONSTASCII_USTRINGPARAM("CreateFromOtherEmbeddedObjects"))
94 , sCreateFromOutline(RTL_CONSTASCII_USTRINGPARAM("CreateFromOutline"))
95 , sCreateFromStarCalc(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarCalc"))
96 , sCreateFromStarChart(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarChart"))
97 , sCreateFromStarDraw(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarDraw"))
98 , sCreateFromStarImage(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarImage"))
99 , sCreateFromStarMath(RTL_CONSTASCII_USTRINGPARAM("CreateFromStarMath"))
100 , sCreateFromTables(RTL_CONSTASCII_USTRINGPARAM("CreateFromTables"))
101 , sCreateFromTextFrames(RTL_CONSTASCII_USTRINGPARAM("CreateFromTextFrames"))
102 , sDdeCommandElement(RTL_CONSTASCII_USTRINGPARAM("DDECommandElement"))
103 , sDdeCommandFile(RTL_CONSTASCII_USTRINGPARAM("DDECommandFile"))
104 , sDdeCommandType(RTL_CONSTASCII_USTRINGPARAM("DDECommandType"))
105 , sFileLink(RTL_CONSTASCII_USTRINGPARAM("FileLink"))
106 , sIsCaseSensitive(RTL_CONSTASCII_USTRINGPARAM("IsCaseSensitive"))
107 , sIsProtected(RTL_CONSTASCII_USTRINGPARAM("IsProtected"))
108 , sIsVisible(RTL_CONSTASCII_USTRINGPARAM("IsVisible"))
109 , sLabelCategory(RTL_CONSTASCII_USTRINGPARAM("LabelCategory"))
110 , sLabelDisplayType(RTL_CONSTASCII_USTRINGPARAM("LabelDisplayType"))
111 , sLevel(RTL_CONSTASCII_USTRINGPARAM("Level"))
112 , sLevelFormat(RTL_CONSTASCII_USTRINGPARAM("LevelFormat"))
113 , sLevelParagraphStyles(RTL_CONSTASCII_USTRINGPARAM("LevelParagraphStyles"))
114 , sLinkRegion(RTL_CONSTASCII_USTRINGPARAM("LinkRegion"))
115 , sMainEntryCharacterStyleName(RTL_CONSTASCII_USTRINGPARAM("MainEntryCharacterStyleName"))
116 , sParaStyleHeading(RTL_CONSTASCII_USTRINGPARAM("ParaStyleHeading"))
117 , sParaStyleLevel(RTL_CONSTASCII_USTRINGPARAM("ParaStyleLevel"))
118 , sTitle(RTL_CONSTASCII_USTRINGPARAM("Title"))
119 , sName(RTL_CONSTASCII_USTRINGPARAM("Name"))
120 , sUseAlphabeticalSeparators(RTL_CONSTASCII_USTRINGPARAM("UseAlphabeticalSeparators"))
121 , sUseCombinedEntries(RTL_CONSTASCII_USTRINGPARAM("UseCombinedEntries"))
122 , sUseDash(RTL_CONSTASCII_USTRINGPARAM("UseDash"))
123 , sUseKeyAsEntry(RTL_CONSTASCII_USTRINGPARAM("UseKeyAsEntry"))
124 , sUseLevelFromSource(RTL_CONSTASCII_USTRINGPARAM("UseLevelFromSource"))
125 , sUsePP(RTL_CONSTASCII_USTRINGPARAM("UsePP"))
126 , sUseUpperCase(RTL_CONSTASCII_USTRINGPARAM("UseUpperCase"))
127 , sIsCommaSeparated(RTL_CONSTASCII_USTRINGPARAM("IsCommaSeparated"))
128 , sIsAutomaticUpdate(RTL_CONSTASCII_USTRINGPARAM("IsAutomaticUpdate"))
129 , sIsRelativeTabstops(RTL_CONSTASCII_USTRINGPARAM("IsRelativeTabstops"))
130 , sCreateFromLevelParagraphStyles(RTL_CONSTASCII_USTRINGPARAM("CreateFromLevelParagraphStyles"))
131 , sDocumentIndex(RTL_CONSTASCII_USTRINGPARAM("DocumentIndex"))
132 , sContentSection(RTL_CONSTASCII_USTRINGPARAM("ContentSection"))
133 , sHeaderSection(RTL_CONSTASCII_USTRINGPARAM("HeaderSection"))
134
135 , sTextSection(RTL_CONSTASCII_USTRINGPARAM("TextSection"))
136 , sIsGlobalDocumentSection(RTL_CONSTASCII_USTRINGPARAM("IsGlobalDocumentSection"))
137 , sProtectionKey(RTL_CONSTASCII_USTRINGPARAM("ProtectionKey"))
138 , sSortAlgorithm(RTL_CONSTASCII_USTRINGPARAM("SortAlgorithm"))
139 , sLocale(RTL_CONSTASCII_USTRINGPARAM("Locale"))
140 , sUserIndexName(RTL_CONSTASCII_USTRINGPARAM("UserIndexName"))
141
142 , sIsCurrentlyVisible(RTL_CONSTASCII_USTRINGPARAM("IsCurrentlyVisible"))
143 , sHeadingStyleName(RTL_CONSTASCII_USTRINGPARAM("HeadingStyleName"))
144
145 , rExport(rExp)
146 , rParaExport(rParaExp)
147 , bHeadingDummiesExported( sal_False )
148 {
149 }
150
151
ExportSectionStart(const Reference<XTextSection> & rSection,sal_Bool bAutoStyles)152 void XMLSectionExport::ExportSectionStart(
153 const Reference<XTextSection> & rSection,
154 sal_Bool bAutoStyles)
155 {
156 Reference<XPropertySet> xPropertySet(rSection, UNO_QUERY);
157
158 // always export section (auto) style
159 if (bAutoStyles)
160 {
161 // get PropertySet and add section style
162 GetParaExport().Add( XML_STYLE_FAMILY_TEXT_SECTION, xPropertySet );
163 }
164 else
165 {
166 // always export section style
167 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_STYLE_NAME,
168 GetParaExport().Find(
169 XML_STYLE_FAMILY_TEXT_SECTION,
170 xPropertySet, sEmpty ) );
171
172 // xml:id for RDF metadata
173 GetExport().AddAttributeXmlId(rSection);
174
175 // export index or regular section
176 Reference<XDocumentIndex> xIndex;
177 if (GetIndex(rSection, xIndex))
178 {
179 if (xIndex.is())
180 {
181 // we are an index
182 ExportIndexStart(xIndex);
183 }
184 else
185 {
186 // we are an index header
187 ExportIndexHeaderStart(rSection);
188 }
189 }
190 else
191 {
192 // we are not an index
193 ExportRegularSectionStart(rSection);
194 }
195 }
196 }
197
GetIndex(const Reference<XTextSection> & rSection,Reference<XDocumentIndex> & rIndex) const198 sal_Bool XMLSectionExport::GetIndex(
199 const Reference<XTextSection> & rSection,
200 Reference<XDocumentIndex> & rIndex) const
201 {
202 // first, reset result
203 sal_Bool bRet = sal_False;
204 rIndex = NULL;
205
206 // get section Properties
207 Reference<XPropertySet> xSectionPropSet(rSection, UNO_QUERY);
208
209 // then check if this section happens to be inside an index
210 if (xSectionPropSet->getPropertySetInfo()->
211 hasPropertyByName(sDocumentIndex))
212 {
213 Any aAny = xSectionPropSet->getPropertyValue(sDocumentIndex);
214 Reference<XDocumentIndex> xDocumentIndex;
215 aAny >>= xDocumentIndex;
216
217 // OK, are we inside of an index
218 if (xDocumentIndex.is())
219 {
220 // is the enclosing index identical with "our" section?
221 Reference<XPropertySet> xIndexPropSet(xDocumentIndex, UNO_QUERY);
222 aAny = xIndexPropSet->getPropertyValue(sContentSection);
223 Reference<XTextSection> xEnclosingSection;
224 aAny >>= xEnclosingSection;
225
226 // if the enclosing section is "our" section, then we are an index!
227 if (rSection == xEnclosingSection)
228 {
229 rIndex = xDocumentIndex;
230 bRet = sal_True;
231 }
232 // else: index header or regular section
233
234 // is the enclosing index identical with the header section?
235 aAny = xIndexPropSet->getPropertyValue(sHeaderSection);
236 // now mis-named: contains header section
237 aAny >>= xEnclosingSection;
238
239 // if the enclosing section is "our" section, then we are an index!
240 if (rSection == xEnclosingSection)
241 {
242 bRet = sal_True;
243 }
244 // else: regular section
245 }
246 // else: we aren't even inside of an index
247 }
248 // else: we don't even know what an index is.
249
250 return bRet;
251 }
252
253
ExportSectionEnd(const Reference<XTextSection> & rSection,sal_Bool bAutoStyles)254 void XMLSectionExport::ExportSectionEnd(
255 const Reference<XTextSection> & rSection,
256 sal_Bool bAutoStyles)
257 {
258 // no end section for styles
259 if (!bAutoStyles)
260 {
261 enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
262
263 // export index or regular section end
264 Reference<XDocumentIndex> xIndex;
265 if (GetIndex(rSection, xIndex))
266 {
267 if (xIndex.is())
268 {
269 // index end: close index body element
270 GetExport().EndElement( XML_NAMESPACE_TEXT, XML_INDEX_BODY,
271 sal_True );
272 GetExport().IgnorableWhitespace();
273
274 switch (MapSectionType(xIndex->getServiceName()))
275 {
276 case TEXT_SECTION_TYPE_TOC:
277 eElement = XML_TABLE_OF_CONTENT;
278 break;
279
280 case TEXT_SECTION_TYPE_ILLUSTRATION:
281 eElement = XML_ILLUSTRATION_INDEX;
282 break;
283
284 case TEXT_SECTION_TYPE_ALPHABETICAL:
285 eElement = XML_ALPHABETICAL_INDEX;
286 break;
287
288 case TEXT_SECTION_TYPE_TABLE:
289 eElement = XML_TABLE_INDEX;
290 break;
291
292 case TEXT_SECTION_TYPE_OBJECT:
293 eElement = XML_OBJECT_INDEX;
294 break;
295
296 case TEXT_SECTION_TYPE_USER:
297 eElement = XML_USER_INDEX;
298 break;
299
300 case TEXT_SECTION_TYPE_BIBLIOGRAPHY:
301 eElement = XML_BIBLIOGRAPHY;
302 break;
303
304 default:
305 OSL_ENSURE(false, "unknown index type");
306 // default: skip index!
307 break;
308 }
309 }
310 else
311 {
312 eElement = XML_INDEX_TITLE;
313 }
314 }
315 else
316 {
317 eElement = XML_SECTION;
318 }
319
320 if (XML_TOKEN_INVALID != eElement)
321 {
322 // any old attributes?
323 GetExport().CheckAttrList();
324
325 // element surrounded by whitespace
326 GetExport().EndElement( XML_NAMESPACE_TEXT, eElement, sal_True);
327 GetExport().IgnorableWhitespace();
328 }
329 else
330 {
331 OSL_ENSURE(false, "Need element name!");
332 }
333 }
334 // else: autostyles -> ignore
335 }
336
ExportIndexStart(const Reference<XDocumentIndex> & rIndex)337 void XMLSectionExport::ExportIndexStart(
338 const Reference<XDocumentIndex> & rIndex)
339 {
340 // get PropertySet
341 Reference<XPropertySet> xPropertySet(rIndex, UNO_QUERY);
342
343 switch (MapSectionType(rIndex->getServiceName()))
344 {
345 case TEXT_SECTION_TYPE_TOC:
346 ExportTableOfContentStart(xPropertySet);
347 break;
348
349 case TEXT_SECTION_TYPE_ILLUSTRATION:
350 ExportIllustrationIndexStart(xPropertySet);
351 break;
352
353 case TEXT_SECTION_TYPE_ALPHABETICAL:
354 ExportAlphabeticalIndexStart(xPropertySet);
355 break;
356
357 case TEXT_SECTION_TYPE_TABLE:
358 ExportTableIndexStart(xPropertySet);
359 break;
360
361 case TEXT_SECTION_TYPE_OBJECT:
362 ExportObjectIndexStart(xPropertySet);
363 break;
364
365 case TEXT_SECTION_TYPE_USER:
366 ExportUserIndexStart(xPropertySet);
367 break;
368
369 case TEXT_SECTION_TYPE_BIBLIOGRAPHY:
370 ExportBibliographyStart(xPropertySet);
371 break;
372
373 default:
374 // skip index
375 OSL_ENSURE(false, "unknown index type");
376 break;
377 }
378 }
379
ExportIndexHeaderStart(const Reference<XTextSection> & rSection)380 void XMLSectionExport::ExportIndexHeaderStart(
381 const Reference<XTextSection> & rSection)
382 {
383 // export name, dammit!
384 Reference<XNamed> xName(rSection, UNO_QUERY);
385 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
386
387 // format already handled -> export only start element
388 GetExport().StartElement( XML_NAMESPACE_TEXT, XML_INDEX_TITLE, sal_True );
389 GetExport().IgnorableWhitespace();
390 }
391
392
393 SvXMLEnumStringMapEntry __READONLY_DATA aIndexTypeMap[] =
394 {
395 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ContentIndex", TEXT_SECTION_TYPE_TOC ),
396 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.DocumentIndex", TEXT_SECTION_TYPE_ALPHABETICAL ),
397 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.TableIndex", TEXT_SECTION_TYPE_TABLE ),
398 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ObjectIndex", TEXT_SECTION_TYPE_OBJECT ),
399 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.Bibliography", TEXT_SECTION_TYPE_BIBLIOGRAPHY ),
400 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.UserIndex", TEXT_SECTION_TYPE_USER ),
401 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.IllustrationsIndex", TEXT_SECTION_TYPE_ILLUSTRATION ),
402 ENUM_STRING_MAP_END()
403 };
404
MapSectionType(const OUString & rServiceName)405 enum SectionTypeEnum XMLSectionExport::MapSectionType(
406 const OUString& rServiceName)
407 {
408 enum SectionTypeEnum eType = TEXT_SECTION_TYPE_UNKNOWN;
409
410 sal_uInt16 nTmp;
411 if (SvXMLUnitConverter::convertEnum(nTmp, rServiceName, aIndexTypeMap))
412 {
413 eType = (enum SectionTypeEnum)nTmp;
414 }
415
416 // TODO: index header section types, etc.
417
418 return eType;
419 }
420
ExportRegularSectionStart(const Reference<XTextSection> & rSection)421 void XMLSectionExport::ExportRegularSectionStart(
422 const Reference<XTextSection> & rSection)
423 {
424 // style name already handled in ExportSectionStart(...)
425
426 Reference<XNamed> xName(rSection, UNO_QUERY);
427 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
428
429 // get XPropertySet for other values
430 Reference<XPropertySet> xPropSet(rSection, UNO_QUERY);
431 Any aAny;
432
433 // condition and display
434 aAny = xPropSet->getPropertyValue(sCondition);
435 OUString sCond;
436 aAny >>= sCond;
437 enum XMLTokenEnum eDisplay = XML_TOKEN_INVALID;
438 // strict ODF 1.2 has no form for the condition of a visible section (display="condition" means hidden)
439 const sal_Bool bStrict = SvtSaveOptions::IsODFStrict( GetExport().getDefaultVersion() );
440 const sal_Bool bIsVisible = *(sal_Bool*)xPropSet->getPropertyValue(sIsVisible).getValue();
441 if (sCond.getLength() > 0 && !( bStrict && bIsVisible ))
442 {
443 OUString sQValue =
444 GetExport().GetNamespaceMap().GetQNameByKey( XML_NAMESPACE_OOOW,
445 sCond, sal_False );
446 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_CONDITION, sQValue);
447 eDisplay = XML_CONDITION;
448
449 // #97450# store hidden-status (of conditional sections only)
450 aAny = xPropSet->getPropertyValue(sIsCurrentlyVisible);
451 if (!bStrict && ! *(sal_Bool*)aAny.getValue())
452 {
453 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_IS_HIDDEN,
454 XML_TRUE);
455 }
456 }
457 else
458 {
459 eDisplay = XML_NONE;
460 }
461 aAny = xPropSet->getPropertyValue(sIsVisible);
462 if (! *(sal_Bool*)aAny.getValue())
463 {
464 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_DISPLAY, eDisplay);
465 }
466
467 // protect + protection key
468 aAny = xPropSet->getPropertyValue(sIsProtected);
469 if (*(sal_Bool*)aAny.getValue())
470 {
471 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTED, XML_TRUE);
472 }
473 Sequence<sal_Int8> aPassword;
474 xPropSet->getPropertyValue(sProtectionKey) >>= aPassword;
475 if (aPassword.getLength() > 0)
476 {
477 OUStringBuffer aBuffer;
478 SvXMLUnitConverter::encodeBase64(aBuffer, aPassword);
479 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTION_KEY,
480 aBuffer.makeStringAndClear());
481 // ODF 1.2 19.851; without the attribute the key is read as SHA-1
482 const OUString aDigest( SvPasswordHelper::GetDigestAlgorithmIRI( aPassword ) );
483 if (aDigest.getLength() &&
484 GetExport().getDefaultVersion() >= SvtSaveOptions::ODFVER_012)
485 {
486 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
487 XML_PROTECTION_KEY_DIGEST_ALGORITHM, aDigest);
488 }
489 }
490
491 // export element
492 GetExport().IgnorableWhitespace();
493 GetExport().StartElement( XML_NAMESPACE_TEXT, XML_SECTION, sal_True );
494
495 // data source
496 // unfortunately, we have to test all relevant strings for non-zero length
497 aAny = xPropSet->getPropertyValue(sFileLink);
498 SectionFileLink aFileLink;
499 aAny >>= aFileLink;
500
501 aAny = xPropSet->getPropertyValue(sLinkRegion);
502 OUString sRegionName;
503 aAny >>= sRegionName;
504
505 if ( (aFileLink.FileURL.getLength() > 0) ||
506 (aFileLink.FilterName.getLength() > 0) ||
507 (sRegionName.getLength() > 0) )
508 {
509 if (aFileLink.FileURL.getLength() > 0)
510 {
511 GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_TYPE, XML_SIMPLE);
512 GetExport().AddAttribute(XML_NAMESPACE_XLINK, XML_HREF,
513 GetExport().GetRelativeReference( aFileLink.FileURL) );
514 }
515
516 if (aFileLink.FilterName.getLength() > 0)
517 {
518 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_FILTER_NAME,
519 aFileLink.FilterName);
520 }
521
522 if (sRegionName.getLength() > 0)
523 {
524 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_SECTION_NAME,
525 sRegionName);
526 }
527
528 SvXMLElementExport aElem(GetExport(),
529 XML_NAMESPACE_TEXT, XML_SECTION_SOURCE,
530 sal_True, sal_True);
531 }
532 else
533 {
534 // check for DDE first
535 if (xPropSet->getPropertySetInfo()->hasPropertyByName(sDdeCommandFile))
536 {
537 // data source DDE
538 // unfortunately, we have to test all relevant strings for
539 // non-zero length
540 aAny = xPropSet->getPropertyValue(sDdeCommandFile);
541 OUString sApplication;
542 aAny >>= sApplication;
543 aAny = xPropSet->getPropertyValue(sDdeCommandType);
544 OUString sTopic;
545 aAny >>= sTopic;
546 aAny = xPropSet->getPropertyValue(sDdeCommandElement);
547 OUString sItem;
548 aAny >>= sItem;
549
550 if ( (sApplication.getLength() > 0) ||
551 (sTopic.getLength() > 0) ||
552 (sItem.getLength() > 0 ) )
553 {
554 GetExport().AddAttribute(XML_NAMESPACE_OFFICE,
555 XML_DDE_APPLICATION, sApplication);
556 GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_TOPIC,
557 sTopic);
558 GetExport().AddAttribute(XML_NAMESPACE_OFFICE, XML_DDE_ITEM,
559 sItem);
560
561 aAny = xPropSet->getPropertyValue(sIsAutomaticUpdate);
562 if (*(sal_Bool*)aAny.getValue())
563 {
564 GetExport().AddAttribute(XML_NAMESPACE_OFFICE,
565 XML_AUTOMATIC_UPDATE, XML_TRUE);
566 }
567
568 SvXMLElementExport aElem(GetExport(),
569 XML_NAMESPACE_OFFICE,
570 XML_DDE_SOURCE, sal_True, sal_True);
571 }
572 // else: no DDE data source
573 }
574 // else: no DDE on this system
575 }
576 }
577
ExportTableOfContentStart(const Reference<XPropertySet> & rPropertySet)578 void XMLSectionExport::ExportTableOfContentStart(
579 const Reference<XPropertySet> & rPropertySet)
580 {
581 // export TOC element start
582 ExportBaseIndexStart(XML_TABLE_OF_CONTENT, rPropertySet);
583
584 // scope for table-of-content-source element
585 {
586
587 Any aAny;
588
589 // TOC specific index source attributes:
590
591 // outline-level: 1..10
592 sal_Int16 nLevel = sal_Int16();
593 if( rPropertySet->getPropertyValue(sLevel) >>= nLevel )
594 {
595 OUStringBuffer sBuffer;
596 SvXMLUnitConverter::convertNumber(sBuffer, (sal_Int32)nLevel);
597 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
598 XML_OUTLINE_LEVEL,
599 sBuffer.makeStringAndClear());
600 }
601
602 // use outline level
603 ExportBoolean(rPropertySet, sCreateFromOutline,
604 XML_USE_OUTLINE_LEVEL, sal_True);
605
606 // use index marks
607 ExportBoolean(rPropertySet, sCreateFromMarks,
608 XML_USE_INDEX_MARKS, sal_True);
609
610 // use level styles
611 ExportBoolean(rPropertySet, sCreateFromLevelParagraphStyles,
612 XML_USE_INDEX_SOURCE_STYLES, sal_False);
613
614 ExportBaseIndexSource(TEXT_SECTION_TYPE_TOC, rPropertySet);
615 }
616
617 ExportBaseIndexBody(TEXT_SECTION_TYPE_TOC, rPropertySet);
618 }
619
ExportObjectIndexStart(const Reference<XPropertySet> & rPropertySet)620 void XMLSectionExport::ExportObjectIndexStart(
621 const Reference<XPropertySet> & rPropertySet)
622 {
623 // export index start
624 ExportBaseIndexStart(XML_OBJECT_INDEX, rPropertySet);
625
626 // scope for index source element
627 {
628 ExportBoolean(rPropertySet, sCreateFromOtherEmbeddedObjects,
629 XML_USE_OTHER_OBJECTS, sal_False);
630 ExportBoolean(rPropertySet, sCreateFromStarCalc,
631 XML_USE_SPREADSHEET_OBJECTS, sal_False);
632 ExportBoolean(rPropertySet, sCreateFromStarChart,
633 XML_USE_CHART_OBJECTS, sal_False);
634 ExportBoolean(rPropertySet, sCreateFromStarDraw,
635 XML_USE_DRAW_OBJECTS, sal_False);
636 ExportBoolean(rPropertySet, sCreateFromStarMath,
637 XML_USE_MATH_OBJECTS, sal_False);
638
639 ExportBaseIndexSource(TEXT_SECTION_TYPE_OBJECT, rPropertySet);
640 }
641
642 ExportBaseIndexBody(TEXT_SECTION_TYPE_OBJECT, rPropertySet);
643 }
644
ExportIllustrationIndexStart(const Reference<XPropertySet> & rPropertySet)645 void XMLSectionExport::ExportIllustrationIndexStart(
646 const Reference<XPropertySet> & rPropertySet)
647 {
648 // export index start
649 ExportBaseIndexStart(XML_ILLUSTRATION_INDEX, rPropertySet);
650
651 // scope for index source element
652 {
653 // export common attributes for illustration and table indices
654 ExportTableAndIllustrationIndexSourceAttributes(rPropertySet);
655
656 ExportBaseIndexSource(TEXT_SECTION_TYPE_ILLUSTRATION, rPropertySet);
657 }
658
659 ExportBaseIndexBody(TEXT_SECTION_TYPE_ILLUSTRATION, rPropertySet);
660 }
661
ExportTableIndexStart(const Reference<XPropertySet> & rPropertySet)662 void XMLSectionExport::ExportTableIndexStart(
663 const Reference<XPropertySet> & rPropertySet)
664 {
665 // export index start
666 ExportBaseIndexStart(XML_TABLE_INDEX, rPropertySet);
667
668 // scope for index source element
669 {
670 // export common attributes for illustration and table indices
671 ExportTableAndIllustrationIndexSourceAttributes(rPropertySet);
672
673 ExportBaseIndexSource(TEXT_SECTION_TYPE_TABLE, rPropertySet);
674 }
675
676 ExportBaseIndexBody(TEXT_SECTION_TYPE_TABLE, rPropertySet);
677 }
678
ExportAlphabeticalIndexStart(const Reference<XPropertySet> & rPropertySet)679 void XMLSectionExport::ExportAlphabeticalIndexStart(
680 const Reference<XPropertySet> & rPropertySet)
681 {
682 // export TOC element start
683 ExportBaseIndexStart(XML_ALPHABETICAL_INDEX, rPropertySet);
684
685 // scope for table-of-content-source element
686 {
687
688 // style name (if present)
689 Any aAny;
690 aAny = rPropertySet->getPropertyValue(sMainEntryCharacterStyleName);
691 OUString sStyleName;
692 aAny >>= sStyleName;
693 if (sStyleName.getLength())
694 {
695 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
696 XML_MAIN_ENTRY_STYLE_NAME,
697 GetExport().EncodeStyleName( sStyleName ));
698 }
699
700 // other (boolean) attributes
701 ExportBoolean(rPropertySet, sIsCaseSensitive, XML_IGNORE_CASE,
702 sal_False, sal_True);
703 ExportBoolean(rPropertySet, sUseAlphabeticalSeparators,
704 XML_ALPHABETICAL_SEPARATORS, sal_False);
705 ExportBoolean(rPropertySet, sUseCombinedEntries, XML_COMBINE_ENTRIES,
706 sal_True);
707 ExportBoolean(rPropertySet, sUseDash, XML_COMBINE_ENTRIES_WITH_DASH,
708 sal_False);
709 ExportBoolean(rPropertySet, sUseKeyAsEntry, XML_USE_KEYS_AS_ENTRIES,
710 sal_False);
711 ExportBoolean(rPropertySet, sUsePP, XML_COMBINE_ENTRIES_WITH_PP,
712 sal_True);
713 ExportBoolean(rPropertySet, sUseUpperCase, XML_CAPITALIZE_ENTRIES,
714 sal_False);
715 ExportBoolean(rPropertySet, sIsCommaSeparated, XML_COMMA_SEPARATED,
716 sal_False);
717
718 // sort algorithm
719 aAny = rPropertySet->getPropertyValue(sSortAlgorithm);
720 OUString sAlgorithm;
721 aAny >>= sAlgorithm;
722 if (sAlgorithm.getLength() > 0)
723 {
724 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_SORT_ALGORITHM,
725 sAlgorithm );
726 }
727
728 // locale
729 aAny = rPropertySet->getPropertyValue(sLocale);
730 Locale aLocale;
731 aAny >>= aLocale;
732 GetExport().AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
733 aLocale.Language);
734 GetExport().AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
735 aLocale.Country);
736
737 ExportBaseIndexSource(TEXT_SECTION_TYPE_ALPHABETICAL, rPropertySet);
738 }
739
740 ExportBaseIndexBody(TEXT_SECTION_TYPE_ALPHABETICAL, rPropertySet);
741 }
742
ExportUserIndexStart(const Reference<XPropertySet> & rPropertySet)743 void XMLSectionExport::ExportUserIndexStart(
744 const Reference<XPropertySet> & rPropertySet)
745 {
746 // export TOC element start
747 ExportBaseIndexStart(XML_USER_INDEX, rPropertySet);
748
749 // scope for table-of-content-source element
750 {
751 // bool attributes
752 ExportBoolean(rPropertySet, sCreateFromEmbeddedObjects,
753 XML_USE_OBJECTS, sal_False);
754 ExportBoolean(rPropertySet, sCreateFromGraphicObjects,
755 XML_USE_GRAPHICS, sal_False);
756 ExportBoolean(rPropertySet, sCreateFromMarks,
757 XML_USE_INDEX_MARKS, sal_False);
758 ExportBoolean(rPropertySet, sCreateFromTables,
759 XML_USE_TABLES, sal_False);
760 ExportBoolean(rPropertySet, sCreateFromTextFrames,
761 XML_USE_FLOATING_FRAMES, sal_False);
762 ExportBoolean(rPropertySet, sUseLevelFromSource,
763 XML_COPY_OUTLINE_LEVELS, sal_False);
764 ExportBoolean(rPropertySet, sCreateFromLevelParagraphStyles,
765 XML_USE_INDEX_SOURCE_STYLES, sal_False);
766
767 Any aAny = rPropertySet->getPropertyValue( sUserIndexName );
768 OUString sIndexName;
769 aAny >>= sIndexName;
770 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_INDEX_NAME,
771 sIndexName);
772
773 ExportBaseIndexSource(TEXT_SECTION_TYPE_USER, rPropertySet);
774 }
775
776 ExportBaseIndexBody(TEXT_SECTION_TYPE_USER, rPropertySet);
777 }
778
ExportBibliographyStart(const Reference<XPropertySet> & rPropertySet)779 void XMLSectionExport::ExportBibliographyStart(
780 const Reference<XPropertySet> & rPropertySet)
781 {
782 // export TOC element start
783 ExportBaseIndexStart(XML_BIBLIOGRAPHY, rPropertySet);
784
785 // scope for table-of-content-source element
786 {
787 // No attributes. Fine.
788
789 ExportBaseIndexSource(TEXT_SECTION_TYPE_BIBLIOGRAPHY, rPropertySet);
790 }
791
792 ExportBaseIndexBody(TEXT_SECTION_TYPE_BIBLIOGRAPHY, rPropertySet);
793 }
794
795
ExportBaseIndexStart(XMLTokenEnum eElement,const Reference<XPropertySet> & rPropertySet)796 void XMLSectionExport::ExportBaseIndexStart(
797 XMLTokenEnum eElement,
798 const Reference<XPropertySet> & rPropertySet)
799 {
800 // protect + protection key
801 Any aAny = rPropertySet->getPropertyValue(sIsProtected);
802 if (*(sal_Bool*)aAny.getValue())
803 {
804 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_PROTECTED, XML_TRUE);
805 }
806
807 // index name
808 OUString sIndexName;
809 rPropertySet->getPropertyValue(sName) >>= sIndexName;
810 if ( sIndexName.getLength() > 0 )
811 {
812 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, sIndexName);
813 }
814
815 // index Element start
816 GetExport().IgnorableWhitespace();
817 GetExport().StartElement( XML_NAMESPACE_TEXT, eElement, sal_False );
818 }
819
820 static const XMLTokenEnum aTypeSourceElementNameMap[] =
821 {
822 XML_TABLE_OF_CONTENT_SOURCE, // TOC
823 XML_TABLE_INDEX_SOURCE, // table index
824 XML_ILLUSTRATION_INDEX_SOURCE, // illustration index
825 XML_OBJECT_INDEX_SOURCE, // object index
826 XML_USER_INDEX_SOURCE, // user index
827 XML_ALPHABETICAL_INDEX_SOURCE, // alphabetical index
828 XML_BIBLIOGRAPHY_SOURCE // bibliography
829 };
830
ExportBaseIndexSource(SectionTypeEnum eType,const Reference<XPropertySet> & rPropertySet)831 void XMLSectionExport::ExportBaseIndexSource(
832 SectionTypeEnum eType,
833 const Reference<XPropertySet> & rPropertySet)
834 {
835 // check type
836 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
837 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
838
839 Any aAny;
840
841 // common attributes; not supported by bibliography
842 if (eType != TEXT_SECTION_TYPE_BIBLIOGRAPHY)
843 {
844 // document or chapter index?
845 aAny = rPropertySet->getPropertyValue(sCreateFromChapter);
846 if (*(sal_Bool*)aAny.getValue())
847 {
848 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
849 XML_INDEX_SCOPE, XML_CHAPTER);
850 }
851
852 // tab-stops relative to margin?
853 aAny = rPropertySet->getPropertyValue(sIsRelativeTabstops);
854 if (! *(sal_Bool*)aAny.getValue())
855 {
856 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
857 XML_RELATIVE_TAB_STOP_POSITION,
858 XML_FALSE);
859 }
860 }
861
862 // the index source element (all indices)
863 SvXMLElementExport aElem(GetExport(),
864 XML_NAMESPACE_TEXT,
865 GetXMLToken(
866 aTypeSourceElementNameMap[
867 eType - TEXT_SECTION_TYPE_TOC]),
868 sal_True, sal_True);
869
870 // scope for title template (all indices)
871 {
872 // header style name
873 aAny = rPropertySet->getPropertyValue(sParaStyleHeading);
874 OUString sStyleName;
875 aAny >>= sStyleName;
876 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
877 XML_STYLE_NAME,
878 GetExport().EncodeStyleName( sStyleName ));
879
880 // title template
881 SvXMLElementExport aHeaderTemplate(GetExport(),
882 XML_NAMESPACE_TEXT,
883 XML_INDEX_TITLE_TEMPLATE,
884 sal_True, sal_False);
885
886 // title as element content
887 aAny = rPropertySet->getPropertyValue(sTitle);
888 OUString sTitleString;
889 aAny >>= sTitleString;
890 GetExport().Characters(sTitleString);
891 }
892
893 // export level templates (all indices)
894 aAny = rPropertySet->getPropertyValue(sLevelFormat);
895 Reference<XIndexReplace> xLevelTemplates;
896 aAny >>= xLevelTemplates;
897
898 // iterate over level formats;
899 // skip element 0 (empty template for title)
900 sal_Int32 nLevelCount = xLevelTemplates->getCount();
901 for(sal_Int32 i = 1; i<nLevelCount; i++)
902 {
903 // get sequence
904 Sequence<PropertyValues> aTemplateSequence;
905 aAny = xLevelTemplates->getByIndex(i);
906 aAny >>= aTemplateSequence;
907
908 // export the sequence (abort export if an error occurred; #91214#)
909 sal_Bool bResult =
910 ExportIndexTemplate(eType, i, rPropertySet, aTemplateSequence);
911 if ( !bResult )
912 break;
913 }
914
915 // only TOC and user index:
916 // styles from which to build the index (LevelParagraphStyles)
917 if ( (TEXT_SECTION_TYPE_TOC == eType) ||
918 (TEXT_SECTION_TYPE_USER == eType) )
919 {
920 aAny = rPropertySet->getPropertyValue(sLevelParagraphStyles);
921 Reference<XIndexReplace> xLevelParagraphStyles;
922 aAny >>= xLevelParagraphStyles;
923 ExportLevelParagraphStyles(xLevelParagraphStyles);
924 }
925 }
926
927
ExportBaseIndexBody(SectionTypeEnum eType,const Reference<XPropertySet> &)928 void XMLSectionExport::ExportBaseIndexBody(
929 SectionTypeEnum
930 #if OSL_DEBUG_LEVEL > 0
931 eType
932 #endif
933 ,
934 const Reference<XPropertySet> &)
935 {
936 // type not used; checked anyway.
937 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
938 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
939
940 // export start only
941
942 // any old attributes?
943 GetExport().CheckAttrList();
944
945 // start surrounded by whitespace
946 GetExport().IgnorableWhitespace();
947 GetExport().StartElement( XML_NAMESPACE_TEXT, XML_INDEX_BODY, sal_True );
948 }
949
ExportTableAndIllustrationIndexSourceAttributes(const Reference<XPropertySet> & rPropertySet)950 void XMLSectionExport::ExportTableAndIllustrationIndexSourceAttributes(
951 const Reference<XPropertySet> & rPropertySet)
952 {
953 // use caption
954 Any aAny = rPropertySet->getPropertyValue(sCreateFromLabels);
955 if (! *(sal_Bool*)aAny.getValue())
956 {
957 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
958 XML_USE_CAPTION, XML_FALSE);
959 }
960
961 // sequence name
962 aAny = rPropertySet->getPropertyValue(sLabelCategory);
963 OUString sSequenceName;
964 aAny >>= sSequenceName;
965 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
966 XML_CAPTION_SEQUENCE_NAME,
967 sSequenceName);
968
969 // caption format
970 aAny = rPropertySet->getPropertyValue(sLabelDisplayType);
971 sal_Int16 nType = 0;
972 aAny >>= nType;
973 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
974 XML_CAPTION_SEQUENCE_FORMAT,
975 XMLTextFieldExport::MapReferenceType(nType));
976 }
977
978
979 // map index of LevelFormats to attribute value;
980 // level 0 is always the header
981 static const XMLTokenEnum aLevelNameTOCMap[] =
982 { XML_TOKEN_INVALID, XML_1, XML_2, XML_3, XML_4, XML_5, XML_6, XML_7,
983 XML_8, XML_9, XML_10, XML_TOKEN_INVALID };
984 static const XMLTokenEnum aLevelNameTableMap[] =
985 { XML_TOKEN_INVALID, XML__EMPTY, XML_TOKEN_INVALID };
986 static const XMLTokenEnum aLevelNameAlphaMap[] =
987 { XML_TOKEN_INVALID, XML_SEPARATOR, XML_1, XML_2, XML_3, XML_TOKEN_INVALID };
988 static const XMLTokenEnum aLevelNameBibliographyMap[] =
989 { XML_TOKEN_INVALID, XML_ARTICLE, XML_BOOK, XML_BOOKLET, XML_CONFERENCE,
990 XML_CUSTOM1, XML_CUSTOM2, XML_CUSTOM3, XML_CUSTOM4,
991 XML_CUSTOM5, XML_EMAIL, XML_INBOOK, XML_INCOLLECTION,
992 XML_INPROCEEDINGS, XML_JOURNAL,
993 XML_MANUAL, XML_MASTERSTHESIS, XML_MISC, XML_PHDTHESIS,
994 XML_PROCEEDINGS, XML_TECHREPORT, XML_UNPUBLISHED, XML_WWW,
995 XML_TOKEN_INVALID };
996
997 static const XMLTokenEnum* aTypeLevelNameMap[] =
998 {
999 aLevelNameTOCMap, // TOC
1000 aLevelNameTableMap, // table index
1001 aLevelNameTableMap, // illustration index
1002 aLevelNameTableMap, // object index
1003 aLevelNameTOCMap, // user index
1004 aLevelNameAlphaMap, // alphabetical index
1005 aLevelNameBibliographyMap // bibliography
1006 };
1007
1008 static const sal_Char* aLevelStylePropNameTOCMap[] =
1009 { NULL, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
1010 "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
1011 "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
1012 "ParaStyleLevel10", NULL };
1013 static const sal_Char* aLevelStylePropNameTableMap[] =
1014 { NULL, "ParaStyleLevel1", NULL };
1015 static const sal_Char* aLevelStylePropNameAlphaMap[] =
1016 { NULL, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
1017 "ParaStyleLevel3", NULL };
1018 static const sal_Char* aLevelStylePropNameBibliographyMap[] =
1019 // TODO: replace with real property names, when available
1020 { NULL, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1021 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1022 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1023 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1024 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1025 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1026 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
1027 "ParaStyleLevel1",
1028 NULL };
1029
1030 static const sal_Char** aTypeLevelStylePropNameMap[] =
1031 {
1032 aLevelStylePropNameTOCMap, // TOC
1033 aLevelStylePropNameTableMap, // table index
1034 aLevelStylePropNameTableMap, // illustration index
1035 aLevelStylePropNameTableMap, // object index
1036 aLevelStylePropNameTOCMap, // user index
1037 aLevelStylePropNameAlphaMap, // alphabetical index
1038 aLevelStylePropNameBibliographyMap // bibliography
1039 };
1040
1041 static const XMLTokenEnum aTypeLevelAttrMap[] =
1042 {
1043 XML_OUTLINE_LEVEL, // TOC
1044 XML_TOKEN_INVALID, // table index
1045 XML_TOKEN_INVALID, // illustration index
1046 XML_TOKEN_INVALID, // object index
1047 XML_OUTLINE_LEVEL, // user index
1048 XML_OUTLINE_LEVEL, // alphabetical index
1049 XML_BIBLIOGRAPHY_TYPE // bibliography
1050 };
1051
1052 static const XMLTokenEnum aTypeElementNameMap[] =
1053 {
1054 XML_TABLE_OF_CONTENT_ENTRY_TEMPLATE, // TOC
1055 XML_TABLE_INDEX_ENTRY_TEMPLATE, // table index
1056 XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE, // illustration index
1057 XML_OBJECT_INDEX_ENTRY_TEMPLATE, // object index
1058 XML_USER_INDEX_ENTRY_TEMPLATE, // user index
1059 XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE, // alphabetical index
1060 XML_BIBLIOGRAPHY_ENTRY_TEMPLATE // bibliography
1061 };
1062
1063
ExportIndexTemplate(SectionTypeEnum eType,sal_Int32 nOutlineLevel,const Reference<XPropertySet> & rPropertySet,Sequence<Sequence<PropertyValue>> & rValues)1064 sal_Bool XMLSectionExport::ExportIndexTemplate(
1065 SectionTypeEnum eType,
1066 sal_Int32 nOutlineLevel,
1067 const Reference<XPropertySet> & rPropertySet,
1068 Sequence<Sequence<PropertyValue> > & rValues)
1069 {
1070 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
1071 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
1072 OSL_ENSURE(nOutlineLevel >= 0, "illegal outline level");
1073
1074 if ( (eType >= TEXT_SECTION_TYPE_TOC) &&
1075 (eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY) &&
1076 (nOutlineLevel >= 0) )
1077 {
1078 // get level name and level attribute name from aLevelNameMap;
1079 const XMLTokenEnum eLevelAttrName(
1080 aTypeLevelAttrMap[eType-TEXT_SECTION_TYPE_TOC]);
1081 const XMLTokenEnum eLevelName(
1082 aTypeLevelNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
1083
1084 // #92124#: some old documents may be broken, then they have
1085 // too many template levels; we need to recognize this and
1086 // export only as many as is legal for the respective index
1087 // type. To do this, we simply return an error flag, which
1088 // will then abort further template level exports.
1089 OSL_ENSURE(XML_TOKEN_INVALID != eLevelName, "can't find level name");
1090 if ( XML_TOKEN_INVALID == eLevelName )
1091 {
1092 // output level not found? Then end of templates! #91214#
1093 return sal_False;
1094 }
1095
1096 // output level name
1097 if ((XML_TOKEN_INVALID != eLevelName) && (XML_TOKEN_INVALID != eLevelAttrName))
1098 {
1099 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1100 GetXMLToken(eLevelAttrName),
1101 GetXMLToken(eLevelName));
1102 }
1103
1104 // paragraph level style name
1105 const sal_Char* pPropName(
1106 aTypeLevelStylePropNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
1107 OSL_ENSURE(NULL != pPropName, "can't find property name");
1108 if (NULL != pPropName)
1109 {
1110 Any aAny = rPropertySet->getPropertyValue(
1111 OUString::createFromAscii(pPropName));
1112 OUString sParaStyleName;
1113 aAny >>= sParaStyleName;
1114 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1115 XML_STYLE_NAME,
1116 GetExport().EncodeStyleName( sParaStyleName ));
1117 }
1118
1119 // template element
1120 const XMLTokenEnum eElementName(
1121 aTypeElementNameMap[eType - TEXT_SECTION_TYPE_TOC]);
1122 SvXMLElementExport aLevelTemplate(GetExport(),
1123 XML_NAMESPACE_TEXT,
1124 GetXMLToken(eElementName),
1125 sal_True, sal_True);
1126
1127 // export sequence
1128 sal_Int32 nTemplateCount = rValues.getLength();
1129 for(sal_Int32 nTemplateNo = 0;
1130 nTemplateNo < nTemplateCount;
1131 nTemplateNo++)
1132 {
1133 ExportIndexTemplateElement(
1134 eType, //i90246
1135 rValues[nTemplateNo]);
1136 }
1137 }
1138
1139 return sal_True;
1140 }
1141
1142
1143 enum TemplateTypeEnum
1144 {
1145 TOK_TTYPE_ENTRY_NUMBER,
1146 TOK_TTYPE_ENTRY_TEXT,
1147 TOK_TTYPE_TAB_STOP,
1148 TOK_TTYPE_TEXT,
1149 TOK_TTYPE_PAGE_NUMBER,
1150 TOK_TTYPE_CHAPTER_INFO,
1151 TOK_TTYPE_HYPERLINK_START,
1152 TOK_TTYPE_HYPERLINK_END,
1153 TOK_TTYPE_BIBLIOGRAPHY,
1154 TOK_TTYPE_INVALID
1155 };
1156
1157 enum TemplateParamEnum
1158 {
1159 TOK_TPARAM_TOKEN_TYPE,
1160 TOK_TPARAM_CHAR_STYLE,
1161 TOK_TPARAM_TAB_RIGHT_ALIGNED,
1162 TOK_TPARAM_TAB_POSITION,
1163 TOK_TPARAM_TAB_WITH_TAB, // #i21237#
1164 TOK_TPARAM_TAB_FILL_CHAR,
1165 TOK_TPARAM_TEXT,
1166 TOK_TPARAM_CHAPTER_FORMAT,
1167 TOK_TPARAM_CHAPTER_LEVEL,//i53420
1168 TOK_TPARAM_BIBLIOGRAPHY_DATA
1169 };
1170
1171 SvXMLEnumStringMapEntry __READONLY_DATA aTemplateTypeMap[] =
1172 {
1173 ENUM_STRING_MAP_ENTRY( "TokenEntryNumber", TOK_TTYPE_ENTRY_NUMBER ),
1174 ENUM_STRING_MAP_ENTRY( "TokenEntryText", TOK_TTYPE_ENTRY_TEXT ),
1175 ENUM_STRING_MAP_ENTRY( "TokenTabStop", TOK_TTYPE_TAB_STOP ),
1176 ENUM_STRING_MAP_ENTRY( "TokenText", TOK_TTYPE_TEXT ),
1177 ENUM_STRING_MAP_ENTRY( "TokenPageNumber", TOK_TTYPE_PAGE_NUMBER ),
1178 ENUM_STRING_MAP_ENTRY( "TokenChapterInfo", TOK_TTYPE_CHAPTER_INFO ),
1179 ENUM_STRING_MAP_ENTRY( "TokenHyperlinkStart", TOK_TTYPE_HYPERLINK_START ),
1180 ENUM_STRING_MAP_ENTRY( "TokenHyperlinkEnd", TOK_TTYPE_HYPERLINK_END ),
1181 ENUM_STRING_MAP_ENTRY( "TokenBibliographyDataField", TOK_TTYPE_BIBLIOGRAPHY ),
1182 ENUM_STRING_MAP_END()
1183 };
1184
1185 SvXMLEnumStringMapEntry __READONLY_DATA aTemplateParamMap[] =
1186 {
1187 ENUM_STRING_MAP_ENTRY( "TokenType", TOK_TPARAM_TOKEN_TYPE ),
1188 ENUM_STRING_MAP_ENTRY( "CharacterStyleName", TOK_TPARAM_CHAR_STYLE ),
1189 ENUM_STRING_MAP_ENTRY( "TabStopRightAligned", TOK_TPARAM_TAB_RIGHT_ALIGNED ),
1190 ENUM_STRING_MAP_ENTRY( "TabStopPosition", TOK_TPARAM_TAB_POSITION ),
1191 ENUM_STRING_MAP_ENTRY( "TabStopFillCharacter", TOK_TPARAM_TAB_FILL_CHAR ),
1192 // #i21237#
1193 ENUM_STRING_MAP_ENTRY( "WithTab", TOK_TPARAM_TAB_WITH_TAB ),
1194 ENUM_STRING_MAP_ENTRY( "Text", TOK_TPARAM_TEXT ),
1195 ENUM_STRING_MAP_ENTRY( "ChapterFormat", TOK_TPARAM_CHAPTER_FORMAT ),
1196 ENUM_STRING_MAP_ENTRY( "ChapterLevel", TOK_TPARAM_CHAPTER_LEVEL ),//i53420
1197 ENUM_STRING_MAP_ENTRY( "BibliographyDataField", TOK_TPARAM_BIBLIOGRAPHY_DATA ),
1198 ENUM_STRING_MAP_END()
1199 };
1200
1201 SvXMLEnumMapEntry __READONLY_DATA aBibliographyDataFieldMap[] =
1202 {
1203 { XML_ADDRESS, BibliographyDataField::ADDRESS },
1204 { XML_ANNOTE, BibliographyDataField::ANNOTE },
1205 { XML_AUTHOR, BibliographyDataField::AUTHOR },
1206 { XML_BIBLIOGRAPHY_TYPE, BibliographyDataField::BIBILIOGRAPHIC_TYPE },
1207 { XML_BOOKTITLE, BibliographyDataField::BOOKTITLE },
1208 { XML_CHAPTER, BibliographyDataField::CHAPTER },
1209 { XML_CUSTOM1, BibliographyDataField::CUSTOM1 },
1210 { XML_CUSTOM2, BibliographyDataField::CUSTOM2 },
1211 { XML_CUSTOM3, BibliographyDataField::CUSTOM3 },
1212 { XML_CUSTOM4, BibliographyDataField::CUSTOM4 },
1213 { XML_CUSTOM5, BibliographyDataField::CUSTOM5 },
1214 { XML_EDITION, BibliographyDataField::EDITION },
1215 { XML_EDITOR, BibliographyDataField::EDITOR },
1216 { XML_HOWPUBLISHED, BibliographyDataField::HOWPUBLISHED },
1217 { XML_IDENTIFIER, BibliographyDataField::IDENTIFIER },
1218 { XML_INSTITUTION, BibliographyDataField::INSTITUTION },
1219 { XML_ISBN, BibliographyDataField::ISBN },
1220 { XML_JOURNAL, BibliographyDataField::JOURNAL },
1221 { XML_MONTH, BibliographyDataField::MONTH },
1222 { XML_NOTE, BibliographyDataField::NOTE },
1223 { XML_NUMBER, BibliographyDataField::NUMBER },
1224 { XML_ORGANIZATIONS, BibliographyDataField::ORGANIZATIONS },
1225 { XML_PAGES, BibliographyDataField::PAGES },
1226 { XML_PUBLISHER, BibliographyDataField::PUBLISHER },
1227 { XML_REPORT_TYPE, BibliographyDataField::REPORT_TYPE },
1228 { XML_SCHOOL, BibliographyDataField::SCHOOL },
1229 { XML_SERIES, BibliographyDataField::SERIES },
1230 { XML_TITLE, BibliographyDataField::TITLE },
1231 { XML_URL, BibliographyDataField::URL },
1232 { XML_VOLUME, BibliographyDataField::VOLUME },
1233 { XML_YEAR, BibliographyDataField::YEAR },
1234 { XML_TOKEN_INVALID, 0 }
1235 };
1236
ExportIndexTemplateElement(SectionTypeEnum eType,Sequence<PropertyValue> & rValues)1237 void XMLSectionExport::ExportIndexTemplateElement(
1238 SectionTypeEnum eType, //i90246
1239 Sequence<PropertyValue> & rValues)
1240 {
1241 // variables for template values
1242
1243 // char style
1244 OUString sCharStyle;
1245 sal_Bool bCharStyleOK = sal_False;
1246
1247 // text
1248 OUString sText;
1249 sal_Bool bTextOK = sal_False;
1250
1251 // tab position
1252 sal_Bool bRightAligned = sal_False;
1253 sal_Bool bRightAlignedOK = sal_False;
1254
1255 // tab position
1256 sal_Int32 nTabPosition = 0;
1257 sal_Bool bTabPositionOK = sal_False;
1258
1259 // fill character
1260 OUString sFillChar;
1261 sal_Bool bFillCharOK = sal_False;
1262
1263 // chapter format
1264 sal_Int16 nChapterFormat = 0;
1265 sal_Bool bChapterFormatOK = sal_False;
1266
1267 // outline max level
1268 sal_Int16 nLevel = 0;
1269 sal_Bool bLevelOK = sal_False;
1270
1271 // Bibliography Data
1272 sal_Int16 nBibliographyData = 0;
1273 sal_Bool bBibliographyDataOK = sal_False;
1274
1275 // With Tab Stop #i21237#
1276 sal_Bool bWithTabStop = sal_False;
1277 sal_Bool bWithTabStopOK = sal_False;
1278
1279 //i90246, the ODF version being written to is:
1280 const SvtSaveOptions::ODFDefaultVersion aODFVersion = rExport.getDefaultVersion();
1281 //the above version cannot be used for old OOo (OOo 1.0) formats!
1282
1283 // token type
1284 enum TemplateTypeEnum nTokenType = TOK_TTYPE_INVALID;
1285
1286 sal_Int32 nCount = rValues.getLength();
1287 for(sal_Int32 i = 0; i<nCount; i++)
1288 {
1289 sal_uInt16 nToken;
1290 if ( SvXMLUnitConverter::convertEnum( nToken, rValues[i].Name,
1291 aTemplateParamMap ) )
1292 {
1293 // Only use direct and default values.
1294 // Wrong. no property states, so ignore.
1295 // if ( (beans::PropertyState_DIRECT_VALUE == rValues[i].State) ||
1296 // (beans::PropertyState_DEFAULT_VALUE == rValues[i].State) )
1297
1298 switch (nToken)
1299 {
1300 case TOK_TPARAM_TOKEN_TYPE:
1301 {
1302 sal_uInt16 nTmp;
1303 OUString sVal;
1304 rValues[i].Value >>= sVal;
1305 if (SvXMLUnitConverter::convertEnum( nTmp, sVal,
1306 aTemplateTypeMap))
1307 {
1308 nTokenType = (enum TemplateTypeEnum)nTmp;
1309 }
1310 break;
1311 }
1312
1313 case TOK_TPARAM_CHAR_STYLE:
1314 // only valid, if not empty
1315 rValues[i].Value >>= sCharStyle;
1316 bCharStyleOK = sCharStyle.getLength() > 0;
1317 break;
1318
1319 case TOK_TPARAM_TEXT:
1320 rValues[i].Value >>= sText;
1321 bTextOK = sal_True;
1322 break;
1323
1324 case TOK_TPARAM_TAB_RIGHT_ALIGNED:
1325 bRightAligned =
1326 *(sal_Bool *)rValues[i].Value.getValue();
1327 bRightAlignedOK = sal_True;
1328 break;
1329
1330 case TOK_TPARAM_TAB_POSITION:
1331 rValues[i].Value >>= nTabPosition;
1332 bTabPositionOK = sal_True;
1333 break;
1334
1335 // #i21237#
1336 case TOK_TPARAM_TAB_WITH_TAB:
1337 bWithTabStop = *(sal_Bool *)rValues[i].Value.getValue();
1338 bWithTabStopOK = sal_True;
1339 break;
1340
1341 case TOK_TPARAM_TAB_FILL_CHAR:
1342 rValues[i].Value >>= sFillChar;
1343 bFillCharOK = sal_True;
1344 break;
1345
1346 case TOK_TPARAM_CHAPTER_FORMAT:
1347 rValues[i].Value >>= nChapterFormat;
1348 bChapterFormatOK = sal_True;
1349 break;
1350 //---> i53420
1351 case TOK_TPARAM_CHAPTER_LEVEL:
1352 rValues[i].Value >>= nLevel;
1353 bLevelOK = sal_True;
1354 break;
1355 //<---
1356 case TOK_TPARAM_BIBLIOGRAPHY_DATA:
1357 rValues[i].Value >>= nBibliographyData;
1358 bBibliographyDataOK = sal_True;
1359 break;
1360 }
1361 }
1362 }
1363
1364 // convert type to token (and check validity) ...
1365 XMLTokenEnum eElement(XML_TOKEN_INVALID);
1366 switch(nTokenType)
1367 {
1368 case TOK_TTYPE_ENTRY_TEXT:
1369 eElement = XML_INDEX_ENTRY_TEXT;
1370 break;
1371 case TOK_TTYPE_TAB_STOP:
1372 // test validity
1373 if ( bRightAligned || bTabPositionOK || bFillCharOK )
1374 {
1375 eElement = XML_INDEX_ENTRY_TAB_STOP;
1376 }
1377 break;
1378 case TOK_TTYPE_TEXT:
1379 // test validity
1380 if (bTextOK)
1381 {
1382 eElement = XML_INDEX_ENTRY_SPAN;
1383 }
1384 break;
1385 case TOK_TTYPE_PAGE_NUMBER:
1386 eElement = XML_INDEX_ENTRY_PAGE_NUMBER;
1387 break;
1388 case TOK_TTYPE_CHAPTER_INFO: // keyword index
1389 eElement = XML_INDEX_ENTRY_CHAPTER;
1390 break;
1391 case TOK_TTYPE_ENTRY_NUMBER: // table of content
1392 eElement = XML_INDEX_ENTRY_CHAPTER;
1393 break;
1394 case TOK_TTYPE_HYPERLINK_START:
1395 // strict ODF 1.2 allows the link tokens in table-of-content templates only, ODF 1.3 also in the table, illustration, object and user index templates
1396 if ( !SvtSaveOptions::IsODFStrict( aODFVersion ) || TEXT_SECTION_TYPE_TOC == eType
1397 || ( aODFVersion >= SvtSaveOptions::ODFVER_013 && ( TEXT_SECTION_TYPE_TABLE == eType
1398 || TEXT_SECTION_TYPE_ILLUSTRATION == eType || TEXT_SECTION_TYPE_OBJECT == eType || TEXT_SECTION_TYPE_USER == eType ) ) )
1399 eElement = XML_INDEX_ENTRY_LINK_START;
1400 break;
1401 case TOK_TTYPE_HYPERLINK_END:
1402 if ( !SvtSaveOptions::IsODFStrict( aODFVersion ) || TEXT_SECTION_TYPE_TOC == eType
1403 || ( aODFVersion >= SvtSaveOptions::ODFVER_013 && ( TEXT_SECTION_TYPE_TABLE == eType
1404 || TEXT_SECTION_TYPE_ILLUSTRATION == eType || TEXT_SECTION_TYPE_OBJECT == eType || TEXT_SECTION_TYPE_USER == eType ) ) )
1405 eElement = XML_INDEX_ENTRY_LINK_END;
1406 break;
1407 case TOK_TTYPE_BIBLIOGRAPHY:
1408 if (bBibliographyDataOK)
1409 {
1410 eElement = XML_INDEX_ENTRY_BIBLIOGRAPHY;
1411 }
1412 break;
1413 default:
1414 ; // unknown/unimplemented template
1415 break;
1416 }
1417
1418 //--->i90246
1419 //check the ODF version being exported
1420 if( aODFVersion == SvtSaveOptions::ODFVER_011
1421 || aODFVersion == SvtSaveOptions::ODFVER_010)
1422 {
1423 bLevelOK = sal_False;
1424 if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1425 {
1426 //if we are emitting for ODF 1.1 or 1.0, this information can be used for alphabetical index only
1427 //it's not permitted in other indexes
1428 if (eType != TEXT_SECTION_TYPE_ALPHABETICAL)
1429 {
1430 eElement = XML_TOKEN_INVALID; //not permitted, invalidate the element
1431 }
1432 else //maps format for 1.1 & 1.0
1433 {
1434 // a few word here: OOo up to 2.4 uses the field chapter info in Alphabetical index
1435 // in a way different from the ODF 1.1/1.0 specification:
1436 //
1437 // ODF1.1/1.0 OOo display in chapter info ODF1.2
1438 // (used in alphabetical index only
1439 //
1440 // number chapter number without pre/postfix plain-number
1441 // number-and-name chapter number without pre/postfix plus title plain-number-and-name
1442 //
1443 // with issue i89791 the reading of ODF 1.1 and 1.0 was corrected
1444 // this one corrects the writing back from ODF 1.2 to ODF 1.1/1.0
1445 // unfortunately if there is another application which interprets correctly ODF1.1/1.0,
1446 // the resulting alphabetical index will be rendered wrong by OOo 2.4 version
1447 //
1448 switch( nChapterFormat )
1449 {
1450 case ChapterFormat::DIGIT:
1451 nChapterFormat = ChapterFormat::NUMBER;
1452 break;
1453 case ChapterFormat::NO_PREFIX_SUFFIX:
1454 nChapterFormat = ChapterFormat::NAME_NUMBER;
1455 break;
1456 }
1457 }
1458 }
1459 else if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1460 {
1461 //in case of ODF 1.1 or 1.0 the only allowed number format is "number"
1462 //so, force it...
1463 // The only expected 'foreign' nChapterFormat is
1464 // ' ChapterFormat::DIGIT', forced to 'none, since the
1465 // 'value allowed in ODF 1.1 and 1.0 is 'number' the default
1466 // this can be obtained by simply disabling the chapter format
1467 bChapterFormatOK = sal_False;
1468 }
1469 }
1470 //<---
1471
1472 // ... and write Element
1473 if (eElement != XML_TOKEN_INVALID)
1474 {
1475 // character style (for most templates)
1476 if (bCharStyleOK)
1477 {
1478 switch (nTokenType)
1479 {
1480 case TOK_TTYPE_ENTRY_TEXT:
1481 case TOK_TTYPE_TEXT:
1482 case TOK_TTYPE_PAGE_NUMBER:
1483 case TOK_TTYPE_ENTRY_NUMBER:
1484 case TOK_TTYPE_HYPERLINK_START:
1485 case TOK_TTYPE_HYPERLINK_END:
1486 case TOK_TTYPE_BIBLIOGRAPHY:
1487 case TOK_TTYPE_CHAPTER_INFO:
1488 case TOK_TTYPE_TAB_STOP:
1489 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1490 XML_STYLE_NAME,
1491 GetExport().EncodeStyleName( sCharStyle) );
1492 break;
1493 default:
1494 ; // nothing: no character style
1495 break;
1496 }
1497 }
1498
1499 // tab properties
1500 if (TOK_TTYPE_TAB_STOP == nTokenType)
1501 {
1502 // tab type
1503 GetExport().AddAttribute(XML_NAMESPACE_STYLE, XML_TYPE,
1504 bRightAligned ? XML_RIGHT : XML_LEFT);
1505
1506 if (bTabPositionOK && (! bRightAligned))
1507 {
1508 // position for left tabs (convert to measure)
1509 OUStringBuffer sBuf;
1510 GetExport().GetMM100UnitConverter().convertMeasure(sBuf,
1511 nTabPosition);
1512 GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1513 XML_POSITION,
1514 sBuf.makeStringAndClear());
1515 }
1516
1517 // fill char ("leader char")
1518 if (bFillCharOK && (sFillChar.getLength() > 0))
1519 {
1520 GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1521 XML_LEADER_CHAR, sFillChar);
1522 }
1523
1524 // #i21237#
1525 if (bWithTabStopOK && ! bWithTabStop && !SvtSaveOptions::IsODFStrict( aODFVersion ))
1526 {
1527 GetExport().AddAttribute(XML_NAMESPACE_STYLE,
1528 XML_WITH_TAB,
1529 XML_FALSE);
1530 }
1531 }
1532
1533 // bibliography data
1534 if (TOK_TTYPE_BIBLIOGRAPHY == nTokenType)
1535 {
1536 OSL_ENSURE(bBibliographyDataOK, "need bibl data");
1537 OUStringBuffer sBuf;
1538 if (SvXMLUnitConverter::convertEnum( sBuf, nBibliographyData,
1539 aBibliographyDataFieldMap ) )
1540 {
1541 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1542 XML_BIBLIOGRAPHY_DATA_FIELD,
1543 sBuf.makeStringAndClear());
1544 }
1545 }
1546
1547 // chapter info
1548 if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1549 {
1550 OSL_ENSURE(bChapterFormatOK, "need chapter info");
1551 GetExport().AddAttribute(
1552 XML_NAMESPACE_TEXT, XML_DISPLAY,
1553 XMLTextFieldExport::MapChapterDisplayFormat(nChapterFormat));
1554 //---> i53420
1555 if (bLevelOK)
1556 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
1557 OUString::valueOf((sal_Int32)nLevel));
1558 //<---
1559 }
1560
1561 //--->i53420
1562 if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1563 {
1564 if (bChapterFormatOK)
1565 GetExport().AddAttribute(
1566 XML_NAMESPACE_TEXT, XML_DISPLAY,
1567 XMLTextFieldExport::MapChapterDisplayFormat(nChapterFormat));
1568
1569 if (bLevelOK)
1570 GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
1571 OUString::valueOf((sal_Int32)nLevel));
1572 }
1573 //<---
1574 // export template
1575 SvXMLElementExport aTemplateElement(GetExport(), XML_NAMESPACE_TEXT,
1576 GetXMLToken(eElement),
1577 sal_True, sal_False)
1578 ;
1579
1580 // entry text or span element: write text
1581 if (TOK_TTYPE_TEXT == nTokenType)
1582 {
1583 GetExport().Characters(sText);
1584 }
1585 }
1586 }
1587
ExportLevelParagraphStyles(Reference<XIndexReplace> & xLevelParagraphStyles)1588 void XMLSectionExport::ExportLevelParagraphStyles(
1589 Reference<XIndexReplace> & xLevelParagraphStyles)
1590 {
1591 // iterate over levels
1592 sal_Int32 nPLevelCount = xLevelParagraphStyles->getCount();
1593 for(sal_Int32 nLevel = 0; nLevel < nPLevelCount; nLevel++)
1594 {
1595 Any aAny = xLevelParagraphStyles->getByIndex(nLevel);
1596 Sequence<OUString> aStyleNames;
1597 aAny >>= aStyleNames;
1598
1599 // export only if at least one style is contained
1600 sal_Int32 nNamesCount = aStyleNames.getLength();
1601 if (nNamesCount > 0)
1602 {
1603 // level attribute; we count 1..10; API 0..9
1604 OUStringBuffer sBuf;
1605 sal_Int32 nLevelPlusOne = nLevel + 1;
1606 SvXMLUnitConverter::convertNumber(sBuf, nLevelPlusOne);
1607 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1608 XML_OUTLINE_LEVEL,
1609 sBuf.makeStringAndClear());
1610
1611 // source styles element
1612 SvXMLElementExport aParaStyles(GetExport(),
1613 XML_NAMESPACE_TEXT,
1614 XML_INDEX_SOURCE_STYLES,
1615 sal_True, sal_True);
1616
1617 // iterate over styles in this level
1618 for(sal_Int32 nName = 0; nName < nNamesCount; nName++)
1619 {
1620 // stylename attribute
1621 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1622 XML_STYLE_NAME,
1623 GetExport().EncodeStyleName( aStyleNames[nName]) );
1624
1625 // element
1626 SvXMLElementExport aParaStyle(GetExport(),
1627 XML_NAMESPACE_TEXT,
1628 XML_INDEX_SOURCE_STYLE,
1629 sal_True, sal_False);
1630 }
1631 }
1632 }
1633 }
1634
ExportBoolean(const Reference<XPropertySet> & rPropSet,const OUString & sPropertyName,enum XMLTokenEnum eAttributeName,sal_Bool bDefault,sal_Bool bInvert)1635 void XMLSectionExport::ExportBoolean(
1636 const Reference<XPropertySet> & rPropSet,
1637 const OUString& sPropertyName,
1638 enum XMLTokenEnum eAttributeName,
1639 sal_Bool bDefault,
1640 sal_Bool bInvert)
1641 {
1642 OSL_ENSURE(eAttributeName != XML_TOKEN_INVALID, "Need attribute name");
1643
1644 Any aAny = rPropSet->getPropertyValue(sPropertyName);
1645 sal_Bool bTmp = *(sal_Bool*)aAny.getValue();
1646
1647 // value = value ^ bInvert
1648 // omit if value == default
1649 // negate forces sal_Bool to 0/1, making them comparable
1650 if ((!(bTmp ^ bInvert)) != (!bDefault))
1651 {
1652 // export non-default value (since default is omitted)
1653 GetExport().AddAttribute(XML_NAMESPACE_TEXT,
1654 eAttributeName,
1655 bDefault ? XML_FALSE : XML_TRUE);
1656 }
1657 }
1658
1659 const sal_Char sAPI_FieldMaster_Bibliography[] =
1660 "com.sun.star.text.FieldMaster.Bibliography";
1661 const sal_Char sAPI_SortKey[] = "SortKey";
1662 const sal_Char sAPI_IsSortAscending[] = "IsSortAscending";
1663
ExportBibliographyConfiguration(SvXMLExport & rExport)1664 void XMLSectionExport::ExportBibliographyConfiguration(SvXMLExport& rExport)
1665 {
1666 // first: get field master (via text field supplier)
1667 Reference<XTextFieldsSupplier> xTextFieldsSupp( rExport.GetModel(),
1668 UNO_QUERY );
1669 if ( xTextFieldsSupp.is() )
1670 {
1671 const OUString sFieldMaster_Bibliography(
1672 RTL_CONSTASCII_USTRINGPARAM(sAPI_FieldMaster_Bibliography));
1673
1674 // get bibliography field master
1675 Reference<XNameAccess> xMasters =
1676 xTextFieldsSupp->getTextFieldMasters();
1677 if ( xMasters->hasByName(sFieldMaster_Bibliography) )
1678 {
1679 Any aAny =
1680 xMasters->getByName(sFieldMaster_Bibliography);
1681 Reference<XPropertySet> xPropSet;
1682 aAny >>= xPropSet;
1683
1684 OSL_ENSURE( xPropSet.is(), "field master must have XPropSet" );
1685
1686 const OUString sBracketBefore(
1687 RTL_CONSTASCII_USTRINGPARAM("BracketBefore"));
1688 const OUString sBracketAfter(
1689 RTL_CONSTASCII_USTRINGPARAM("BracketAfter"));
1690 const OUString sIsNumberEntries(
1691 RTL_CONSTASCII_USTRINGPARAM("IsNumberEntries"));
1692 const OUString sIsSortByPosition(
1693 RTL_CONSTASCII_USTRINGPARAM("IsSortByPosition"));
1694 const OUString sSortKeys(
1695 RTL_CONSTASCII_USTRINGPARAM("SortKeys"));
1696 const OUString sSortAlgorithm(
1697 RTL_CONSTASCII_USTRINGPARAM("SortAlgorithm"));
1698 const OUString sLocale(
1699 RTL_CONSTASCII_USTRINGPARAM("Locale"));
1700
1701 OUString sTmp;
1702
1703 aAny = xPropSet->getPropertyValue(sBracketBefore);
1704 aAny >>= sTmp;
1705 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_PREFIX, sTmp);
1706
1707 aAny = xPropSet->getPropertyValue(sBracketAfter);
1708 aAny >>= sTmp;
1709 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_SUFFIX, sTmp);
1710
1711 aAny = xPropSet->getPropertyValue(sIsNumberEntries);
1712 if (*(sal_Bool*)aAny.getValue())
1713 {
1714 rExport.AddAttribute(XML_NAMESPACE_TEXT,
1715 XML_NUMBERED_ENTRIES, XML_TRUE);
1716 }
1717
1718 aAny = xPropSet->getPropertyValue(sIsSortByPosition);
1719 if (! *(sal_Bool*)aAny.getValue())
1720 {
1721 rExport.AddAttribute(XML_NAMESPACE_TEXT,
1722 XML_SORT_BY_POSITION, XML_FALSE);
1723 }
1724
1725 // sort algorithm
1726 aAny = xPropSet->getPropertyValue(sSortAlgorithm);
1727 OUString sAlgorithm;
1728 aAny >>= sAlgorithm;
1729 if( sAlgorithm.getLength() > 0 )
1730 {
1731 rExport.AddAttribute( XML_NAMESPACE_TEXT,
1732 XML_SORT_ALGORITHM, sAlgorithm );
1733 }
1734
1735 // locale
1736 aAny = xPropSet->getPropertyValue(sLocale);
1737 Locale aLocale;
1738 aAny >>= aLocale;
1739 rExport.AddAttribute(XML_NAMESPACE_FO, XML_LANGUAGE,
1740 aLocale.Language);
1741 rExport.AddAttribute(XML_NAMESPACE_FO, XML_COUNTRY,
1742 aLocale.Country);
1743
1744 // configuration element
1745 SvXMLElementExport aElement(rExport, XML_NAMESPACE_TEXT,
1746 XML_BIBLIOGRAPHY_CONFIGURATION,
1747 sal_True, sal_True);
1748
1749 // sort keys
1750 aAny = xPropSet->getPropertyValue(sSortKeys);
1751 Sequence<Sequence<PropertyValue> > aKeys;
1752 aAny >>= aKeys;
1753 sal_Int32 nKeysCount = aKeys.getLength();
1754 for(sal_Int32 nKeys = 0; nKeys < nKeysCount; nKeys++)
1755 {
1756 Sequence<PropertyValue> & rKey = aKeys[nKeys];
1757
1758 sal_Int32 nKeyCount = rKey.getLength();
1759 for(sal_Int32 nPropertyKey = 0; nPropertyKey < nKeyCount; nPropertyKey++)
1760 {
1761 PropertyValue& rValue = rKey[nPropertyKey];
1762
1763 if (rValue.Name.equalsAsciiL(sAPI_SortKey,
1764 sizeof(sAPI_SortKey)-1))
1765 {
1766 sal_Int16 nKey = 0;
1767 rValue.Value >>= nKey;
1768 OUStringBuffer sBuf;
1769 if (SvXMLUnitConverter::convertEnum( sBuf, nKey,
1770 aBibliographyDataFieldMap ) )
1771 {
1772 rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_KEY,
1773 sBuf.makeStringAndClear());
1774 }
1775 }
1776 else if (rValue.Name.equalsAsciiL(sAPI_IsSortAscending,
1777 sizeof(sAPI_IsSortAscending)-1))
1778 {
1779 sal_Bool bTmp = *(sal_Bool*)rValue.Value.getValue();
1780 rExport.AddAttribute(XML_NAMESPACE_TEXT,
1781 XML_SORT_ASCENDING,
1782 bTmp ? XML_TRUE : XML_FALSE);
1783 }
1784 }
1785
1786 SvXMLElementExport aKeyElem(rExport,
1787 XML_NAMESPACE_TEXT, XML_SORT_KEY,
1788 sal_True, sal_True);
1789 }
1790 }
1791 }
1792 }
1793
1794
IsMuteSection(const Reference<XTextSection> & rSection) const1795 sal_Bool XMLSectionExport::IsMuteSection(
1796 const Reference<XTextSection> & rSection) const
1797 {
1798 sal_Bool bRet = sal_False;
1799
1800 // a section is mute if
1801 // 1) it exists
1802 // 2) the SaveLinkedSections flag (at the export) is false
1803 // 3) the IsGlobalDocumentSection property is true
1804 // 4) it is not an Index
1805
1806 if ( (!rExport.IsSaveLinkedSections()) && rSection.is() )
1807 {
1808 // walk the section chain and set bRet if any is linked
1809 for(Reference<XTextSection> aSection(rSection);
1810 aSection.is();
1811 aSection = aSection->getParentSection())
1812 {
1813 // check if it is a global document section (linked or index)
1814 Reference<XPropertySet> xPropSet(aSection, UNO_QUERY);
1815 if (xPropSet.is())
1816 {
1817 Any aAny = xPropSet->getPropertyValue(sIsGlobalDocumentSection);
1818
1819 if ( *(sal_Bool*)aAny.getValue() )
1820 {
1821 Reference<XDocumentIndex> xIndex;
1822 if (! GetIndex(rSection, xIndex))
1823 {
1824 bRet = sal_True;
1825
1826 // early out if result is known
1827 break;
1828 }
1829 }
1830 }
1831 // section has no properties: ignore
1832 }
1833 }
1834 // else: no section, or always save sections: default (false)
1835
1836 return bRet;
1837 }
1838
IsMuteSection(const Reference<XTextContent> & rSection,sal_Bool bDefault) const1839 sal_Bool XMLSectionExport::IsMuteSection(
1840 const Reference<XTextContent> & rSection,
1841 sal_Bool bDefault) const
1842 {
1843 // default: like default argument
1844 sal_Bool bRet = bDefault;
1845
1846 Reference<XPropertySet> xPropSet(rSection->getAnchor(), UNO_QUERY);
1847 if (xPropSet.is())
1848 {
1849 if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
1850 {
1851 Any aAny = xPropSet->getPropertyValue(sTextSection);
1852 Reference<XTextSection> xSection;
1853 aAny >>= xSection;
1854
1855 bRet = IsMuteSection(xSection);
1856 }
1857 // else: return default
1858 }
1859 // else: return default
1860
1861 return bRet;
1862 }
1863
IsInSection(const Reference<XTextSection> & rEnclosingSection,const Reference<XTextContent> & rContent,sal_Bool bDefault)1864 sal_Bool XMLSectionExport::IsInSection(
1865 const Reference<XTextSection> & rEnclosingSection,
1866 const Reference<XTextContent> & rContent,
1867 sal_Bool bDefault)
1868 {
1869 // default: like default argument
1870 sal_Bool bRet = bDefault;
1871 OSL_ENSURE(rEnclosingSection.is(), "enclosing section expected");
1872
1873 Reference<XPropertySet> xPropSet(rContent, UNO_QUERY);
1874 if (xPropSet.is())
1875 {
1876 if (xPropSet->getPropertySetInfo()->hasPropertyByName(sTextSection))
1877 {
1878 Any aAny = xPropSet->getPropertyValue(sTextSection);
1879 Reference<XTextSection> xSection;
1880 aAny >>= xSection;
1881
1882 // now walk chain of text sections (if we have one)
1883 if (xSection.is())
1884 {
1885 do
1886 {
1887 bRet = (rEnclosingSection == xSection);
1888 xSection = xSection->getParentSection();
1889 }
1890 while (!bRet && xSection.is());
1891 }
1892 else
1893 bRet = sal_False; // no section -> can't be inside
1894 }
1895 // else: no TextSection property -> return default
1896 }
1897 // else: no XPropertySet -> return default
1898
1899 return bRet;
1900 }
1901
1902
ExportMasterDocHeadingDummies()1903 void XMLSectionExport::ExportMasterDocHeadingDummies()
1904 {
1905 if( bHeadingDummiesExported )
1906 return;
1907
1908 Reference< XChapterNumberingSupplier > xCNSupplier( rExport.GetModel(),
1909 UNO_QUERY );
1910
1911 Reference< XIndexReplace > xChapterNumbering;
1912 if( xCNSupplier.is() )
1913 xChapterNumbering = xCNSupplier->getChapterNumberingRules();
1914
1915 if( !xChapterNumbering.is() )
1916 return;
1917
1918 sal_Int32 nCount = xChapterNumbering->getCount();
1919 for( sal_Int32 nLevel = 0; nLevel < nCount; nLevel++ )
1920 {
1921 OUString sStyle;
1922 Sequence<PropertyValue> aProperties;
1923 xChapterNumbering->getByIndex( nLevel ) >>= aProperties;
1924 for( sal_Int32 i = 0; i < aProperties.getLength(); i++ )
1925 {
1926 if( aProperties[i].Name == sHeadingStyleName )
1927 {
1928 aProperties[i].Value >>= sStyle;
1929 break;
1930 }
1931 }
1932 if( sStyle.getLength() > 0 )
1933 {
1934 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_STYLE_NAME,
1935 GetExport().EncodeStyleName( sStyle ) );
1936
1937 OUStringBuffer sTmp;
1938 sTmp.append( nLevel + 1 );
1939 GetExport().AddAttribute( XML_NAMESPACE_TEXT, XML_OUTLINE_LEVEL,
1940 sTmp.makeStringAndClear() );
1941 SvXMLElementExport aElem( GetExport(), XML_NAMESPACE_TEXT, XML_H,
1942 sal_True, sal_False );
1943 }
1944 }
1945
1946 bHeadingDummiesExported = sal_True;
1947 }
1948