LibreOffice Module xmloff (master) 1
XMLSectionExport.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "XMLSectionExport.hxx"
21#include <o3tl/any.hxx>
22#include <rtl/ustring.hxx>
23#include <rtl/ustrbuf.hxx>
24#include <osl/diagnose.h>
25#include <com/sun/star/frame/XModel.hpp>
26#include <com/sun/star/lang/Locale.hpp>
27#include <com/sun/star/container/XIndexReplace.hpp>
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/beans/PropertyValue.hpp>
30#include <com/sun/star/beans/PropertyValues.hpp>
31#include <com/sun/star/text/XTextSection.hpp>
32#include <com/sun/star/text/SectionFileLink.hpp>
33#include <com/sun/star/container/XNamed.hpp>
34#include <com/sun/star/container/XNameAccess.hpp>
35#include <com/sun/star/text/XDocumentIndex.hpp>
36#include <com/sun/star/text/BibliographyDataField.hpp>
37#include <com/sun/star/text/XTextFieldsSupplier.hpp>
38#include <com/sun/star/text/XChapterNumberingSupplier.hpp>
39#include <com/sun/star/text/ChapterFormat.hpp>
40
41#include <comphelper/base64.hxx>
42
43#include <xmloff/xmltoken.hxx>
45#include <xmloff/families.hxx>
46#include <xmloff/xmluconv.hxx>
48#include <xmloff/xmlexp.hxx>
49#include <xmloff/xmlement.hxx>
50#include <txtflde.hxx>
51
52
53using namespace ::com::sun::star;
54using namespace ::com::sun::star::text;
55using namespace ::com::sun::star::uno;
56using namespace ::xmloff::token;
57
58using ::com::sun::star::beans::XPropertySet;
59using ::com::sun::star::beans::PropertyValue;
60using ::com::sun::star::beans::PropertyValues;
61using ::com::sun::star::container::XIndexReplace;
62using ::com::sun::star::container::XNameAccess;
63using ::com::sun::star::container::XNamed;
64using ::com::sun::star::lang::Locale;
65
66
68 SvXMLExport& rExp,
69 XMLTextParagraphExport& rParaExp)
70: rExport(rExp)
71, rParaExport(rParaExp)
72, bHeadingDummiesExported( false )
73{
74}
75
76
78 const Reference<XTextSection> & rSection,
79 bool bAutoStyles)
80{
81 Reference<XPropertySet> xPropertySet(rSection, UNO_QUERY);
82
83 // always export section (auto) style
84 if (bAutoStyles)
85 {
86 // get PropertySet and add section style
88 }
89 else
90 {
91 // always export section style
93 GetParaExport().Find(
95 xPropertySet, "" ) );
96
97 // xml:id for RDF metadata
98 GetExport().AddAttributeXmlId(rSection);
99
100 // export index or regular section
101 Reference<XDocumentIndex> xIndex;
102 if (GetIndex(rSection, xIndex))
103 {
104 if (xIndex.is())
105 {
106 // we are an index
107 ExportIndexStart(xIndex);
108 }
109 else
110 {
111 // we are an index header
112 ExportIndexHeaderStart(rSection);
113 }
114 }
115 else
116 {
117 // we are not an index
119 }
120 }
121}
122
124 const Reference<XTextSection> & rSection,
125 Reference<XDocumentIndex> & rIndex)
126{
127 // first, reset result
128 bool bRet = false;
129 rIndex = nullptr;
130
131 // get section Properties
132 Reference<XPropertySet> xSectionPropSet(rSection, UNO_QUERY);
133
134 // then check if this section happens to be inside an index
135 if (xSectionPropSet->getPropertySetInfo()->
136 hasPropertyByName("DocumentIndex"))
137 {
138 Any aAny = xSectionPropSet->getPropertyValue("DocumentIndex");
139 Reference<XDocumentIndex> xDocumentIndex;
140 aAny >>= xDocumentIndex;
141
142 // OK, are we inside of an index
143 if (xDocumentIndex.is())
144 {
145 // is the enclosing index identical with "our" section?
146 Reference<XPropertySet> xIndexPropSet(xDocumentIndex, UNO_QUERY);
147 aAny = xIndexPropSet->getPropertyValue("ContentSection");
148 Reference<XTextSection> xEnclosingSection;
149 aAny >>= xEnclosingSection;
150
151 // if the enclosing section is "our" section, then we are an index!
152 if (rSection == xEnclosingSection)
153 {
154 rIndex = xDocumentIndex;
155 bRet = true;
156 }
157 // else: index header or regular section
158
159 // is the enclosing index identical with the header section?
160 aAny = xIndexPropSet->getPropertyValue("HeaderSection");
161 // now mis-named: contains header section
162 aAny >>= xEnclosingSection;
163
164 // if the enclosing section is "our" section, then we are an index!
165 if (rSection == xEnclosingSection)
166 {
167 bRet = true;
168 }
169 // else: regular section
170 }
171 // else: we aren't even inside of an index
172 }
173 // else: we don't even know what an index is.
174
175 return bRet;
176}
177
178
180 const Reference<XTextSection> & rSection,
181 bool bAutoStyles)
182{
183 // no end section for styles
184 if (bAutoStyles)
185 return;
186
187 enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
188
189 // export index or regular section end
190 Reference<XDocumentIndex> xIndex;
191 if (GetIndex(rSection, xIndex))
192 {
193 if (xIndex.is())
194 {
195 // index end: close index body element
197 true );
199
200 switch (MapSectionType(xIndex->getServiceName()))
201 {
203 eElement = XML_TABLE_OF_CONTENT;
204 break;
205
207 eElement = XML_ILLUSTRATION_INDEX;
208 break;
209
211 eElement = XML_ALPHABETICAL_INDEX;
212 break;
213
215 eElement = XML_TABLE_INDEX;
216 break;
217
219 eElement = XML_OBJECT_INDEX;
220 break;
221
223 eElement = XML_USER_INDEX;
224 break;
225
227 eElement = XML_BIBLIOGRAPHY;
228 break;
229
230 default:
231 OSL_FAIL("unknown index type");
232 // default: skip index!
233 break;
234 }
235 }
236 else
237 {
238 eElement = XML_INDEX_TITLE;
239 }
240 }
241 else
242 {
243 eElement = XML_SECTION;
244 }
245
246 if (XML_TOKEN_INVALID != eElement)
247 {
248 // any old attributes?
250
251 // element surrounded by whitespace
252 GetExport().EndElement( XML_NAMESPACE_TEXT, eElement, true);
254 }
255 else
256 {
257 OSL_FAIL("Need element name!");
258 }
259 // else: autostyles -> ignore
260}
261
263 const Reference<XDocumentIndex> & rIndex)
264{
265 // get PropertySet
266 Reference<XPropertySet> xPropertySet(rIndex, UNO_QUERY);
267
268 switch (MapSectionType(rIndex->getServiceName()))
269 {
271 ExportTableOfContentStart(xPropertySet);
272 break;
273
275 ExportIllustrationIndexStart(xPropertySet);
276 break;
277
279 ExportAlphabeticalIndexStart(xPropertySet);
280 break;
281
283 ExportTableIndexStart(xPropertySet);
284 break;
285
287 ExportObjectIndexStart(xPropertySet);
288 break;
289
291 ExportUserIndexStart(xPropertySet);
292 break;
293
295 ExportBibliographyStart(xPropertySet);
296 break;
297
298 default:
299 // skip index
300 OSL_FAIL("unknown index type");
301 break;
302 }
303}
304
306 const Reference<XTextSection> & rSection)
307{
308 // export name, dammit!
309 Reference<XNamed> xName(rSection, UNO_QUERY);
311
312 // format already handled -> export only start element
315}
316
317
319{
320 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ContentIndex", TEXT_SECTION_TYPE_TOC ),
321 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.DocumentIndex", TEXT_SECTION_TYPE_ALPHABETICAL ),
322 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.TableIndex", TEXT_SECTION_TYPE_TABLE ),
323 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ObjectIndex", TEXT_SECTION_TYPE_OBJECT ),
324 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.Bibliography", TEXT_SECTION_TYPE_BIBLIOGRAPHY ),
325 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.UserIndex", TEXT_SECTION_TYPE_USER ),
326 ENUM_STRING_MAP_ENTRY( "com.sun.star.text.IllustrationsIndex", TEXT_SECTION_TYPE_ILLUSTRATION ),
327 { nullptr, 0, SectionTypeEnum(0) }
328};
329
331 std::u16string_view rServiceName)
332{
334
336
337 // TODO: index header section types, etc.
338
339 return eType;
340}
341
343 const Reference<XTextSection> & rSection)
344{
345 // style name already handled in ExportSectionStart(...)
346
347 Reference<XNamed> xName(rSection, UNO_QUERY);
349
350 // get XPropertySet for other values
351 Reference<XPropertySet> xPropSet(rSection, UNO_QUERY);
352
353 // condition and display
354 Any aAny = xPropSet->getPropertyValue("Condition");
355 OUString sCond;
356 aAny >>= sCond;
357 enum XMLTokenEnum eDisplay = XML_TOKEN_INVALID;
358 if (!sCond.isEmpty())
359 {
360 OUString sQValue =
362 sCond, false );
364 eDisplay = XML_CONDITION;
365
366 // #97450# store hidden-status (of conditional sections only)
367 aAny = xPropSet->getPropertyValue("IsCurrentlyVisible");
368 if (! *o3tl::doAccess<bool>(aAny))
369 {
371 XML_TRUE);
372 }
373 }
374 else
375 {
376 eDisplay = XML_NONE;
377 }
378 aAny = xPropSet->getPropertyValue("IsVisible");
379 if (! *o3tl::doAccess<bool>(aAny))
380 {
382 }
383
384 // protect + protection key
385 aAny = xPropSet->getPropertyValue("IsProtected");
386 if (*o3tl::doAccess<bool>(aAny))
387 {
389 }
390 Sequence<sal_Int8> aPassword;
391 xPropSet->getPropertyValue("ProtectionKey") >>= aPassword;
392 if (aPassword.hasElements())
393 {
394 OUStringBuffer aBuffer;
396 // in ODF 1.0/1.1 the algorithm was left unspecified so we can write anything
398 aBuffer.makeStringAndClear());
399 if (aPassword.getLength() == 32 && GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
400 {
401 // attribute exists in ODF 1.2 or later; default is SHA1 so no need to write that
403 // write the URL from ODF 1.2, not the W3C one
404 "http://www.w3.org/2000/09/xmldsig#sha256");
405 }
406 }
407
408 // export element
411
412 // data source
413 // unfortunately, we have to test all relevant strings for non-zero length
414 aAny = xPropSet->getPropertyValue("FileLink");
415 SectionFileLink aFileLink;
416 aAny >>= aFileLink;
417
418 aAny = xPropSet->getPropertyValue("LinkRegion");
419 OUString sRegionName;
420 aAny >>= sRegionName;
421
422 if ( !aFileLink.FileURL.isEmpty() ||
423 !aFileLink.FilterName.isEmpty() ||
424 !sRegionName.isEmpty())
425 {
426 if (!aFileLink.FileURL.isEmpty())
427 {
429 GetExport().GetRelativeReference( aFileLink.FileURL) );
430 }
431
432 if (!aFileLink.FilterName.isEmpty())
433 {
435 aFileLink.FilterName);
436 }
437
438 if (!sRegionName.isEmpty())
439 {
441 sRegionName);
442 }
443
446 true, true);
447 }
448 else
449 {
450 // check for DDE first
451 if (xPropSet->getPropertySetInfo()->hasPropertyByName("DDECommandFile"))
452 {
453 // data source DDE
454 // unfortunately, we have to test all relevant strings for
455 // non-zero length
456 aAny = xPropSet->getPropertyValue("DDECommandFile");
457 OUString sApplication;
458 aAny >>= sApplication;
459 aAny = xPropSet->getPropertyValue("DDECommandType");
460 OUString sTopic;
461 aAny >>= sTopic;
462 aAny = xPropSet->getPropertyValue("DDECommandElement");
463 OUString sItem;
464 aAny >>= sItem;
465
466 if ( !sApplication.isEmpty() ||
467 !sTopic.isEmpty() ||
468 !sItem.isEmpty())
469 {
471 XML_DDE_APPLICATION, sApplication);
473 sTopic);
475 sItem);
476
477 aAny = xPropSet->getPropertyValue("IsAutomaticUpdate");
478 if (*o3tl::doAccess<bool>(aAny))
479 {
482 }
483
486 XML_DDE_SOURCE, true, true);
487 }
488 // else: no DDE data source
489 }
490 // else: no DDE on this system
491 }
492}
493
495 const Reference<XPropertySet> & rPropertySet)
496{
497 // export TOC element start
499
500 // scope for table-of-content-source element
501 {
502 // TOC specific index source attributes:
503
504 // outline-level: 1..10
505 sal_Int16 nLevel = sal_Int16();
506 if( rPropertySet->getPropertyValue("Level") >>= nLevel )
507 {
510 OUString::number(nLevel));
511 }
512
513 // use outline level
514 ExportBoolean(rPropertySet, "CreateFromOutline",
516
517 // use index marks
518 ExportBoolean(rPropertySet, "CreateFromMarks",
519 XML_USE_INDEX_MARKS, true);
520
521 // use level styles
522 ExportBoolean(rPropertySet, "CreateFromLevelParagraphStyles",
524
526 }
527
529}
530
532 const Reference<XPropertySet> & rPropertySet)
533{
534 // export index start
536
537 // scope for index source element
538 {
539 ExportBoolean(rPropertySet, "CreateFromOtherEmbeddedObjects",
540 XML_USE_OTHER_OBJECTS, false);
541 ExportBoolean(rPropertySet, "CreateFromStarCalc",
543 ExportBoolean(rPropertySet, "CreateFromStarChart",
544 XML_USE_CHART_OBJECTS, false);
545 ExportBoolean(rPropertySet, "CreateFromStarDraw",
546 XML_USE_DRAW_OBJECTS, false);
547 ExportBoolean(rPropertySet, "CreateFromStarMath",
548 XML_USE_MATH_OBJECTS, false);
549
551 }
552
554}
555
557 const Reference<XPropertySet> & rPropertySet)
558{
559 // export index start
561
562 // scope for index source element
563 {
564 // export common attributes for illustration and table indices
566
568 }
569
571}
572
574 const Reference<XPropertySet> & rPropertySet)
575{
576 // export index start
578
579 // scope for index source element
580 {
581 // export common attributes for illustration and table indices
583
585 }
586
588}
589
591 const Reference<XPropertySet> & rPropertySet)
592{
593 // export TOC element start
595
596 // scope for table-of-content-source element
597 {
598
599 // style name (if present)
600 Any aAny = rPropertySet->getPropertyValue("MainEntryCharacterStyleName");
601 OUString sStyleName;
602 aAny >>= sStyleName;
603 if (!sStyleName.isEmpty())
604 {
607 GetExport().EncodeStyleName( sStyleName ));
608 }
609
610 // other (boolean) attributes
611 ExportBoolean(rPropertySet, "IsCaseSensitive", XML_IGNORE_CASE,
612 false, true);
613 ExportBoolean(rPropertySet, "UseAlphabeticalSeparators",
615 ExportBoolean(rPropertySet, "UseCombinedEntries", XML_COMBINE_ENTRIES,
616 true);
617 ExportBoolean(rPropertySet, "UseDash", XML_COMBINE_ENTRIES_WITH_DASH,
618 false);
619 ExportBoolean(rPropertySet, "UseKeyAsEntry", XML_USE_KEYS_AS_ENTRIES,
620 false);
621 ExportBoolean(rPropertySet, "UsePP", XML_COMBINE_ENTRIES_WITH_PP,
622 true);
623 ExportBoolean(rPropertySet, "UseUpperCase", XML_CAPITALIZE_ENTRIES,
624 false);
625 ExportBoolean(rPropertySet, "IsCommaSeparated", XML_COMMA_SEPARATED,
626 false);
627
628 // sort algorithm
629 aAny = rPropertySet->getPropertyValue("SortAlgorithm");
630 OUString sAlgorithm;
631 aAny >>= sAlgorithm;
632 if (!sAlgorithm.isEmpty())
633 {
635 sAlgorithm );
636 }
637
638 // locale
639 aAny = rPropertySet->getPropertyValue("Locale");
640 Locale aLocale;
641 aAny >>= aLocale;
643
645 }
646
648}
649
651 const Reference<XPropertySet> & rPropertySet)
652{
653 // export TOC element start
655
656 // scope for table-of-content-source element
657 {
658 // bool attributes
659 ExportBoolean(rPropertySet, "CreateFromEmbeddedObjects",
660 XML_USE_OBJECTS, false);
661 ExportBoolean(rPropertySet, "CreateFromGraphicObjects",
662 XML_USE_GRAPHICS, false);
663 ExportBoolean(rPropertySet, "CreateFromMarks",
664 XML_USE_INDEX_MARKS, false);
665 ExportBoolean(rPropertySet, "CreateFromTables",
666 XML_USE_TABLES, false);
667 ExportBoolean(rPropertySet, "CreateFromTextFrames",
669 ExportBoolean(rPropertySet, "UseLevelFromSource",
671 ExportBoolean(rPropertySet, "CreateFromLevelParagraphStyles",
673
674 Any aAny = rPropertySet->getPropertyValue( "UserIndexName" );
675 OUString sIndexName;
676 aAny >>= sIndexName;
678 sIndexName);
679
681 }
682
684}
685
687 const Reference<XPropertySet> & rPropertySet)
688{
689 // export TOC element start
691
692 // scope for table-of-content-source element
693 {
694 // No attributes. Fine.
695
697 }
698
700}
701
702
704 XMLTokenEnum eElement,
705 const Reference<XPropertySet> & rPropertySet)
706{
707 // protect + protection key
708 Any aAny = rPropertySet->getPropertyValue("IsProtected");
709 if (*o3tl::doAccess<bool>(aAny))
710 {
712 }
713
714 // index name
715 OUString sIndexName;
716 rPropertySet->getPropertyValue("Name") >>= sIndexName;
717 if ( !sIndexName.isEmpty() )
718 {
720 }
721
722 // index Element start
724 GetExport().StartElement( XML_NAMESPACE_TEXT, eElement, false );
725}
726
728{
730 XML_TABLE_INDEX_SOURCE, // table index
731 XML_ILLUSTRATION_INDEX_SOURCE, // illustration index
732 XML_OBJECT_INDEX_SOURCE, // object index
733 XML_USER_INDEX_SOURCE, // user index
734 XML_ALPHABETICAL_INDEX_SOURCE, // alphabetical index
735 XML_BIBLIOGRAPHY_SOURCE // bibliography
736};
737
739 SectionTypeEnum eType,
740 const Reference<XPropertySet> & rPropertySet)
741{
742 // check type
743 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
744 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
745
746 Any aAny;
747
748 // common attributes; not supported by bibliography
750 {
751 // document or chapter index?
752 aAny = rPropertySet->getPropertyValue("CreateFromChapter");
753 if (*o3tl::doAccess<bool>(aAny))
754 {
757 }
758
759 // tab-stops relative to margin?
760 aAny = rPropertySet->getPropertyValue("IsRelativeTabstops");
761 if (! *o3tl::doAccess<bool>(aAny))
762 {
765 XML_FALSE);
766 }
767 }
768
769 // the index source element (all indices)
775 true, true);
776
777 // scope for title template (all indices)
778 {
779 // header style name
780 aAny = rPropertySet->getPropertyValue("ParaStyleHeading");
781 OUString sStyleName;
782 aAny >>= sStyleName;
785 GetExport().EncodeStyleName( sStyleName ));
786
787 // title template
788 SvXMLElementExport aHeaderTemplate(GetExport(),
791 true, false);
792
793 // title as element content
794 aAny = rPropertySet->getPropertyValue("Title");
795 OUString sTitleString;
796 aAny >>= sTitleString;
797 GetExport().Characters(sTitleString);
798 }
799
800 // export level templates (all indices)
801 aAny = rPropertySet->getPropertyValue("LevelFormat");
802 Reference<XIndexReplace> xLevelTemplates;
803 aAny >>= xLevelTemplates;
804
805 // iterate over level formats;
806 // skip element 0 (empty template for title)
807 sal_Int32 nLevelCount = xLevelTemplates->getCount();
808 for(sal_Int32 i = 1; i<nLevelCount; i++)
809 {
810 // get sequence
811 Sequence<PropertyValues> aTemplateSequence;
812 aAny = xLevelTemplates->getByIndex(i);
813 aAny >>= aTemplateSequence;
814
815 // export the sequence (abort export if an error occurred; #91214#)
816 bool bResult =
817 ExportIndexTemplate(eType, i, rPropertySet, aTemplateSequence);
818 if ( !bResult )
819 break;
820 }
821
822 // only TOC and user index:
823 // styles from which to build the index (LevelParagraphStyles)
824 if ( (TEXT_SECTION_TYPE_TOC == eType) ||
826 {
827 aAny = rPropertySet->getPropertyValue("LevelParagraphStyles");
828 Reference<XIndexReplace> xLevelParagraphStyles;
829 aAny >>= xLevelParagraphStyles;
830 ExportLevelParagraphStyles(xLevelParagraphStyles);
831 }
835 {
836 Any const any(rPropertySet->getPropertyValue("CreateFromParagraphStyle"));
837 if (any.hasValue() &&
839 {
840 OUString const styleName(any.get<OUString>());
842 GetExport().EncodeStyleName(styleName));
843
846 }
847 }
848}
849
850
852 SectionTypeEnum eType,
853 const Reference<XPropertySet> &)
854{
855 // type not used; checked anyway.
856 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
857 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
858
859 // export start only
860
861 // any old attributes?
863
864 // start surrounded by whitespace
867}
868
870 const Reference<XPropertySet> & rPropertySet)
871{
872 // use caption
873 Any aAny = rPropertySet->getPropertyValue("CreateFromLabels");
874 if (! *o3tl::doAccess<bool>(aAny))
875 {
878 }
879
880 // sequence name
881 aAny = rPropertySet->getPropertyValue("LabelCategory");
882 OUString sSequenceName;
883 aAny >>= sSequenceName;
886 sSequenceName);
887
888 // caption format
889 aAny = rPropertySet->getPropertyValue("LabelDisplayType");
890 sal_Int16 nType = 0;
891 aAny >>= nType;
895}
896
897
898// map index of LevelFormats to attribute value;
899// level 0 is always the header
915
917{
918 aLevelNameTOCMap, // TOC
919 aLevelNameTableMap, // table index
920 aLevelNameTableMap, // illustration index
921 aLevelNameTableMap, // object index
922 aLevelNameTOCMap, // user index
923 aLevelNameAlphaMap, // alphabetical index
924 aLevelNameBibliographyMap // bibliography
925};
926
927static const char* aLevelStylePropNameTOCMap[] =
928 { nullptr, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
929 "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
930 "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
931 "ParaStyleLevel10", nullptr };
932static const char* aLevelStylePropNameTableMap[] =
933 { nullptr, "ParaStyleLevel1", nullptr };
934static const char* aLevelStylePropNameAlphaMap[] =
935 { nullptr, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
936 "ParaStyleLevel3", nullptr };
938 // TODO: replace with real property names, when available
939 { nullptr, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
940 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
941 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
942 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
943 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
944 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
945 "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
946 "ParaStyleLevel1",
947 nullptr };
948
949static const char** aTypeLevelStylePropNameMap[] =
950{
952 aLevelStylePropNameTableMap, // table index
953 aLevelStylePropNameTableMap, // illustration index
954 aLevelStylePropNameTableMap, // object index
955 aLevelStylePropNameTOCMap, // user index
956 aLevelStylePropNameAlphaMap, // alphabetical index
958};
959
961{
962 XML_OUTLINE_LEVEL, // TOC
963 XML_TOKEN_INVALID, // table index
964 XML_TOKEN_INVALID, // illustration index
965 XML_TOKEN_INVALID, // object index
966 XML_OUTLINE_LEVEL, // user index
967 XML_OUTLINE_LEVEL, // alphabetical index
968 XML_BIBLIOGRAPHY_TYPE // bibliography
969};
970
972{
974 XML_TABLE_INDEX_ENTRY_TEMPLATE, // table index
975 XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE, // illustration index
976 XML_OBJECT_INDEX_ENTRY_TEMPLATE, // object index
977 XML_USER_INDEX_ENTRY_TEMPLATE, // user index
978 XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE, // alphabetical index
979 XML_BIBLIOGRAPHY_ENTRY_TEMPLATE // bibliography
980};
981
982
984 SectionTypeEnum eType,
985 sal_Int32 nOutlineLevel,
986 const Reference<XPropertySet> & rPropertySet,
987 const Sequence<Sequence<PropertyValue> > & rValues)
988{
989 OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
990 OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
991 OSL_ENSURE(nOutlineLevel >= 0, "illegal outline level");
992
993 if ( (eType >= TEXT_SECTION_TYPE_TOC) &&
995 (nOutlineLevel >= 0) )
996 {
997 // get level name and level attribute name from aLevelNameMap;
998 const XMLTokenEnum eLevelAttrName(
1000 const XMLTokenEnum eLevelName(
1002
1003 // #92124#: some old documents may be broken, then they have
1004 // too many template levels; we need to recognize this and
1005 // export only as many as is legal for the respective index
1006 // type. To do this, we simply return an error flag, which
1007 // will then abort further template level exports.
1008 OSL_ENSURE(XML_TOKEN_INVALID != eLevelName, "can't find level name");
1009 if ( XML_TOKEN_INVALID == eLevelName )
1010 {
1011 // output level not found? Then end of templates! #91214#
1012 return false;
1013 }
1014
1015 // output level name
1016 if ((XML_TOKEN_INVALID != eLevelName) && (XML_TOKEN_INVALID != eLevelAttrName))
1017 {
1019 GetXMLToken(eLevelAttrName),
1020 GetXMLToken(eLevelName));
1021 }
1022
1023 // paragraph level style name
1024 const char* pPropName(
1026 OSL_ENSURE(nullptr != pPropName, "can't find property name");
1027 if (nullptr != pPropName)
1028 {
1029 Any aAny = rPropertySet->getPropertyValue(
1030 OUString::createFromAscii(pPropName));
1031 OUString sParaStyleName;
1032 aAny >>= sParaStyleName;
1035 GetExport().EncodeStyleName( sParaStyleName ));
1036 }
1037
1038 // template element
1039 const XMLTokenEnum eElementName(
1041 SvXMLElementExport aLevelTemplate(GetExport(),
1043 GetXMLToken(eElementName),
1044 true, true);
1045
1046 // export sequence
1047 for(auto& rValue : rValues)
1048 {
1050 eType, //i90246
1051 rValue);
1052 }
1053 }
1054
1055 return true;
1056}
1057
1058namespace {
1059
1060enum TemplateTypeEnum
1061{
1062 TOK_TTYPE_ENTRY_NUMBER,
1063 TOK_TTYPE_ENTRY_TEXT,
1064 TOK_TTYPE_TAB_STOP,
1065 TOK_TTYPE_TEXT,
1066 TOK_TTYPE_PAGE_NUMBER,
1067 TOK_TTYPE_CHAPTER_INFO,
1068 TOK_TTYPE_HYPERLINK_START,
1069 TOK_TTYPE_HYPERLINK_END,
1070 TOK_TTYPE_BIBLIOGRAPHY,
1071 TOK_TTYPE_INVALID
1072};
1073
1074enum TemplateParamEnum
1075{
1076 TOK_TPARAM_TOKEN_TYPE,
1077 TOK_TPARAM_CHAR_STYLE,
1078 TOK_TPARAM_TAB_RIGHT_ALIGNED,
1079 TOK_TPARAM_TAB_POSITION,
1080 TOK_TPARAM_TAB_WITH_TAB, // #i21237#
1081 TOK_TPARAM_TAB_FILL_CHAR,
1082 TOK_TPARAM_TEXT,
1083 TOK_TPARAM_CHAPTER_FORMAT,
1084 TOK_TPARAM_CHAPTER_LEVEL,//i53420
1085 TOK_TPARAM_BIBLIOGRAPHY_DATA
1086};
1087
1088}
1089
1091{
1092 ENUM_STRING_MAP_ENTRY( "TokenEntryNumber", TOK_TTYPE_ENTRY_NUMBER ),
1093 ENUM_STRING_MAP_ENTRY( "TokenEntryText", TOK_TTYPE_ENTRY_TEXT ),
1094 ENUM_STRING_MAP_ENTRY( "TokenTabStop", TOK_TTYPE_TAB_STOP ),
1095 ENUM_STRING_MAP_ENTRY( "TokenText", TOK_TTYPE_TEXT ),
1096 ENUM_STRING_MAP_ENTRY( "TokenPageNumber", TOK_TTYPE_PAGE_NUMBER ),
1097 ENUM_STRING_MAP_ENTRY( "TokenChapterInfo", TOK_TTYPE_CHAPTER_INFO ),
1098 ENUM_STRING_MAP_ENTRY( "TokenHyperlinkStart", TOK_TTYPE_HYPERLINK_START ),
1099 ENUM_STRING_MAP_ENTRY( "TokenHyperlinkEnd", TOK_TTYPE_HYPERLINK_END ),
1100 ENUM_STRING_MAP_ENTRY( "TokenBibliographyDataField", TOK_TTYPE_BIBLIOGRAPHY ),
1101 { nullptr, 0, TemplateTypeEnum(0)}
1102};
1103
1105{
1106 ENUM_STRING_MAP_ENTRY( "TokenType", TOK_TPARAM_TOKEN_TYPE ),
1107 ENUM_STRING_MAP_ENTRY( "CharacterStyleName", TOK_TPARAM_CHAR_STYLE ),
1108 ENUM_STRING_MAP_ENTRY( "TabStopRightAligned", TOK_TPARAM_TAB_RIGHT_ALIGNED ),
1109 ENUM_STRING_MAP_ENTRY( "TabStopPosition", TOK_TPARAM_TAB_POSITION ),
1110 ENUM_STRING_MAP_ENTRY( "TabStopFillCharacter", TOK_TPARAM_TAB_FILL_CHAR ),
1111 // #i21237#
1112 ENUM_STRING_MAP_ENTRY( "WithTab", TOK_TPARAM_TAB_WITH_TAB ),
1113 ENUM_STRING_MAP_ENTRY( "Text", TOK_TPARAM_TEXT ),
1114 ENUM_STRING_MAP_ENTRY( "ChapterFormat", TOK_TPARAM_CHAPTER_FORMAT ),
1115 ENUM_STRING_MAP_ENTRY( "ChapterLevel", TOK_TPARAM_CHAPTER_LEVEL ),//i53420
1116 ENUM_STRING_MAP_ENTRY( "BibliographyDataField", TOK_TPARAM_BIBLIOGRAPHY_DATA ),
1117 { nullptr, 0, TemplateParamEnum(0)}
1118};
1119
1121{
1122 { XML_ADDRESS, BibliographyDataField::ADDRESS },
1123 { XML_ANNOTE, BibliographyDataField::ANNOTE },
1124 { XML_AUTHOR, BibliographyDataField::AUTHOR },
1125 { XML_BIBLIOGRAPHY_TYPE, BibliographyDataField::BIBILIOGRAPHIC_TYPE },
1126 { XML_BOOKTITLE, BibliographyDataField::BOOKTITLE },
1127 { XML_CHAPTER, BibliographyDataField::CHAPTER },
1128 { XML_CUSTOM1, BibliographyDataField::CUSTOM1 },
1129 { XML_CUSTOM2, BibliographyDataField::CUSTOM2 },
1130 { XML_CUSTOM3, BibliographyDataField::CUSTOM3 },
1131 { XML_CUSTOM4, BibliographyDataField::CUSTOM4 },
1132 { XML_CUSTOM5, BibliographyDataField::CUSTOM5 },
1133 { XML_EDITION, BibliographyDataField::EDITION },
1134 { XML_EDITOR, BibliographyDataField::EDITOR },
1135 { XML_HOWPUBLISHED, BibliographyDataField::HOWPUBLISHED },
1136 { XML_IDENTIFIER, BibliographyDataField::IDENTIFIER },
1137 { XML_INSTITUTION, BibliographyDataField::INSTITUTION },
1138 { XML_ISBN, BibliographyDataField::ISBN },
1139 { XML_JOURNAL, BibliographyDataField::JOURNAL },
1140 { XML_MONTH, BibliographyDataField::MONTH },
1141 { XML_NOTE, BibliographyDataField::NOTE },
1142 { XML_NUMBER, BibliographyDataField::NUMBER },
1143 { XML_ORGANIZATIONS, BibliographyDataField::ORGANIZATIONS },
1144 { XML_PAGES, BibliographyDataField::PAGES },
1145 { XML_PUBLISHER, BibliographyDataField::PUBLISHER },
1146 { XML_REPORT_TYPE, BibliographyDataField::REPORT_TYPE },
1147 { XML_SCHOOL, BibliographyDataField::SCHOOL },
1148 { XML_SERIES, BibliographyDataField::SERIES },
1149 { XML_TITLE, BibliographyDataField::TITLE },
1150 { XML_URL, BibliographyDataField::URL },
1151 { XML_VOLUME, BibliographyDataField::VOLUME },
1152 { XML_YEAR, BibliographyDataField::YEAR },
1153 { XML_TOKEN_INVALID, 0 }
1154};
1155
1157 SectionTypeEnum eType, //i90246
1158 const Sequence<PropertyValue> & rValues)
1159{
1160 // variables for template values
1161
1162 // char style
1163 OUString sCharStyle;
1164 bool bCharStyleOK = false;
1165
1166 // text
1167 OUString sText;
1168 bool bTextOK = false;
1169
1170 // tab position
1171 bool bRightAligned = false;
1172
1173 // tab position
1174 sal_Int32 nTabPosition = 0;
1175 bool bTabPositionOK = false;
1176
1177 // fill character
1178 OUString sFillChar;
1179 bool bFillCharOK = false;
1180
1181 // chapter format
1182 sal_Int16 nChapterFormat = 0;
1183 bool bChapterFormatOK = false;
1184
1185 // outline max level
1186 sal_Int16 nLevel = 0;
1187 bool bLevelOK = false;
1188
1189 // Bibliography Data
1190 sal_Int16 nBibliographyData = 0;
1191 bool bBibliographyDataOK = false;
1192
1193 // With Tab Stop #i21237#
1194 bool bWithTabStop = false;
1195 bool bWithTabStopOK = false;
1196
1197 //i90246, the ODF version being written to is:
1199 //the above version cannot be used for old OOo (OOo 1.0) formats!
1200
1201 // token type
1202 enum TemplateTypeEnum nTokenType = TOK_TTYPE_INVALID;
1203
1204 for(const auto& rValue : rValues)
1205 {
1206 TemplateParamEnum nToken;
1207 if ( SvXMLUnitConverter::convertEnum( nToken, rValue.Name,
1209 {
1210 // Only use direct and default values.
1211 // Wrong. no property states, so ignore.
1212 // if ( (beans::PropertyState_DIRECT_VALUE == rValues[i].State) ||
1213 // (beans::PropertyState_DEFAULT_VALUE == rValues[i].State) )
1214
1215 switch (nToken)
1216 {
1217 case TOK_TPARAM_TOKEN_TYPE:
1218 {
1219 OUString sVal;
1220 rValue.Value >>= sVal;
1222 break;
1223 }
1224
1225 case TOK_TPARAM_CHAR_STYLE:
1226 // only valid, if not empty
1227 rValue.Value >>= sCharStyle;
1228 bCharStyleOK = !sCharStyle.isEmpty();
1229 break;
1230
1231 case TOK_TPARAM_TEXT:
1232 rValue.Value >>= sText;
1233 bTextOK = true;
1234 break;
1235
1236 case TOK_TPARAM_TAB_RIGHT_ALIGNED:
1237 bRightAligned =
1238 *o3tl::doAccess<bool>(rValue.Value);
1239 break;
1240
1241 case TOK_TPARAM_TAB_POSITION:
1242 rValue.Value >>= nTabPosition;
1243 bTabPositionOK = true;
1244 break;
1245
1246 // #i21237#
1247 case TOK_TPARAM_TAB_WITH_TAB:
1248 bWithTabStop = *o3tl::doAccess<bool>(rValue.Value);
1249 bWithTabStopOK = true;
1250 break;
1251
1252 case TOK_TPARAM_TAB_FILL_CHAR:
1253 rValue.Value >>= sFillChar;
1254 bFillCharOK = true;
1255 break;
1256
1257 case TOK_TPARAM_CHAPTER_FORMAT:
1258 rValue.Value >>= nChapterFormat;
1259 bChapterFormatOK = true;
1260 break;
1261//---> i53420
1262 case TOK_TPARAM_CHAPTER_LEVEL:
1263 rValue.Value >>= nLevel;
1264 bLevelOK = true;
1265 break;
1266 case TOK_TPARAM_BIBLIOGRAPHY_DATA:
1267 rValue.Value >>= nBibliographyData;
1268 bBibliographyDataOK = true;
1269 break;
1270 }
1271 }
1272 }
1273
1274 // convert type to token (and check validity) ...
1276 sal_uInt16 nNamespace(XML_NAMESPACE_TEXT);
1277 switch(nTokenType)
1278 {
1279 case TOK_TTYPE_ENTRY_TEXT:
1280 eElement = XML_INDEX_ENTRY_TEXT;
1281 break;
1282 case TOK_TTYPE_TAB_STOP:
1283 // test validity
1284 if ( bRightAligned || bTabPositionOK || bFillCharOK )
1285 {
1286 eElement = XML_INDEX_ENTRY_TAB_STOP;
1287 }
1288 break;
1289 case TOK_TTYPE_TEXT:
1290 // test validity
1291 if (bTextOK)
1292 {
1293 eElement = XML_INDEX_ENTRY_SPAN;
1294 }
1295 break;
1296 case TOK_TTYPE_PAGE_NUMBER:
1297 eElement = XML_INDEX_ENTRY_PAGE_NUMBER;
1298 break;
1299 case TOK_TTYPE_CHAPTER_INFO: // keyword index
1300 eElement = XML_INDEX_ENTRY_CHAPTER;
1301 break;
1302 case TOK_TTYPE_ENTRY_NUMBER: // table of content
1303 eElement = XML_INDEX_ENTRY_CHAPTER;
1304 break;
1305 case TOK_TTYPE_HYPERLINK_START:
1306 eElement = XML_INDEX_ENTRY_LINK_START;
1307 break;
1308 case TOK_TTYPE_HYPERLINK_END:
1309 eElement = XML_INDEX_ENTRY_LINK_END;
1310 break;
1311 case TOK_TTYPE_BIBLIOGRAPHY:
1312 if (bBibliographyDataOK)
1313 {
1315 }
1316 break;
1317 default:
1318 ; // unknown/unimplemented template
1319 break;
1320 }
1321
1323 {
1324 switch (nTokenType)
1325 {
1326 case TOK_TTYPE_HYPERLINK_START:
1327 case TOK_TTYPE_HYPERLINK_END:
1328 if (SvtSaveOptions::ODFSVER_012 < aODFVersion)
1329 {
1334 // ODF 1.3 OFFICE-3941
1335 nNamespace = (SvtSaveOptions::ODFSVER_013 <= aODFVersion)
1338 }
1339 else
1340 {
1341 eElement = XML_TOKEN_INVALID; // not allowed in ODF <= 1.2
1342 }
1343 break;
1344 default:
1345 break;
1346 }
1347 }
1348
1349 //--->i90246
1350 //check the ODF version being exported
1351 if (aODFVersion == SvtSaveOptions::ODFSVER_011
1352 || aODFVersion == SvtSaveOptions::ODFSVER_010)
1353 {
1354 bLevelOK = false;
1355 if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1356 {
1357 //if we are emitting for ODF 1.1 or 1.0, this information can be used for alphabetical index only
1358 //it's not permitted in other indexes
1360 {
1361 eElement = XML_TOKEN_INVALID; //not permitted, invalidate the element
1362 }
1363 else //maps format for 1.1 & 1.0
1364 {
1365 // a few word here: OOo up to 2.4 uses the field chapter info in Alphabetical index
1366 // in a way different from the ODF 1.1/1.0 specification:
1367
1368 // ODF1.1/1.0 OOo display in chapter info ODF1.2
1369 // (used in alphabetical index only
1370
1371 // number chapter number without pre/postfix plain-number
1372 // number-and-name chapter number without pre/postfix plus title plain-number-and-name
1373
1374 // with issue i89791 the reading of ODF 1.1 and 1.0 was corrected
1375 // this one corrects the writing back from ODF 1.2 to ODF 1.1/1.0
1376 // unfortunately if there is another application which interprets correctly ODF1.1/1.0,
1377 // the resulting alphabetical index will be rendered wrong by OOo 2.4 version
1378
1379 switch( nChapterFormat )
1380 {
1381 case ChapterFormat::DIGIT:
1382 nChapterFormat = ChapterFormat::NUMBER;
1383 break;
1384 case ChapterFormat::NO_PREFIX_SUFFIX:
1385 nChapterFormat = ChapterFormat::NAME_NUMBER;
1386 break;
1387 }
1388 }
1389 }
1390 else if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1391 {
1392 //in case of ODF 1.1 or 1.0 the only allowed number format is "number"
1393 //so, force it...
1394 // The only expected 'foreign' nChapterFormat is
1395 // ' ChapterFormat::DIGIT', forced to 'none, since the
1396 // 'value allowed in ODF 1.1 and 1.0 is 'number' the default
1397 // this can be obtained by simply disabling the chapter format
1398 bChapterFormatOK = false;
1399 }
1400 }
1401
1402 // ... and write Element
1403 if (eElement == XML_TOKEN_INVALID)
1404 return;
1405
1406 // character style (for most templates)
1407 if (bCharStyleOK)
1408 {
1409 switch (nTokenType)
1410 {
1411 case TOK_TTYPE_ENTRY_TEXT:
1412 case TOK_TTYPE_TEXT:
1413 case TOK_TTYPE_PAGE_NUMBER:
1414 case TOK_TTYPE_ENTRY_NUMBER:
1415 case TOK_TTYPE_HYPERLINK_START:
1416 case TOK_TTYPE_HYPERLINK_END:
1417 case TOK_TTYPE_BIBLIOGRAPHY:
1418 case TOK_TTYPE_CHAPTER_INFO:
1419 case TOK_TTYPE_TAB_STOP:
1422 GetExport().EncodeStyleName( sCharStyle) );
1423 break;
1424 default:
1425 ; // nothing: no character style
1426 break;
1427 }
1428 }
1429
1430 // tab properties
1431 if (TOK_TTYPE_TAB_STOP == nTokenType)
1432 {
1433 // tab type
1435 bRightAligned ? XML_RIGHT : XML_LEFT);
1436
1437 if (bTabPositionOK && (! bRightAligned))
1438 {
1439 // position for left tabs (convert to measure)
1440 OUStringBuffer sBuf;
1442 nTabPosition);
1445 sBuf.makeStringAndClear());
1446 }
1447
1448 // fill char ("leader char")
1449 if (bFillCharOK && !sFillChar.isEmpty())
1450 {
1452 XML_LEADER_CHAR, sFillChar);
1453 }
1454
1455 // #i21237#
1456 if (bWithTabStopOK && ! bWithTabStop)
1457 {
1460 XML_FALSE);
1461 }
1462 }
1463
1464 // bibliography data
1465 if (TOK_TTYPE_BIBLIOGRAPHY == nTokenType)
1466 {
1467 OSL_ENSURE(bBibliographyDataOK, "need bibl data");
1468 OUStringBuffer sBuf;
1469 if (SvXMLUnitConverter::convertEnum( sBuf, nBibliographyData,
1471 {
1474 sBuf.makeStringAndClear());
1475 }
1476 }
1477
1478 // chapter info
1479 if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1480 {
1481 OSL_ENSURE(bChapterFormatOK, "need chapter info");
1485//---> i53420
1486 if (bLevelOK)
1488 OUString::number(nLevel));
1489 }
1490
1491//--->i53420
1492 if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1493 {
1494 if (bChapterFormatOK)
1498
1499 if (bLevelOK)
1501 OUString::number(nLevel));
1502 }
1503 // export template
1504 SvXMLElementExport aTemplateElement(GetExport(), nNamespace,
1505 GetXMLToken(eElement),
1506 true, false)
1507 ;
1508
1509 // entry text or span element: write text
1510 if (TOK_TTYPE_TEXT == nTokenType)
1511 {
1512 GetExport().Characters(sText);
1513 }
1514}
1515
1517 Reference<XIndexReplace> const & xLevelParagraphStyles)
1518{
1519 // iterate over levels
1520 sal_Int32 nPLevelCount = xLevelParagraphStyles->getCount();
1521 for(sal_Int32 nLevel = 0; nLevel < nPLevelCount; nLevel++)
1522 {
1523 Any aAny = xLevelParagraphStyles->getByIndex(nLevel);
1524 Sequence<OUString> aStyleNames;
1525 aAny >>= aStyleNames;
1526
1527 // export only if at least one style is contained
1528 if (aStyleNames.hasElements())
1529 {
1530 // level attribute; we count 1..10; API 0..9
1531 sal_Int32 nLevelPlusOne = nLevel + 1;
1534 OUString::number(nLevelPlusOne));
1535
1536 // source styles element
1537 SvXMLElementExport aParaStyles(GetExport(),
1540 true, true);
1541
1542 // iterate over styles in this level
1543 for(const auto& rStyleName : std::as_const(aStyleNames))
1544 {
1545 // stylename attribute
1548 GetExport().EncodeStyleName(rStyleName) );
1549
1550 // element
1551 SvXMLElementExport aParaStyle(GetExport(),
1554 true, false);
1555 }
1556 }
1557 }
1558}
1559
1561 const Reference<XPropertySet> & rPropSet,
1562 const OUString& sPropertyName,
1563 enum XMLTokenEnum eAttributeName,
1564 bool bDefault,
1565 bool bInvert)
1566{
1567 OSL_ENSURE(eAttributeName != XML_TOKEN_INVALID, "Need attribute name");
1568
1569 Any aAny = rPropSet->getPropertyValue(sPropertyName);
1570 bool bTmp = *o3tl::doAccess<bool>(aAny);
1571
1572 // value = value ^ bInvert
1573 // omit if value == default
1574 if ( (bTmp != bInvert) != bDefault )
1575 {
1576 // export non-default value (since default is omitted)
1578 eAttributeName,
1579 bDefault ? XML_FALSE : XML_TRUE);
1580 }
1581}
1582
1584{
1585 // first: get field master (via text field supplier)
1586 Reference<XTextFieldsSupplier> xTextFieldsSupp( rExport.GetModel(),
1587 UNO_QUERY );
1588 if ( !xTextFieldsSupp.is() )
1589 return;
1590
1591 static constexpr OUStringLiteral sFieldMaster_Bibliography(u"com.sun.star.text.FieldMaster.Bibliography");
1592
1593 // get bibliography field master
1594 Reference<XNameAccess> xMasters =
1595 xTextFieldsSupp->getTextFieldMasters();
1596 if ( !xMasters->hasByName(sFieldMaster_Bibliography) )
1597 return;
1598
1599 Any aAny =
1600 xMasters->getByName(sFieldMaster_Bibliography);
1601 Reference<XPropertySet> xPropSet;
1602 aAny >>= xPropSet;
1603
1604 OSL_ENSURE( xPropSet.is(), "field master must have XPropSet" );
1605
1606 OUString sTmp;
1607
1608 aAny = xPropSet->getPropertyValue("BracketBefore");
1609 aAny >>= sTmp;
1611
1612 aAny = xPropSet->getPropertyValue("BracketAfter");
1613 aAny >>= sTmp;
1615
1616 aAny = xPropSet->getPropertyValue("IsNumberEntries");
1617 if (*o3tl::doAccess<bool>(aAny))
1618 {
1621 }
1622
1623 aAny = xPropSet->getPropertyValue("IsSortByPosition");
1624 if (! *o3tl::doAccess<bool>(aAny))
1625 {
1628 }
1629
1630 // sort algorithm
1631 aAny = xPropSet->getPropertyValue("SortAlgorithm");
1632 OUString sAlgorithm;
1633 aAny >>= sAlgorithm;
1634 if( !sAlgorithm.isEmpty() )
1635 {
1637 XML_SORT_ALGORITHM, sAlgorithm );
1638 }
1639
1640 // locale
1641 aAny = xPropSet->getPropertyValue("Locale");
1642 Locale aLocale;
1643 aAny >>= aLocale;
1645
1646 // configuration element
1649 true, true);
1650
1651 // sort keys
1652 aAny = xPropSet->getPropertyValue("SortKeys");
1653 Sequence<Sequence<PropertyValue> > aKeys;
1654 aAny >>= aKeys;
1655 for(const Sequence<PropertyValue> & rKey : std::as_const(aKeys))
1656 {
1657 for(const PropertyValue& rValue : rKey)
1658 {
1659 if (rValue.Name == "SortKey")
1660 {
1661 sal_Int16 nKey = 0;
1662 rValue.Value >>= nKey;
1663 OUStringBuffer sBuf;
1664 if (SvXMLUnitConverter::convertEnum( sBuf, nKey,
1666 {
1668 sBuf.makeStringAndClear());
1669 }
1670 }
1671 else if (rValue.Name == "IsSortAscending")
1672 {
1673 bool bTmp = *o3tl::doAccess<bool>(rValue.Value);
1676 bTmp ? XML_TRUE : XML_FALSE);
1677 }
1678 }
1679
1680 SvXMLElementExport aKeyElem(rExport,
1682 true, true);
1683 }
1684}
1685
1686
1688 const Reference<XTextSection> & rSection) const
1689{
1690 bool bRet = false;
1691
1692 // a section is mute if
1693 // 1) it exists
1694 // 2) the SaveLinkedSections flag (at the export) is false
1695 // 3) the IsGlobalDocumentSection property is true
1696 // 4) it is not an Index
1697
1698 if ( (!rExport.IsSaveLinkedSections()) && rSection.is() )
1699 {
1700 // walk the section chain and set bRet if any is linked
1701 for(Reference<XTextSection> aSection(rSection);
1702 aSection.is();
1703 aSection = aSection->getParentSection())
1704 {
1705 // check if it is a global document section (linked or index)
1706 Reference<XPropertySet> xPropSet(aSection, UNO_QUERY);
1707 if (xPropSet.is())
1708 {
1709 Any aAny = xPropSet->getPropertyValue("IsGlobalDocumentSection");
1710
1711 if ( *o3tl::doAccess<bool>(aAny) )
1712 {
1713 Reference<XDocumentIndex> xIndex;
1714 if (! GetIndex(rSection, xIndex))
1715 {
1716 bRet = true;
1717
1718 // early out if result is known
1719 break;
1720 }
1721 }
1722 }
1723 // section has no properties: ignore
1724 }
1725 }
1726 // else: no section, or always save sections: default (false)
1727
1728 return bRet;
1729}
1730
1732 const Reference<XTextContent> & rSection,
1733 bool bDefault) const
1734{
1735 // default: like default argument
1736 bool bRet = bDefault;
1737
1738 Reference<XPropertySet> xPropSet(rSection->getAnchor(), UNO_QUERY);
1739 if (xPropSet.is())
1740 {
1741 if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1742 {
1743 Any aAny = xPropSet->getPropertyValue("TextSection");
1744 Reference<XTextSection> xSection;
1745 aAny >>= xSection;
1746
1747 bRet = IsMuteSection(xSection);
1748 }
1749 // else: return default
1750 }
1751 // else: return default
1752
1753 return bRet;
1754}
1755
1757 const Reference<XTextSection> & rEnclosingSection,
1758 const Reference<XTextContent> & rContent,
1759 bool bDefault)
1760{
1761 // default: like default argument
1762 bool bRet = bDefault;
1763 OSL_ENSURE(rEnclosingSection.is(), "enclosing section expected");
1764
1765 Reference<XPropertySet> xPropSet(rContent, UNO_QUERY);
1766 if (xPropSet.is())
1767 {
1768 if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1769 {
1770 Any aAny = xPropSet->getPropertyValue("TextSection");
1771 Reference<XTextSection> xSection;
1772 aAny >>= xSection;
1773
1774 // now walk chain of text sections (if we have one)
1775 if (xSection.is())
1776 {
1777 do
1778 {
1779 bRet = (rEnclosingSection == xSection);
1780 xSection = xSection->getParentSection();
1781 }
1782 while (!bRet && xSection.is());
1783 }
1784 else
1785 bRet = false; // no section -> can't be inside
1786 }
1787 // else: no TextSection property -> return default
1788 }
1789 // else: no XPropertySet -> return default
1790
1791 return bRet;
1792}
1793
1794
1796{
1798 return;
1799
1800 Reference< XChapterNumberingSupplier > xCNSupplier( rExport.GetModel(),
1801 UNO_QUERY );
1802
1803 Reference< XIndexReplace > xChapterNumbering;
1804 if( xCNSupplier.is() )
1805 xChapterNumbering = xCNSupplier->getChapterNumberingRules();
1806
1807 if( !xChapterNumbering.is() )
1808 return;
1809
1810 sal_Int32 nCount = xChapterNumbering->getCount();
1811 for( sal_Int32 nLevel = 0; nLevel < nCount; nLevel++ )
1812 {
1813 OUString sStyle;
1814 Sequence<PropertyValue> aProperties;
1815 xChapterNumbering->getByIndex( nLevel ) >>= aProperties;
1816 auto pProp = std::find_if(std::cbegin(aProperties), std::cend(aProperties),
1817 [](const PropertyValue& rProp) { return rProp.Name == "HeadingStyleName"; });
1818 if (pProp != std::cend(aProperties))
1819 pProp->Value >>= sStyle;
1820
1821 if( !sStyle.isEmpty() )
1822 {
1824 GetExport().EncodeStyleName( sStyle ) );
1825
1827 OUString::number( nLevel + 1 ) );
1829 true, false );
1830 }
1831 }
1832
1834}
1835
1836/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
PropertiesInfo aProperties
const XMLTokenEnum aLevelNameAlphaMap[]
static const char * aLevelStylePropNameTOCMap[]
SvXMLEnumStringMapEntry< TemplateParamEnum > const aTemplateParamMap[]
const XMLTokenEnum aLevelNameBibliographyMap[]
static const char * aLevelStylePropNameTableMap[]
SvXMLEnumStringMapEntry< TemplateTypeEnum > const aTemplateTypeMap[]
const XMLTokenEnum aTypeSourceElementNameMap[]
SvXMLEnumStringMapEntry< SectionTypeEnum > const aIndexTypeMap[]
static const char ** aTypeLevelStylePropNameMap[]
static const char * aLevelStylePropNameBibliographyMap[]
const XMLTokenEnum aTypeLevelAttrMap[]
const XMLTokenEnum aLevelNameTableMap[]
SvXMLEnumMapEntry< sal_Int16 > const aBibliographyDataFieldMap[]
const XMLTokenEnum aLevelNameTOCMap[]
const XMLTokenEnum aTypeElementNameMap[]
static const XMLTokenEnum * aTypeLevelNameMap[]
static const char * aLevelStylePropNameAlphaMap[]
SectionTypeEnum
@ TEXT_SECTION_TYPE_ALPHABETICAL
@ TEXT_SECTION_TYPE_BIBLIOGRAPHY
@ TEXT_SECTION_TYPE_OBJECT
@ TEXT_SECTION_TYPE_ILLUSTRATION
@ TEXT_SECTION_TYPE_TABLE
@ TEXT_SECTION_TYPE_UNKNOWN
@ TEXT_SECTION_TYPE_USER
@ TEXT_SECTION_TYPE_TOC
const Any & any
const SvXMLNamespaceMap & GetNamespaceMap() const
Definition: xmlexp.hxx:385
void AddAttributeXmlId(css::uno::Reference< css::uno::XInterface > const &i_xIfc)
add xml:id attribute (for RDF metadata)
Definition: xmlexp.cxx:2290
void StartElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
Definition: xmlexp.cxx:2091
void AddAttribute(sal_uInt16 nPrefix, const OUString &rName, const OUString &rValue)
Definition: xmlexp.cxx:907
void Characters(const OUString &rChars)
Definition: xmlexp.cxx:2126
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:411
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2264
void IgnorableWhitespace()
Definition: xmlexp.cxx:2187
void CheckAttrList()
Definition: xmlexp.cxx:1012
void AddLanguageTagAttributes(sal_uInt16 nPrefix, sal_uInt16 nPrefixRfc, const css::lang::Locale &rLocale, bool bWriteEmpty)
Add language tag attributes, deciding which are necessary.
Definition: xmlexp.cxx:941
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlexp.hxx:391
void EndElement(sal_uInt16 nPrefix, enum ::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
Definition: xmlexp.cxx:2148
bool IsSaveLinkedSections() const
Definition: xmlexp.hxx:470
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
static bool convertEnum(EnumT &rEnum, std::u16string_view rValue, const SvXMLEnumMapEntry< EnumT > *pMap)
convert string to enum using given enum map, if the enum is not found in the map, this method will re...
Definition: xmluconv.hxx:145
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
convert measure to string: from meCoreMeasureUnit to meXMLMeasureUnit
Definition: xmluconv.cxx:208
XMLTextParagraphExport & GetParaExport()
void ExportLevelParagraphStyles(css::uno::Reference< css::container::XIndexReplace > const &xStyles)
export level paragraph styles
void ExportSectionStart(const css::uno::Reference< css::text::XTextSection > &rSection, bool bAutoStyles)
export section or index start and source elements.
void ExportUserIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a user index (and source element)
static enum SectionTypeEnum MapSectionType(std::u16string_view rSectionName)
map service name to section type
static bool IsInSection(const css::uno::Reference< css::text::XTextSection > &rEnclosingSection, const css::uno::Reference< css::text::XTextContent > &rContent, bool bDefault)
Determine whether rContent is contained in rEnclosingSection.
void ExportSectionEnd(const css::uno::Reference< css::text::XTextSection > &rSection, bool bAutoStyles)
export section or index end elements
void ExportBibliographyStart(const css::uno::Reference< css::beans::XPropertySet > &rIndex)
export the bibliography (and source element)
void ExportBaseIndexStart(::xmloff::token::XMLTokenEnum eElement, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index element start (for all index types).
void ExportObjectIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an object index (and source element)
XMLSectionExport(SvXMLExport &rExp, XMLTextParagraphExport &rParaExp)
void ExportTableOfContentStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a table of content (and source element)
void ExportTableIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a table index (and source element)
void ExportBoolean(const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const OUString &sPropertyName, enum ::xmloff::token::XMLTokenEnum eAttributeName, bool bDefault, bool bInvert=false)
helper to export boolean properties
void ExportBaseIndexBody(SectionTypeEnum eType, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index body (common for all index types).
void ExportIndexTemplateElement(SectionTypeEnum eType, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
export a single template element (e.g. span or tab-stop)
void ExportMasterDocHeadingDummies()
export a heading for every level.
void ExportRegularSectionStart(const css::uno::Reference< css::text::XTextSection > &rSection)
export a proper section (and source elements)
void ExportAlphabeticalIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an alphabetical/keyword index (and source element)
void ExportTableAndIllustrationIndexSourceAttributes(const css::uno::Reference< css::beans::XPropertySet > &rSection)
Helper method to export common attributes for table and illustration indices.
static bool GetIndex(const css::uno::Reference< css::text::XTextSection > &rSection, css::uno::Reference< css::text::XDocumentIndex > &rIndex)
If this section is an index, the index is written in the rIndex parameter.
SvXMLExport & rExport
void ExportIndexHeaderStart(const css::uno::Reference< css::text::XTextSection > &rSection)
export an index header start element.
static void ExportBibliographyConfiguration(SvXMLExport &rExport)
Export the configuration element for bibliography indices.
SvXMLExport & GetExport()
void ExportBaseIndexSource(SectionTypeEnum eType, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index source element (common for all index types).
void ExportIndexStart(const css::uno::Reference< css::text::XDocumentIndex > &rSection)
export an index start element.
bool ExportIndexTemplate(SectionTypeEnum eType, sal_Int32 nLevel, const css::uno::Reference< css::beans::XPropertySet > &rPropSet, const css::uno::Sequence< css::uno::Sequence< css::beans::PropertyValue > > &rValues)
export one template for the specific index type
bool IsMuteSection(const css::uno::Reference< css::text::XTextSection > &rSection) const
Should the content of this section be exported? (E.g.
void ExportIllustrationIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an illustration index (and source element)
static enum::xmloff::token::XMLTokenEnum MapChapterDisplayFormat(sal_Int16 nType)
map ChapterDisplayFormat to XML string
Definition: txtflde.cxx:3023
static enum::xmloff::token::XMLTokenEnum MapReferenceType(sal_Int16 nType)
map ReferenceFieldPart to XML string
Definition: txtflde.cxx:3082
void Add(XmlStyleFamily nFamily, MultiPropertySetHelper &rPropSetHelper, const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
add autostyle for specified family
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
int nCount
float u
DocumentType eType
int i
Handling of tokens in XML:
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:50
@ XML_BIBLIOGRAPHY_DATA_FIELD
Definition: xmltoken.hxx:329
@ XML_ILLUSTRATION_INDEX
Definition: xmltoken.hxx:1073
@ XML_MAIN_ENTRY_STYLE_NAME
Definition: xmltoken.hxx:1242
@ XML_INDEX_ENTRY_TAB_STOP
Definition: xmltoken.hxx:1094
@ XML_USE_FLOATING_FRAMES
Definition: xmltoken.hxx:2070
@ XML_COMBINE_ENTRIES_WITH_PP
Definition: xmltoken.hxx:478
@ XML_TABLE_INDEX_SOURCE
Definition: xmltoken.hxx:1924
@ XML_COPY_OUTLINE_LEVELS
Definition: xmltoken.hxx:523
@ XML_RELATIVE_TAB_STOP_POSITION
Definition: xmltoken.hxx:1623
@ XML_BIBLIOGRAPHY_CONFIGURATION
Definition: xmltoken.hxx:328
@ XML_CAPTION_SEQUENCE_FORMAT
Definition: xmltoken.hxx:397
@ XML_INDEX_ENTRY_BIBLIOGRAPHY
Definition: xmltoken.hxx:1087
@ XML_USE_KEYS_AS_ENTRIES
Definition: xmltoken.hxx:2075
@ XML_AUTOMATIC_UPDATE
Definition: xmltoken.hxx:304
@ XML_ILLUSTRATION_INDEX_SOURCE
Definition: xmltoken.hxx:1075
@ XML_INDEX_ENTRY_LINK_START
Definition: xmltoken.hxx:1091
@ XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE
Definition: xmltoken.hxx:238
@ XML_INDEX_SOURCE_STYLES
Definition: xmltoken.hxx:1100
@ XML_BIBLIOGRAPHY_ENTRY_TEMPLATE
Definition: xmltoken.hxx:330
@ XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE
Definition: xmltoken.hxx:1074
@ XML_INDEX_TITLE_TEMPLATE
Definition: xmltoken.hxx:1102
@ XML_TABLE_OF_CONTENT_ENTRY_TEMPLATE
Definition: xmltoken.hxx:1927
@ XML_INDEX_SOURCE_STYLE
Definition: xmltoken.hxx:1099
@ XML_INDEX_ENTRY_PAGE_NUMBER
Definition: xmltoken.hxx:1092
@ XML_OBJECT_INDEX_ENTRY_TEMPLATE
Definition: xmltoken.hxx:1426
@ XML_PROTECTION_KEY_DIGEST_ALGORITHM
Definition: xmltoken.hxx:1575
@ XML_BIBLIOGRAPHY_SOURCE
Definition: xmltoken.hxx:332
@ XML_OBJECT_INDEX_SOURCE
Definition: xmltoken.hxx:1427
@ XML_INDEX_ENTRY_CHAPTER
Definition: xmltoken.hxx:1088
@ XML_USE_INDEX_SOURCE_STYLES
Definition: xmltoken.hxx:2074
@ XML_ALPHABETICAL_INDEX
Definition: xmltoken.hxx:236
@ XML_TABLE_OF_CONTENT_SOURCE
Definition: xmltoken.hxx:1928
@ XML_BIBLIOGRAPHY_TYPE
Definition: xmltoken.hxx:333
@ XML_CAPITALIZE_ENTRIES
Definition: xmltoken.hxx:392
@ XML_CAPTION_SEQUENCE_NAME
Definition: xmltoken.hxx:398
@ XML_ALPHABETICAL_INDEX_SOURCE
Definition: xmltoken.hxx:242
@ XML_INDEX_ENTRY_LINK_END
Definition: xmltoken.hxx:1090
@ XML_USER_INDEX_ENTRY_TEMPLATE
Definition: xmltoken.hxx:2093
@ XML_COMBINE_ENTRIES_WITH_DASH
Definition: xmltoken.hxx:477
@ XML_ALPHABETICAL_SEPARATORS
Definition: xmltoken.hxx:243
@ XML_TABLE_INDEX_ENTRY_TEMPLATE
Definition: xmltoken.hxx:1923
@ XML_USE_SPREADSHEET_OBJECTS
Definition: xmltoken.hxx:2082
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3541
DefTokenId nToken
QPRO_FUNC_TYPE nType
OReadStatusBarDocumentHandler::StatusBar_XML_Namespace nNamespace
Map a const char* (with length) to a sal_uInt16 value.
Definition: xmlement.hxx:71
std::unique_ptr< char[]> aBuffer
#define ENUM_STRING_MAP_ENTRY(name, tok)
Definition: xmlement.hxx:62
constexpr sal_uInt16 XML_NAMESPACE_XLINK
constexpr sal_uInt16 XML_NAMESPACE_TEXT
constexpr sal_uInt16 XML_NAMESPACE_OOOW
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
constexpr sal_uInt16 XML_NAMESPACE_STYLE
constexpr sal_uInt16 XML_NAMESPACE_FO