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>
44 #include <xmloff/xmlnmspe.hxx>
45 #include <xmloff/families.hxx>
46 #include <xmloff/xmluconv.hxx>
47 #include <xmloff/nmspmap.hxx>
48 #include <xmloff/xmlexp.hxx>
49 #include <xmloff/xmlement.hxx>
50 #include <txtflde.hxx>
51 
52 
53 using namespace ::com::sun::star;
54 using namespace ::com::sun::star::text;
55 using namespace ::com::sun::star::uno;
56 using namespace ::std;
57 using namespace ::xmloff::token;
58 
59 using ::com::sun::star::beans::XPropertySet;
60 using ::com::sun::star::beans::PropertyValue;
61 using ::com::sun::star::beans::PropertyValues;
62 using ::com::sun::star::container::XIndexReplace;
63 using ::com::sun::star::container::XNameAccess;
64 using ::com::sun::star::container::XNamed;
65 using ::com::sun::star::lang::Locale;
66 
67 
69  SvXMLExport& rExp,
70  XMLTextParagraphExport& rParaExp)
71 : rExport(rExp)
72 , rParaExport(rParaExp)
73 , bHeadingDummiesExported( false )
74 {
75 }
76 
77 
79  const Reference<XTextSection> & rSection,
80  bool bAutoStyles)
81 {
82  Reference<XPropertySet> xPropertySet(rSection, UNO_QUERY);
83 
84  // always export section (auto) style
85  if (bAutoStyles)
86  {
87  // get PropertySet and add section style
89  }
90  else
91  {
92  // always export section style
94  GetParaExport().Find(
96  xPropertySet, "" ) );
97 
98  // xml:id for RDF metadata
99  GetExport().AddAttributeXmlId(rSection);
100 
101  // export index or regular section
102  Reference<XDocumentIndex> xIndex;
103  if (GetIndex(rSection, xIndex))
104  {
105  if (xIndex.is())
106  {
107  // we are an index
108  ExportIndexStart(xIndex);
109  }
110  else
111  {
112  // we are an index header
113  ExportIndexHeaderStart(rSection);
114  }
115  }
116  else
117  {
118  // we are not an index
119  ExportRegularSectionStart(rSection);
120  }
121  }
122 }
123 
125  const Reference<XTextSection> & rSection,
126  Reference<XDocumentIndex> & rIndex)
127 {
128  // first, reset result
129  bool bRet = false;
130  rIndex = nullptr;
131 
132  // get section Properties
133  Reference<XPropertySet> xSectionPropSet(rSection, UNO_QUERY);
134 
135  // then check if this section happens to be inside an index
136  if (xSectionPropSet->getPropertySetInfo()->
137  hasPropertyByName("DocumentIndex"))
138  {
139  Any aAny = xSectionPropSet->getPropertyValue("DocumentIndex");
140  Reference<XDocumentIndex> xDocumentIndex;
141  aAny >>= xDocumentIndex;
142 
143  // OK, are we inside of an index
144  if (xDocumentIndex.is())
145  {
146  // is the enclosing index identical with "our" section?
147  Reference<XPropertySet> xIndexPropSet(xDocumentIndex, UNO_QUERY);
148  aAny = xIndexPropSet->getPropertyValue("ContentSection");
149  Reference<XTextSection> xEnclosingSection;
150  aAny >>= xEnclosingSection;
151 
152  // if the enclosing section is "our" section, then we are an index!
153  if (rSection == xEnclosingSection)
154  {
155  rIndex = xDocumentIndex;
156  bRet = true;
157  }
158  // else: index header or regular section
159 
160  // is the enclosing index identical with the header section?
161  aAny = xIndexPropSet->getPropertyValue("HeaderSection");
162  // now mis-named: contains header section
163  aAny >>= xEnclosingSection;
164 
165  // if the enclosing section is "our" section, then we are an index!
166  if (rSection == xEnclosingSection)
167  {
168  bRet = true;
169  }
170  // else: regular section
171  }
172  // else: we aren't even inside of an index
173  }
174  // else: we don't even know what an index is.
175 
176  return bRet;
177 }
178 
179 
181  const Reference<XTextSection> & rSection,
182  bool bAutoStyles)
183 {
184  // no end section for styles
185  if (!bAutoStyles)
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  }
260  // else: autostyles -> ignore
261 }
262 
264  const Reference<XDocumentIndex> & rIndex)
265 {
266  // get PropertySet
267  Reference<XPropertySet> xPropertySet(rIndex, UNO_QUERY);
268 
269  switch (MapSectionType(rIndex->getServiceName()))
270  {
272  ExportTableOfContentStart(xPropertySet);
273  break;
274 
276  ExportIllustrationIndexStart(xPropertySet);
277  break;
278 
280  ExportAlphabeticalIndexStart(xPropertySet);
281  break;
282 
284  ExportTableIndexStart(xPropertySet);
285  break;
286 
288  ExportObjectIndexStart(xPropertySet);
289  break;
290 
292  ExportUserIndexStart(xPropertySet);
293  break;
294 
296  ExportBibliographyStart(xPropertySet);
297  break;
298 
299  default:
300  // skip index
301  OSL_FAIL("unknown index type");
302  break;
303  }
304 }
305 
307  const Reference<XTextSection> & rSection)
308 {
309  // export name, dammit!
310  Reference<XNamed> xName(rSection, UNO_QUERY);
311  GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
312 
313  // format already handled -> export only start element
316 }
317 
318 
320 {
321  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ContentIndex", TEXT_SECTION_TYPE_TOC ),
322  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.DocumentIndex", TEXT_SECTION_TYPE_ALPHABETICAL ),
323  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.TableIndex", TEXT_SECTION_TYPE_TABLE ),
324  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.ObjectIndex", TEXT_SECTION_TYPE_OBJECT ),
325  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.Bibliography", TEXT_SECTION_TYPE_BIBLIOGRAPHY ),
326  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.UserIndex", TEXT_SECTION_TYPE_USER ),
327  ENUM_STRING_MAP_ENTRY( "com.sun.star.text.IllustrationsIndex", TEXT_SECTION_TYPE_ILLUSTRATION ),
328  { nullptr, 0, SectionTypeEnum(0) }
329 };
330 
332  const OUString& rServiceName)
333 {
335 
336  SvXMLUnitConverter::convertEnum(eType, rServiceName, aIndexTypeMap);
337 
338  // TODO: index header section types, etc.
339 
340  return eType;
341 }
342 
344  const Reference<XTextSection> & rSection)
345 {
346  // style name already handled in ExportSectionStart(...)
347 
348  Reference<XNamed> xName(rSection, UNO_QUERY);
349  GetExport().AddAttribute(XML_NAMESPACE_TEXT, XML_NAME, xName->getName());
350 
351  // get XPropertySet for other values
352  Reference<XPropertySet> xPropSet(rSection, UNO_QUERY);
353 
354  // condition and display
355  Any aAny = xPropSet->getPropertyValue("Condition");
356  OUString sCond;
357  aAny >>= sCond;
358  enum XMLTokenEnum eDisplay = XML_TOKEN_INVALID;
359  if (!sCond.isEmpty())
360  {
361  OUString sQValue =
363  sCond, false );
365  eDisplay = XML_CONDITION;
366 
367  // #97450# store hidden-status (of conditional sections only)
368  aAny = xPropSet->getPropertyValue("IsCurrentlyVisible");
369  if (! *o3tl::doAccess<bool>(aAny))
370  {
372  XML_TRUE);
373  }
374  }
375  else
376  {
377  eDisplay = XML_NONE;
378  }
379  aAny = xPropSet->getPropertyValue("IsVisible");
380  if (! *o3tl::doAccess<bool>(aAny))
381  {
383  }
384 
385  // protect + protection key
386  aAny = xPropSet->getPropertyValue("IsProtected");
387  if (*o3tl::doAccess<bool>(aAny))
388  {
390  }
391  Sequence<sal_Int8> aPassword;
392  xPropSet->getPropertyValue("ProtectionKey") >>= aPassword;
393  if (aPassword.hasElements())
394  {
395  OUStringBuffer aBuffer;
396  ::comphelper::Base64::encode(aBuffer, aPassword);
397  // in ODF 1.0/1.1 the algorithm was left unspecified so we can write anything
399  aBuffer.makeStringAndClear());
400  if (aPassword.getLength() == 32 && GetExport().getSaneDefaultVersion() >= SvtSaveOptions::ODFSVER_012)
401  {
402  // attribute exists in ODF 1.2 or later; default is SHA1 so no need to write that
404  // write the URL from ODF 1.2, not the W3C one
405  "http://www.w3.org/2000/09/xmldsig#sha256");
406  }
407  }
408 
409  // export element
412 
413  // data source
414  // unfortunately, we have to test all relevant strings for non-zero length
415  aAny = xPropSet->getPropertyValue("FileLink");
416  SectionFileLink aFileLink;
417  aAny >>= aFileLink;
418 
419  aAny = xPropSet->getPropertyValue("LinkRegion");
420  OUString sRegionName;
421  aAny >>= sRegionName;
422 
423  if ( !aFileLink.FileURL.isEmpty() ||
424  !aFileLink.FilterName.isEmpty() ||
425  !sRegionName.isEmpty())
426  {
427  if (!aFileLink.FileURL.isEmpty())
428  {
430  GetExport().GetRelativeReference( aFileLink.FileURL) );
431  }
432 
433  if (!aFileLink.FilterName.isEmpty())
434  {
436  aFileLink.FilterName);
437  }
438 
439  if (!sRegionName.isEmpty())
440  {
442  sRegionName);
443  }
444 
447  true, true);
448  }
449  else
450  {
451  // check for DDE first
452  if (xPropSet->getPropertySetInfo()->hasPropertyByName("DDECommandFile"))
453  {
454  // data source DDE
455  // unfortunately, we have to test all relevant strings for
456  // non-zero length
457  aAny = xPropSet->getPropertyValue("DDECommandFile");
458  OUString sApplication;
459  aAny >>= sApplication;
460  aAny = xPropSet->getPropertyValue("DDECommandType");
461  OUString sTopic;
462  aAny >>= sTopic;
463  aAny = xPropSet->getPropertyValue("DDECommandElement");
464  OUString sItem;
465  aAny >>= sItem;
466 
467  if ( !sApplication.isEmpty() ||
468  !sTopic.isEmpty() ||
469  !sItem.isEmpty())
470  {
472  XML_DDE_APPLICATION, sApplication);
474  sTopic);
476  sItem);
477 
478  aAny = xPropSet->getPropertyValue("IsAutomaticUpdate");
479  if (*o3tl::doAccess<bool>(aAny))
480  {
483  }
484 
487  XML_DDE_SOURCE, true, true);
488  }
489  // else: no DDE data source
490  }
491  // else: no DDE on this system
492  }
493 }
494 
496  const Reference<XPropertySet> & rPropertySet)
497 {
498  // export TOC element start
500 
501  // scope for table-of-content-source element
502  {
503  // TOC specific index source attributes:
504 
505  // outline-level: 1..10
506  sal_Int16 nLevel = sal_Int16();
507  if( rPropertySet->getPropertyValue("Level") >>= nLevel )
508  {
511  OUString::number(nLevel));
512  }
513 
514  // use outline level
515  ExportBoolean(rPropertySet, "CreateFromOutline",
516  XML_USE_OUTLINE_LEVEL, true);
517 
518  // use index marks
519  ExportBoolean(rPropertySet, "CreateFromMarks",
520  XML_USE_INDEX_MARKS, true);
521 
522  // use level styles
523  ExportBoolean(rPropertySet, "CreateFromLevelParagraphStyles",
525 
527  }
528 
530 }
531 
533  const Reference<XPropertySet> & rPropertySet)
534 {
535  // export index start
536  ExportBaseIndexStart(XML_OBJECT_INDEX, rPropertySet);
537 
538  // scope for index source element
539  {
540  ExportBoolean(rPropertySet, "CreateFromOtherEmbeddedObjects",
541  XML_USE_OTHER_OBJECTS, false);
542  ExportBoolean(rPropertySet, "CreateFromStarCalc",
544  ExportBoolean(rPropertySet, "CreateFromStarChart",
545  XML_USE_CHART_OBJECTS, false);
546  ExportBoolean(rPropertySet, "CreateFromStarDraw",
547  XML_USE_DRAW_OBJECTS, false);
548  ExportBoolean(rPropertySet, "CreateFromStarMath",
549  XML_USE_MATH_OBJECTS, false);
550 
552  }
553 
555 }
556 
558  const Reference<XPropertySet> & rPropertySet)
559 {
560  // export index start
562 
563  // scope for index source element
564  {
565  // export common attributes for illustration and table indices
567 
569  }
570 
572 }
573 
575  const Reference<XPropertySet> & rPropertySet)
576 {
577  // export index start
578  ExportBaseIndexStart(XML_TABLE_INDEX, rPropertySet);
579 
580  // scope for index source element
581  {
582  // export common attributes for illustration and table indices
584 
586  }
587 
589 }
590 
592  const Reference<XPropertySet> & rPropertySet)
593 {
594  // export TOC element start
596 
597  // scope for table-of-content-source element
598  {
599 
600  // style name (if present)
601  Any aAny = rPropertySet->getPropertyValue("MainEntryCharacterStyleName");
602  OUString sStyleName;
603  aAny >>= sStyleName;
604  if (!sStyleName.isEmpty())
605  {
608  GetExport().EncodeStyleName( sStyleName ));
609  }
610 
611  // other (boolean) attributes
612  ExportBoolean(rPropertySet, "IsCaseSensitive", XML_IGNORE_CASE,
613  false, true);
614  ExportBoolean(rPropertySet, "UseAlphabeticalSeparators",
616  ExportBoolean(rPropertySet, "UseCombinedEntries", XML_COMBINE_ENTRIES,
617  true);
618  ExportBoolean(rPropertySet, "UseDash", XML_COMBINE_ENTRIES_WITH_DASH,
619  false);
620  ExportBoolean(rPropertySet, "UseKeyAsEntry", XML_USE_KEYS_AS_ENTRIES,
621  false);
622  ExportBoolean(rPropertySet, "UsePP", XML_COMBINE_ENTRIES_WITH_PP,
623  true);
624  ExportBoolean(rPropertySet, "UseUpperCase", XML_CAPITALIZE_ENTRIES,
625  false);
626  ExportBoolean(rPropertySet, "IsCommaSeparated", XML_COMMA_SEPARATED,
627  false);
628 
629  // sort algorithm
630  aAny = rPropertySet->getPropertyValue("SortAlgorithm");
631  OUString sAlgorithm;
632  aAny >>= sAlgorithm;
633  if (!sAlgorithm.isEmpty())
634  {
636  sAlgorithm );
637  }
638 
639  // locale
640  aAny = rPropertySet->getPropertyValue("Locale");
641  Locale aLocale;
642  aAny >>= aLocale;
644 
646  }
647 
649 }
650 
652  const Reference<XPropertySet> & rPropertySet)
653 {
654  // export TOC element start
655  ExportBaseIndexStart(XML_USER_INDEX, rPropertySet);
656 
657  // scope for table-of-content-source element
658  {
659  // bool attributes
660  ExportBoolean(rPropertySet, "CreateFromEmbeddedObjects",
661  XML_USE_OBJECTS, false);
662  ExportBoolean(rPropertySet, "CreateFromGraphicObjects",
663  XML_USE_GRAPHICS, false);
664  ExportBoolean(rPropertySet, "CreateFromMarks",
665  XML_USE_INDEX_MARKS, false);
666  ExportBoolean(rPropertySet, "CreateFromTables",
667  XML_USE_TABLES, false);
668  ExportBoolean(rPropertySet, "CreateFromTextFrames",
669  XML_USE_FLOATING_FRAMES, false);
670  ExportBoolean(rPropertySet, "UseLevelFromSource",
671  XML_COPY_OUTLINE_LEVELS, false);
672  ExportBoolean(rPropertySet, "CreateFromLevelParagraphStyles",
674 
675  Any aAny = rPropertySet->getPropertyValue( "UserIndexName" );
676  OUString sIndexName;
677  aAny >>= sIndexName;
679  sIndexName);
680 
682  }
683 
685 }
686 
688  const Reference<XPropertySet> & rPropertySet)
689 {
690  // export TOC element start
691  ExportBaseIndexStart(XML_BIBLIOGRAPHY, rPropertySet);
692 
693  // scope for table-of-content-source element
694  {
695  // No attributes. Fine.
696 
698  }
699 
701 }
702 
703 
705  XMLTokenEnum eElement,
706  const Reference<XPropertySet> & rPropertySet)
707 {
708  // protect + protection key
709  Any aAny = rPropertySet->getPropertyValue("IsProtected");
710  if (*o3tl::doAccess<bool>(aAny))
711  {
713  }
714 
715  // index name
716  OUString sIndexName;
717  rPropertySet->getPropertyValue("Name") >>= sIndexName;
718  if ( !sIndexName.isEmpty() )
719  {
721  }
722 
723  // index Element start
725  GetExport().StartElement( XML_NAMESPACE_TEXT, eElement, false );
726 }
727 
729 {
731  XML_TABLE_INDEX_SOURCE, // table index
732  XML_ILLUSTRATION_INDEX_SOURCE, // illustration index
733  XML_OBJECT_INDEX_SOURCE, // object index
734  XML_USER_INDEX_SOURCE, // user index
735  XML_ALPHABETICAL_INDEX_SOURCE, // alphabetical index
736  XML_BIBLIOGRAPHY_SOURCE // bibliography
737 };
738 
740  SectionTypeEnum eType,
741  const Reference<XPropertySet> & rPropertySet)
742 {
743  // check type
744  OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
745  OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
746 
747  Any aAny;
748 
749  // common attributes; not supported by bibliography
750  if (eType != TEXT_SECTION_TYPE_BIBLIOGRAPHY)
751  {
752  // document or chapter index?
753  aAny = rPropertySet->getPropertyValue("CreateFromChapter");
754  if (*o3tl::doAccess<bool>(aAny))
755  {
758  }
759 
760  // tab-stops relative to margin?
761  aAny = rPropertySet->getPropertyValue("IsRelativeTabstops");
762  if (! *o3tl::doAccess<bool>(aAny))
763  {
766  XML_FALSE);
767  }
768  }
769 
770  // the index source element (all indices)
773  GetXMLToken(
775  eType - TEXT_SECTION_TYPE_TOC]),
776  true, true);
777 
778  // scope for title template (all indices)
779  {
780  // header style name
781  aAny = rPropertySet->getPropertyValue("ParaStyleHeading");
782  OUString sStyleName;
783  aAny >>= sStyleName;
786  GetExport().EncodeStyleName( sStyleName ));
787 
788  // title template
789  SvXMLElementExport aHeaderTemplate(GetExport(),
792  true, false);
793 
794  // title as element content
795  aAny = rPropertySet->getPropertyValue("Title");
796  OUString sTitleString;
797  aAny >>= sTitleString;
798  GetExport().Characters(sTitleString);
799  }
800 
801  // export level templates (all indices)
802  aAny = rPropertySet->getPropertyValue("LevelFormat");
803  Reference<XIndexReplace> xLevelTemplates;
804  aAny >>= xLevelTemplates;
805 
806  // iterate over level formats;
807  // skip element 0 (empty template for title)
808  sal_Int32 nLevelCount = xLevelTemplates->getCount();
809  for(sal_Int32 i = 1; i<nLevelCount; i++)
810  {
811  // get sequence
812  Sequence<PropertyValues> aTemplateSequence;
813  aAny = xLevelTemplates->getByIndex(i);
814  aAny >>= aTemplateSequence;
815 
816  // export the sequence (abort export if an error occurred; #91214#)
817  bool bResult =
818  ExportIndexTemplate(eType, i, rPropertySet, aTemplateSequence);
819  if ( !bResult )
820  break;
821  }
822 
823  // only TOC and user index:
824  // styles from which to build the index (LevelParagraphStyles)
825  if ( (TEXT_SECTION_TYPE_TOC == eType) ||
826  (TEXT_SECTION_TYPE_USER == eType) )
827  {
828  aAny = rPropertySet->getPropertyValue("LevelParagraphStyles");
829  Reference<XIndexReplace> xLevelParagraphStyles;
830  aAny >>= xLevelParagraphStyles;
831  ExportLevelParagraphStyles(xLevelParagraphStyles);
832  }
833 }
834 
835 
837  SectionTypeEnum eType,
838  const Reference<XPropertySet> &)
839 {
840  // type not used; checked anyway.
841  OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
842  OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
843 
844  // export start only
845 
846  // any old attributes?
848 
849  // start surrounded by whitespace
852 }
853 
855  const Reference<XPropertySet> & rPropertySet)
856 {
857  // use caption
858  Any aAny = rPropertySet->getPropertyValue("CreateFromLabels");
859  if (! *o3tl::doAccess<bool>(aAny))
860  {
863  }
864 
865  // sequence name
866  aAny = rPropertySet->getPropertyValue("LabelCategory");
867  OUString sSequenceName;
868  aAny >>= sSequenceName;
871  sSequenceName);
872 
873  // caption format
874  aAny = rPropertySet->getPropertyValue("LabelDisplayType");
875  sal_Int16 nType = 0;
876  aAny >>= nType;
880 }
881 
882 
883 // map index of LevelFormats to attribute value;
884 // level 0 is always the header
900 
902 {
903  aLevelNameTOCMap, // TOC
904  aLevelNameTableMap, // table index
905  aLevelNameTableMap, // illustration index
906  aLevelNameTableMap, // object index
907  aLevelNameTOCMap, // user index
908  aLevelNameAlphaMap, // alphabetical index
909  aLevelNameBibliographyMap // bibliography
910 };
911 
912 static const char* aLevelStylePropNameTOCMap[] =
913  { nullptr, "ParaStyleLevel1", "ParaStyleLevel2", "ParaStyleLevel3",
914  "ParaStyleLevel4", "ParaStyleLevel5", "ParaStyleLevel6",
915  "ParaStyleLevel7", "ParaStyleLevel8", "ParaStyleLevel9",
916  "ParaStyleLevel10", nullptr };
917 static const char* aLevelStylePropNameTableMap[] =
918  { nullptr, "ParaStyleLevel1", nullptr };
919 static const char* aLevelStylePropNameAlphaMap[] =
920  { nullptr, "ParaStyleSeparator", "ParaStyleLevel1", "ParaStyleLevel2",
921  "ParaStyleLevel3", nullptr };
923  // TODO: replace with real property names, when available
924  { nullptr, "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
925  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
926  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
927  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
928  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
929  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
930  "ParaStyleLevel1", "ParaStyleLevel1", "ParaStyleLevel1",
931  "ParaStyleLevel1",
932  nullptr };
933 
934 static const char** aTypeLevelStylePropNameMap[] =
935 {
937  aLevelStylePropNameTableMap, // table index
938  aLevelStylePropNameTableMap, // illustration index
939  aLevelStylePropNameTableMap, // object index
940  aLevelStylePropNameTOCMap, // user index
941  aLevelStylePropNameAlphaMap, // alphabetical index
942  aLevelStylePropNameBibliographyMap // bibliography
943 };
944 
946 {
947  XML_OUTLINE_LEVEL, // TOC
948  XML_TOKEN_INVALID, // table index
949  XML_TOKEN_INVALID, // illustration index
950  XML_TOKEN_INVALID, // object index
951  XML_OUTLINE_LEVEL, // user index
952  XML_OUTLINE_LEVEL, // alphabetical index
953  XML_BIBLIOGRAPHY_TYPE // bibliography
954 };
955 
957 {
959  XML_TABLE_INDEX_ENTRY_TEMPLATE, // table index
960  XML_ILLUSTRATION_INDEX_ENTRY_TEMPLATE, // illustration index
961  XML_OBJECT_INDEX_ENTRY_TEMPLATE, // object index
962  XML_USER_INDEX_ENTRY_TEMPLATE, // user index
963  XML_ALPHABETICAL_INDEX_ENTRY_TEMPLATE, // alphabetical index
964  XML_BIBLIOGRAPHY_ENTRY_TEMPLATE // bibliography
965 };
966 
967 
969  SectionTypeEnum eType,
970  sal_Int32 nOutlineLevel,
971  const Reference<XPropertySet> & rPropertySet,
972  const Sequence<Sequence<PropertyValue> > & rValues)
973 {
974  OSL_ENSURE(eType >= TEXT_SECTION_TYPE_TOC, "illegal index type");
975  OSL_ENSURE(eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY, "illegal index type");
976  OSL_ENSURE(nOutlineLevel >= 0, "illegal outline level");
977 
978  if ( (eType >= TEXT_SECTION_TYPE_TOC) &&
979  (eType <= TEXT_SECTION_TYPE_BIBLIOGRAPHY) &&
980  (nOutlineLevel >= 0) )
981  {
982  // get level name and level attribute name from aLevelNameMap;
983  const XMLTokenEnum eLevelAttrName(
985  const XMLTokenEnum eLevelName(
986  aTypeLevelNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
987 
988  // #92124#: some old documents may be broken, then they have
989  // too many template levels; we need to recognize this and
990  // export only as many as is legal for the respective index
991  // type. To do this, we simply return an error flag, which
992  // will then abort further template level exports.
993  OSL_ENSURE(XML_TOKEN_INVALID != eLevelName, "can't find level name");
994  if ( XML_TOKEN_INVALID == eLevelName )
995  {
996  // output level not found? Then end of templates! #91214#
997  return false;
998  }
999 
1000  // output level name
1001  if ((XML_TOKEN_INVALID != eLevelName) && (XML_TOKEN_INVALID != eLevelAttrName))
1002  {
1004  GetXMLToken(eLevelAttrName),
1005  GetXMLToken(eLevelName));
1006  }
1007 
1008  // paragraph level style name
1009  const char* pPropName(
1010  aTypeLevelStylePropNameMap[eType-TEXT_SECTION_TYPE_TOC][nOutlineLevel]);
1011  OSL_ENSURE(nullptr != pPropName, "can't find property name");
1012  if (nullptr != pPropName)
1013  {
1014  Any aAny = rPropertySet->getPropertyValue(
1015  OUString::createFromAscii(pPropName));
1016  OUString sParaStyleName;
1017  aAny >>= sParaStyleName;
1020  GetExport().EncodeStyleName( sParaStyleName ));
1021  }
1022 
1023  // template element
1024  const XMLTokenEnum eElementName(
1026  SvXMLElementExport aLevelTemplate(GetExport(),
1028  GetXMLToken(eElementName),
1029  true, true);
1030 
1031  // export sequence
1032  for(auto& rValue : rValues)
1033  {
1035  eType, //i90246
1036  rValue);
1037  }
1038  }
1039 
1040  return true;
1041 }
1042 
1043 namespace {
1044 
1046 {
1047  TOK_TTYPE_ENTRY_NUMBER,
1048  TOK_TTYPE_ENTRY_TEXT,
1049  TOK_TTYPE_TAB_STOP,
1050  TOK_TTYPE_TEXT,
1051  TOK_TTYPE_PAGE_NUMBER,
1052  TOK_TTYPE_CHAPTER_INFO,
1053  TOK_TTYPE_HYPERLINK_START,
1054  TOK_TTYPE_HYPERLINK_END,
1055  TOK_TTYPE_BIBLIOGRAPHY,
1056  TOK_TTYPE_INVALID
1057 };
1058 
1060 {
1061  TOK_TPARAM_TOKEN_TYPE,
1062  TOK_TPARAM_CHAR_STYLE,
1063  TOK_TPARAM_TAB_RIGHT_ALIGNED,
1064  TOK_TPARAM_TAB_POSITION,
1065  TOK_TPARAM_TAB_WITH_TAB, // #i21237#
1066  TOK_TPARAM_TAB_FILL_CHAR,
1067  TOK_TPARAM_TEXT,
1068  TOK_TPARAM_CHAPTER_FORMAT,
1069  TOK_TPARAM_CHAPTER_LEVEL,//i53420
1070  TOK_TPARAM_BIBLIOGRAPHY_DATA
1071 };
1072 
1073 }
1074 
1076 {
1077  ENUM_STRING_MAP_ENTRY( "TokenEntryNumber", TOK_TTYPE_ENTRY_NUMBER ),
1078  ENUM_STRING_MAP_ENTRY( "TokenEntryText", TOK_TTYPE_ENTRY_TEXT ),
1079  ENUM_STRING_MAP_ENTRY( "TokenTabStop", TOK_TTYPE_TAB_STOP ),
1080  ENUM_STRING_MAP_ENTRY( "TokenText", TOK_TTYPE_TEXT ),
1081  ENUM_STRING_MAP_ENTRY( "TokenPageNumber", TOK_TTYPE_PAGE_NUMBER ),
1082  ENUM_STRING_MAP_ENTRY( "TokenChapterInfo", TOK_TTYPE_CHAPTER_INFO ),
1083  ENUM_STRING_MAP_ENTRY( "TokenHyperlinkStart", TOK_TTYPE_HYPERLINK_START ),
1084  ENUM_STRING_MAP_ENTRY( "TokenHyperlinkEnd", TOK_TTYPE_HYPERLINK_END ),
1085  ENUM_STRING_MAP_ENTRY( "TokenBibliographyDataField", TOK_TTYPE_BIBLIOGRAPHY ),
1086  { nullptr, 0, TemplateTypeEnum(0)}
1087 };
1088 
1090 {
1091  ENUM_STRING_MAP_ENTRY( "TokenType", TOK_TPARAM_TOKEN_TYPE ),
1092  ENUM_STRING_MAP_ENTRY( "CharacterStyleName", TOK_TPARAM_CHAR_STYLE ),
1093  ENUM_STRING_MAP_ENTRY( "TabStopRightAligned", TOK_TPARAM_TAB_RIGHT_ALIGNED ),
1094  ENUM_STRING_MAP_ENTRY( "TabStopPosition", TOK_TPARAM_TAB_POSITION ),
1095  ENUM_STRING_MAP_ENTRY( "TabStopFillCharacter", TOK_TPARAM_TAB_FILL_CHAR ),
1096  // #i21237#
1097  ENUM_STRING_MAP_ENTRY( "WithTab", TOK_TPARAM_TAB_WITH_TAB ),
1098  ENUM_STRING_MAP_ENTRY( "Text", TOK_TPARAM_TEXT ),
1099  ENUM_STRING_MAP_ENTRY( "ChapterFormat", TOK_TPARAM_CHAPTER_FORMAT ),
1100  ENUM_STRING_MAP_ENTRY( "ChapterLevel", TOK_TPARAM_CHAPTER_LEVEL ),//i53420
1101  ENUM_STRING_MAP_ENTRY( "BibliographyDataField", TOK_TPARAM_BIBLIOGRAPHY_DATA ),
1102  { nullptr, 0, TemplateParamEnum(0)}
1103 };
1104 
1106 {
1107  { XML_ADDRESS, BibliographyDataField::ADDRESS },
1108  { XML_ANNOTE, BibliographyDataField::ANNOTE },
1109  { XML_AUTHOR, BibliographyDataField::AUTHOR },
1110  { XML_BIBLIOGRAPHY_TYPE, BibliographyDataField::BIBILIOGRAPHIC_TYPE },
1111  { XML_BOOKTITLE, BibliographyDataField::BOOKTITLE },
1112  { XML_CHAPTER, BibliographyDataField::CHAPTER },
1113  { XML_CUSTOM1, BibliographyDataField::CUSTOM1 },
1114  { XML_CUSTOM2, BibliographyDataField::CUSTOM2 },
1115  { XML_CUSTOM3, BibliographyDataField::CUSTOM3 },
1116  { XML_CUSTOM4, BibliographyDataField::CUSTOM4 },
1117  { XML_CUSTOM5, BibliographyDataField::CUSTOM5 },
1118  { XML_EDITION, BibliographyDataField::EDITION },
1119  { XML_EDITOR, BibliographyDataField::EDITOR },
1120  { XML_HOWPUBLISHED, BibliographyDataField::HOWPUBLISHED },
1121  { XML_IDENTIFIER, BibliographyDataField::IDENTIFIER },
1122  { XML_INSTITUTION, BibliographyDataField::INSTITUTION },
1123  { XML_ISBN, BibliographyDataField::ISBN },
1124  { XML_JOURNAL, BibliographyDataField::JOURNAL },
1125  { XML_MONTH, BibliographyDataField::MONTH },
1126  { XML_NOTE, BibliographyDataField::NOTE },
1127  { XML_NUMBER, BibliographyDataField::NUMBER },
1128  { XML_ORGANIZATIONS, BibliographyDataField::ORGANIZATIONS },
1129  { XML_PAGES, BibliographyDataField::PAGES },
1130  { XML_PUBLISHER, BibliographyDataField::PUBLISHER },
1131  { XML_REPORT_TYPE, BibliographyDataField::REPORT_TYPE },
1132  { XML_SCHOOL, BibliographyDataField::SCHOOL },
1133  { XML_SERIES, BibliographyDataField::SERIES },
1134  { XML_TITLE, BibliographyDataField::TITLE },
1135  { XML_URL, BibliographyDataField::URL },
1136  { XML_VOLUME, BibliographyDataField::VOLUME },
1137  { XML_YEAR, BibliographyDataField::YEAR },
1138  { XML_TOKEN_INVALID, 0 }
1139 };
1140 
1142  SectionTypeEnum eType, //i90246
1143  const Sequence<PropertyValue> & rValues)
1144 {
1145  // variables for template values
1146 
1147  // char style
1148  OUString sCharStyle;
1149  bool bCharStyleOK = false;
1150 
1151  // text
1152  OUString sText;
1153  bool bTextOK = false;
1154 
1155  // tab position
1156  bool bRightAligned = false;
1157 
1158  // tab position
1159  sal_Int32 nTabPosition = 0;
1160  bool bTabPositionOK = false;
1161 
1162  // fill character
1163  OUString sFillChar;
1164  bool bFillCharOK = false;
1165 
1166  // chapter format
1167  sal_Int16 nChapterFormat = 0;
1168  bool bChapterFormatOK = false;
1169 
1170  // outline max level
1171  sal_Int16 nLevel = 0;
1172  bool bLevelOK = false;
1173 
1174  // Bibliography Data
1175  sal_Int16 nBibliographyData = 0;
1176  bool bBibliographyDataOK = false;
1177 
1178  // With Tab Stop #i21237#
1179  bool bWithTabStop = false;
1180  bool bWithTabStopOK = false;
1181 
1182  //i90246, the ODF version being written to is:
1184  //the above version cannot be used for old OOo (OOo 1.0) formats!
1185 
1186  // token type
1187  enum TemplateTypeEnum nTokenType = TOK_TTYPE_INVALID;
1188 
1189  for(const auto& rValue : rValues)
1190  {
1192  if ( SvXMLUnitConverter::convertEnum( nToken, rValue.Name,
1193  aTemplateParamMap ) )
1194  {
1195  // Only use direct and default values.
1196  // Wrong. no property states, so ignore.
1197  // if ( (beans::PropertyState_DIRECT_VALUE == rValues[i].State) ||
1198  // (beans::PropertyState_DEFAULT_VALUE == rValues[i].State) )
1199 
1200  switch (nToken)
1201  {
1202  case TOK_TPARAM_TOKEN_TYPE:
1203  {
1204  OUString sVal;
1205  rValue.Value >>= sVal;
1206  SvXMLUnitConverter::convertEnum( nTokenType, sVal, aTemplateTypeMap);
1207  break;
1208  }
1209 
1210  case TOK_TPARAM_CHAR_STYLE:
1211  // only valid, if not empty
1212  rValue.Value >>= sCharStyle;
1213  bCharStyleOK = !sCharStyle.isEmpty();
1214  break;
1215 
1216  case TOK_TPARAM_TEXT:
1217  rValue.Value >>= sText;
1218  bTextOK = true;
1219  break;
1220 
1221  case TOK_TPARAM_TAB_RIGHT_ALIGNED:
1222  bRightAligned =
1223  *o3tl::doAccess<bool>(rValue.Value);
1224  break;
1225 
1226  case TOK_TPARAM_TAB_POSITION:
1227  rValue.Value >>= nTabPosition;
1228  bTabPositionOK = true;
1229  break;
1230 
1231  // #i21237#
1232  case TOK_TPARAM_TAB_WITH_TAB:
1233  bWithTabStop = *o3tl::doAccess<bool>(rValue.Value);
1234  bWithTabStopOK = true;
1235  break;
1236 
1237  case TOK_TPARAM_TAB_FILL_CHAR:
1238  rValue.Value >>= sFillChar;
1239  bFillCharOK = true;
1240  break;
1241 
1242  case TOK_TPARAM_CHAPTER_FORMAT:
1243  rValue.Value >>= nChapterFormat;
1244  bChapterFormatOK = true;
1245  break;
1246 //---> i53420
1247  case TOK_TPARAM_CHAPTER_LEVEL:
1248  rValue.Value >>= nLevel;
1249  bLevelOK = true;
1250  break;
1251  case TOK_TPARAM_BIBLIOGRAPHY_DATA:
1252  rValue.Value >>= nBibliographyData;
1253  bBibliographyDataOK = true;
1254  break;
1255  }
1256  }
1257  }
1258 
1259  // convert type to token (and check validity) ...
1260  XMLTokenEnum eElement(XML_TOKEN_INVALID);
1261  sal_uInt16 nNamespace(XML_NAMESPACE_TEXT);
1262  switch(nTokenType)
1263  {
1264  case TOK_TTYPE_ENTRY_TEXT:
1265  eElement = XML_INDEX_ENTRY_TEXT;
1266  break;
1267  case TOK_TTYPE_TAB_STOP:
1268  // test validity
1269  if ( bRightAligned || bTabPositionOK || bFillCharOK )
1270  {
1271  eElement = XML_INDEX_ENTRY_TAB_STOP;
1272  }
1273  break;
1274  case TOK_TTYPE_TEXT:
1275  // test validity
1276  if (bTextOK)
1277  {
1278  eElement = XML_INDEX_ENTRY_SPAN;
1279  }
1280  break;
1281  case TOK_TTYPE_PAGE_NUMBER:
1282  eElement = XML_INDEX_ENTRY_PAGE_NUMBER;
1283  break;
1284  case TOK_TTYPE_CHAPTER_INFO: // keyword index
1285  eElement = XML_INDEX_ENTRY_CHAPTER;
1286  break;
1287  case TOK_TTYPE_ENTRY_NUMBER: // table of content
1288  eElement = XML_INDEX_ENTRY_CHAPTER;
1289  break;
1290  case TOK_TTYPE_HYPERLINK_START:
1291  eElement = XML_INDEX_ENTRY_LINK_START;
1292  break;
1293  case TOK_TTYPE_HYPERLINK_END:
1294  eElement = XML_INDEX_ENTRY_LINK_END;
1295  break;
1296  case TOK_TTYPE_BIBLIOGRAPHY:
1297  if (bBibliographyDataOK)
1298  {
1299  eElement = XML_INDEX_ENTRY_BIBLIOGRAPHY;
1300  }
1301  break;
1302  default:
1303  ; // unknown/unimplemented template
1304  break;
1305  }
1306 
1307  if (eType != TEXT_SECTION_TYPE_TOC)
1308  {
1309  switch (nTokenType)
1310  {
1311  case TOK_TTYPE_HYPERLINK_START:
1312  case TOK_TTYPE_HYPERLINK_END:
1313  if (SvtSaveOptions::ODFSVER_012 < aODFVersion)
1314  {
1315  assert(eType == TEXT_SECTION_TYPE_ILLUSTRATION
1316  || eType == TEXT_SECTION_TYPE_OBJECT
1317  || eType == TEXT_SECTION_TYPE_TABLE
1318  || eType == TEXT_SECTION_TYPE_USER);
1319  nNamespace = XML_NAMESPACE_LO_EXT;
1320  }
1321  else
1322  {
1323  eElement = XML_TOKEN_INVALID; // not allowed in ODF <= 1.2
1324  }
1325  break;
1326  default:
1327  break;
1328  }
1329  }
1330 
1331  //--->i90246
1332  //check the ODF version being exported
1333  if (aODFVersion == SvtSaveOptions::ODFSVER_011
1334  || aODFVersion == SvtSaveOptions::ODFSVER_010)
1335  {
1336  bLevelOK = false;
1337  if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1338  {
1339  //if we are emitting for ODF 1.1 or 1.0, this information can be used for alphabetical index only
1340  //it's not permitted in other indexes
1341  if (eType != TEXT_SECTION_TYPE_ALPHABETICAL)
1342  {
1343  eElement = XML_TOKEN_INVALID; //not permitted, invalidate the element
1344  }
1345  else //maps format for 1.1 & 1.0
1346  {
1347  // a few word here: OOo up to 2.4 uses the field chapter info in Alphabetical index
1348  // in a way different from the ODF 1.1/1.0 specification:
1349 
1350  // ODF1.1/1.0 OOo display in chapter info ODF1.2
1351  // (used in alphabetical index only
1352 
1353  // number chapter number without pre/postfix plain-number
1354  // number-and-name chapter number without pre/postfix plus title plain-number-and-name
1355 
1356  // with issue i89791 the reading of ODF 1.1 and 1.0 was corrected
1357  // this one corrects the writing back from ODF 1.2 to ODF 1.1/1.0
1358  // unfortunately if there is another application which interprets correctly ODF1.1/1.0,
1359  // the resulting alphabetical index will be rendered wrong by OOo 2.4 version
1360 
1361  switch( nChapterFormat )
1362  {
1363  case ChapterFormat::DIGIT:
1364  nChapterFormat = ChapterFormat::NUMBER;
1365  break;
1366  case ChapterFormat::NO_PREFIX_SUFFIX:
1367  nChapterFormat = ChapterFormat::NAME_NUMBER;
1368  break;
1369  }
1370  }
1371  }
1372  else if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1373  {
1374  //in case of ODF 1.1 or 1.0 the only allowed number format is "number"
1375  //so, force it...
1376  // The only expected 'foreign' nChapterFormat is
1377  // ' ChapterFormat::DIGIT', forced to 'none, since the
1378  // 'value allowed in ODF 1.1 and 1.0 is 'number' the default
1379  // this can be obtained by simply disabling the chapter format
1380  bChapterFormatOK = false;
1381  }
1382  }
1383 
1384  // ... and write Element
1385  if (eElement != XML_TOKEN_INVALID)
1386  {
1387  // character style (for most templates)
1388  if (bCharStyleOK)
1389  {
1390  switch (nTokenType)
1391  {
1392  case TOK_TTYPE_ENTRY_TEXT:
1393  case TOK_TTYPE_TEXT:
1394  case TOK_TTYPE_PAGE_NUMBER:
1395  case TOK_TTYPE_ENTRY_NUMBER:
1396  case TOK_TTYPE_HYPERLINK_START:
1397  case TOK_TTYPE_HYPERLINK_END:
1398  case TOK_TTYPE_BIBLIOGRAPHY:
1399  case TOK_TTYPE_CHAPTER_INFO:
1400  case TOK_TTYPE_TAB_STOP:
1403  GetExport().EncodeStyleName( sCharStyle) );
1404  break;
1405  default:
1406  ; // nothing: no character style
1407  break;
1408  }
1409  }
1410 
1411  // tab properties
1412  if (TOK_TTYPE_TAB_STOP == nTokenType)
1413  {
1414  // tab type
1416  bRightAligned ? XML_RIGHT : XML_LEFT);
1417 
1418  if (bTabPositionOK && (! bRightAligned))
1419  {
1420  // position for left tabs (convert to measure)
1421  OUStringBuffer sBuf;
1423  nTabPosition);
1425  XML_POSITION,
1426  sBuf.makeStringAndClear());
1427  }
1428 
1429  // fill char ("leader char")
1430  if (bFillCharOK && !sFillChar.isEmpty())
1431  {
1433  XML_LEADER_CHAR, sFillChar);
1434  }
1435 
1436  // #i21237#
1437  if (bWithTabStopOK && ! bWithTabStop)
1438  {
1440  XML_WITH_TAB,
1441  XML_FALSE);
1442  }
1443  }
1444 
1445  // bibliography data
1446  if (TOK_TTYPE_BIBLIOGRAPHY == nTokenType)
1447  {
1448  OSL_ENSURE(bBibliographyDataOK, "need bibl data");
1449  OUStringBuffer sBuf;
1450  if (SvXMLUnitConverter::convertEnum( sBuf, nBibliographyData,
1451  aBibliographyDataFieldMap ) )
1452  {
1455  sBuf.makeStringAndClear());
1456  }
1457  }
1458 
1459  // chapter info
1460  if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1461  {
1462  OSL_ENSURE(bChapterFormatOK, "need chapter info");
1466 //---> i53420
1467  if (bLevelOK)
1469  OUString::number(nLevel));
1470  }
1471 
1472 //--->i53420
1473  if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1474  {
1475  if (bChapterFormatOK)
1479 
1480  if (bLevelOK)
1482  OUString::number(nLevel));
1483  }
1484  // export template
1485  SvXMLElementExport aTemplateElement(GetExport(), nNamespace,
1486  GetXMLToken(eElement),
1487  true, false)
1488  ;
1489 
1490  // entry text or span element: write text
1491  if (TOK_TTYPE_TEXT == nTokenType)
1492  {
1493  GetExport().Characters(sText);
1494  }
1495  }
1496 }
1497 
1499  Reference<XIndexReplace> const & xLevelParagraphStyles)
1500 {
1501  // iterate over levels
1502  sal_Int32 nPLevelCount = xLevelParagraphStyles->getCount();
1503  for(sal_Int32 nLevel = 0; nLevel < nPLevelCount; nLevel++)
1504  {
1505  Any aAny = xLevelParagraphStyles->getByIndex(nLevel);
1506  Sequence<OUString> aStyleNames;
1507  aAny >>= aStyleNames;
1508 
1509  // export only if at least one style is contained
1510  if (aStyleNames.hasElements())
1511  {
1512  // level attribute; we count 1..10; API 0..9
1513  sal_Int32 nLevelPlusOne = nLevel + 1;
1516  OUString::number(nLevelPlusOne));
1517 
1518  // source styles element
1519  SvXMLElementExport aParaStyles(GetExport(),
1522  true, true);
1523 
1524  // iterate over styles in this level
1525  for(const auto& rStyleName : std::as_const(aStyleNames))
1526  {
1527  // stylename attribute
1530  GetExport().EncodeStyleName(rStyleName) );
1531 
1532  // element
1533  SvXMLElementExport aParaStyle(GetExport(),
1536  true, false);
1537  }
1538  }
1539  }
1540 }
1541 
1543  const Reference<XPropertySet> & rPropSet,
1544  const OUString& sPropertyName,
1545  enum XMLTokenEnum eAttributeName,
1546  bool bDefault,
1547  bool bInvert)
1548 {
1549  OSL_ENSURE(eAttributeName != XML_TOKEN_INVALID, "Need attribute name");
1550 
1551  Any aAny = rPropSet->getPropertyValue(sPropertyName);
1552  bool bTmp = *o3tl::doAccess<bool>(aAny);
1553 
1554  // value = value ^ bInvert
1555  // omit if value == default
1556  if ( (bTmp != bInvert) != bDefault )
1557  {
1558  // export non-default value (since default is omitted)
1560  eAttributeName,
1561  bDefault ? XML_FALSE : XML_TRUE);
1562  }
1563 }
1564 
1566 {
1567  // first: get field master (via text field supplier)
1568  Reference<XTextFieldsSupplier> xTextFieldsSupp( rExport.GetModel(),
1569  UNO_QUERY );
1570  if ( xTextFieldsSupp.is() )
1571  {
1572  const OUString sFieldMaster_Bibliography("com.sun.star.text.FieldMaster.Bibliography");
1573 
1574  // get bibliography field master
1575  Reference<XNameAccess> xMasters =
1576  xTextFieldsSupp->getTextFieldMasters();
1577  if ( xMasters->hasByName(sFieldMaster_Bibliography) )
1578  {
1579  Any aAny =
1580  xMasters->getByName(sFieldMaster_Bibliography);
1581  Reference<XPropertySet> xPropSet;
1582  aAny >>= xPropSet;
1583 
1584  OSL_ENSURE( xPropSet.is(), "field master must have XPropSet" );
1585 
1586  const OUString sBracketBefore("BracketBefore");
1587  const OUString sBracketAfter("BracketAfter");
1588  const OUString sIsNumberEntries("IsNumberEntries");
1589  const OUString sIsSortByPosition("IsSortByPosition");
1590  const OUString sSortKeys("SortKeys");
1591  const OUString sSortAlgorithm("SortAlgorithm");
1592  const OUString sLocale("Locale");
1593 
1594  OUString sTmp;
1595 
1596  aAny = xPropSet->getPropertyValue(sBracketBefore);
1597  aAny >>= sTmp;
1598  rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_PREFIX, sTmp);
1599 
1600  aAny = xPropSet->getPropertyValue(sBracketAfter);
1601  aAny >>= sTmp;
1602  rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_SUFFIX, sTmp);
1603 
1604  aAny = xPropSet->getPropertyValue(sIsNumberEntries);
1605  if (*o3tl::doAccess<bool>(aAny))
1606  {
1609  }
1610 
1611  aAny = xPropSet->getPropertyValue(sIsSortByPosition);
1612  if (! *o3tl::doAccess<bool>(aAny))
1613  {
1616  }
1617 
1618  // sort algorithm
1619  aAny = xPropSet->getPropertyValue(sSortAlgorithm);
1620  OUString sAlgorithm;
1621  aAny >>= sAlgorithm;
1622  if( !sAlgorithm.isEmpty() )
1623  {
1625  XML_SORT_ALGORITHM, sAlgorithm );
1626  }
1627 
1628  // locale
1629  aAny = xPropSet->getPropertyValue(sLocale);
1630  Locale aLocale;
1631  aAny >>= aLocale;
1633 
1634  // configuration element
1635  SvXMLElementExport aElement(rExport, XML_NAMESPACE_TEXT,
1637  true, true);
1638 
1639  // sort keys
1640  aAny = xPropSet->getPropertyValue(sSortKeys);
1641  Sequence<Sequence<PropertyValue> > aKeys;
1642  aAny >>= aKeys;
1643  for(const Sequence<PropertyValue> & rKey : std::as_const(aKeys))
1644  {
1645  for(const PropertyValue& rValue : rKey)
1646  {
1647  if (rValue.Name == "SortKey")
1648  {
1649  sal_Int16 nKey = 0;
1650  rValue.Value >>= nKey;
1651  OUStringBuffer sBuf;
1652  if (SvXMLUnitConverter::convertEnum( sBuf, nKey,
1653  aBibliographyDataFieldMap ) )
1654  {
1656  sBuf.makeStringAndClear());
1657  }
1658  }
1659  else if (rValue.Name == "IsSortAscending")
1660  {
1661  bool bTmp = *o3tl::doAccess<bool>(rValue.Value);
1664  bTmp ? XML_TRUE : XML_FALSE);
1665  }
1666  }
1667 
1668  SvXMLElementExport aKeyElem(rExport,
1670  true, true);
1671  }
1672  }
1673  }
1674 }
1675 
1676 
1678  const Reference<XTextSection> & rSection) const
1679 {
1680  bool bRet = false;
1681 
1682  // a section is mute if
1683  // 1) it exists
1684  // 2) the SaveLinkedSections flag (at the export) is false
1685  // 3) the IsGlobalDocumentSection property is true
1686  // 4) it is not an Index
1687 
1688  if ( (!rExport.IsSaveLinkedSections()) && rSection.is() )
1689  {
1690  // walk the section chain and set bRet if any is linked
1691  for(Reference<XTextSection> aSection(rSection);
1692  aSection.is();
1693  aSection = aSection->getParentSection())
1694  {
1695  // check if it is a global document section (linked or index)
1696  Reference<XPropertySet> xPropSet(aSection, UNO_QUERY);
1697  if (xPropSet.is())
1698  {
1699  Any aAny = xPropSet->getPropertyValue("IsGlobalDocumentSection");
1700 
1701  if ( *o3tl::doAccess<bool>(aAny) )
1702  {
1703  Reference<XDocumentIndex> xIndex;
1704  if (! GetIndex(rSection, xIndex))
1705  {
1706  bRet = true;
1707 
1708  // early out if result is known
1709  break;
1710  }
1711  }
1712  }
1713  // section has no properties: ignore
1714  }
1715  }
1716  // else: no section, or always save sections: default (false)
1717 
1718  return bRet;
1719 }
1720 
1722  const Reference<XTextContent> & rSection,
1723  bool bDefault) const
1724 {
1725  // default: like default argument
1726  bool bRet = bDefault;
1727 
1728  Reference<XPropertySet> xPropSet(rSection->getAnchor(), UNO_QUERY);
1729  if (xPropSet.is())
1730  {
1731  if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1732  {
1733  Any aAny = xPropSet->getPropertyValue("TextSection");
1734  Reference<XTextSection> xSection;
1735  aAny >>= xSection;
1736 
1737  bRet = IsMuteSection(xSection);
1738  }
1739  // else: return default
1740  }
1741  // else: return default
1742 
1743  return bRet;
1744 }
1745 
1747  const Reference<XTextSection> & rEnclosingSection,
1748  const Reference<XTextContent> & rContent,
1749  bool bDefault)
1750 {
1751  // default: like default argument
1752  bool bRet = bDefault;
1753  OSL_ENSURE(rEnclosingSection.is(), "enclosing section expected");
1754 
1755  Reference<XPropertySet> xPropSet(rContent, UNO_QUERY);
1756  if (xPropSet.is())
1757  {
1758  if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1759  {
1760  Any aAny = xPropSet->getPropertyValue("TextSection");
1761  Reference<XTextSection> xSection;
1762  aAny >>= xSection;
1763 
1764  // now walk chain of text sections (if we have one)
1765  if (xSection.is())
1766  {
1767  do
1768  {
1769  bRet = (rEnclosingSection == xSection);
1770  xSection = xSection->getParentSection();
1771  }
1772  while (!bRet && xSection.is());
1773  }
1774  else
1775  bRet = false; // no section -> can't be inside
1776  }
1777  // else: no TextSection property -> return default
1778  }
1779  // else: no XPropertySet -> return default
1780 
1781  return bRet;
1782 }
1783 
1784 
1786 {
1788  return;
1789 
1790  Reference< XChapterNumberingSupplier > xCNSupplier( rExport.GetModel(),
1791  UNO_QUERY );
1792 
1793  Reference< XIndexReplace > xChapterNumbering;
1794  if( xCNSupplier.is() )
1795  xChapterNumbering = xCNSupplier->getChapterNumberingRules();
1796 
1797  if( !xChapterNumbering.is() )
1798  return;
1799 
1800  sal_Int32 nCount = xChapterNumbering->getCount();
1801  for( sal_Int32 nLevel = 0; nLevel < nCount; nLevel++ )
1802  {
1803  OUString sStyle;
1804  Sequence<PropertyValue> aProperties;
1805  xChapterNumbering->getByIndex( nLevel ) >>= aProperties;
1806  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
1807  [](const PropertyValue& rProp) { return rProp.Name == "HeadingStyleName"; });
1808  if (pProp != aProperties.end())
1809  pProp->Value >>= sStyle;
1810 
1811  if( !sStyle.isEmpty() )
1812  {
1814  GetExport().EncodeStyleName( sStyle ) );
1815 
1817  OUString::number( nLevel + 1 ) );
1819  true, false );
1820  }
1821  }
1822 
1823  bHeadingDummiesExported = true;
1824 }
1825 
1826 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static const XMLTokenEnum aTypeSourceElementNameMap[]
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
Definition: xmlnmspe.hxx:80
constexpr sal_uInt16 XML_NAMESPACE_STYLE
Definition: xmlnmspe.hxx:30
static const char * aLevelStylePropNameTOCMap[]
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
static bool convertEnum(EnumT &rEnum, const OUString &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:128
void ExportTableOfContentStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a table of content (and source element)
static const char * aLevelStylePropNameBibliographyMap[]
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.
void ExportUserIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a user index (and source element)
SectionTypeEnum
void ExportTableAndIllustrationIndexSourceAttributes(const css::uno::Reference< css::beans::XPropertySet > &rSection)
Helper method to export common attributes for table and illustration indices.
const SvXMLUnitConverter & GetMM100UnitConverter() const
Definition: xmlexp.hxx:395
void CheckAttrList()
Definition: xmlexp.cxx:1047
static enum::xmloff::token::XMLTokenEnum MapReferenceType(sal_Int16 nType)
map ReferenceFieldPart to XML string
Definition: txtflde.cxx:3092
const char * pPropName
void ExportSectionEnd(const css::uno::Reference< css::text::XTextSection > &rSection, bool bAutoStyles)
export section or index end elements
void ExportRegularSectionStart(const css::uno::Reference< css::text::XTextSection > &rSection)
export a proper section (and source elements)
XMLTextParagraphExport & GetParaExport()
constexpr sal_uInt16 XML_NAMESPACE_TEXT
Definition: xmlnmspe.hxx:31
static const XMLTokenEnum aLevelNameTOCMap[]
SvXMLEnumStringMapEntry< TemplateParamEnum > const aTemplateParamMap[]
TemplateTypeEnum
static enum::xmloff::token::XMLTokenEnum MapChapterDisplayFormat(sal_Int16 nType)
map ChapterDisplayFormat to XML string
Definition: txtflde.cxx:3033
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:415
PropertiesInfo aProperties
void ExportObjectIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an object index (and source element)
SvXMLEnumStringMapEntry< SectionTypeEnum > const aIndexTypeMap[]
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:976
XMLSectionExport(SvXMLExport &rExp, XMLTextParagraphExport &rParaExp)
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
static const char ** aTypeLevelStylePropNameMap[]
int nCount
void ExportBaseIndexBody(SectionTypeEnum eType, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index body (common for all index types).
void AddAttribute(sal_uInt16 nPrefix, const char *pName, const OUString &rValue)
Definition: xmlexp.cxx:926
void StartElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
Definition: xmlexp.cxx:2128
static const XMLTokenEnum aLevelNameBibliographyMap[]
SvXMLExport & GetExport()
static void encode(OUStringBuffer &aStrBuffer, const css::uno::Sequence< sal_Int8 > &aPass)
XMLTokenEnum
The enumeration of all XML tokens.
Definition: xmltoken.hxx:47
bool IsMuteSection(const css::uno::Reference< css::text::XTextSection > &rSection) const
Should the content of this section be exported? (E.g.
DocumentType eType
void ExportAlphabeticalIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an alphabetical/keyword index (and source element)
SvtSaveOptions::ODFSaneDefaultVersion getSaneDefaultVersion() const
returns the deterministic version for odf export
Definition: xmlexp.cxx:2312
Map a const char* (with length) to a sal_uInt16 value.
Definition: xmlement.hxx:70
int i
SvXMLExport & rExport
SvXMLEnumStringMapEntry< TemplateTypeEnum > const aTemplateTypeMap[]
static const XMLTokenEnum aLevelNameTableMap[]
TemplateParamEnum
void ExportIndexStart(const css::uno::Reference< css::text::XDocumentIndex > &rSection)
export an index start element.
void Add(XmlStyleFamily nFamily, MultiPropertySetHelper &rPropSetHelper, const css::uno::Reference< css::beans::XPropertySet > &rPropSet)
add autostyle for specified family
OUString GetQNameByKey(sal_uInt16 nKey, const OUString &rLocalName, bool bCache=true) const
Definition: nmspmap.cxx:187
void ExportIndexTemplateElement(SectionTypeEnum eType, const css::uno::Sequence< css::beans::PropertyValue > &rValues)
export a single template element (e.g. span or tab-stop)
static enum SectionTypeEnum MapSectionType(const OUString &rSectionName)
map service name to section type
const SvXMLNamespaceMap & GetNamespaceMap() const
Definition: xmlexp.hxx:392
static const char * aLevelStylePropNameTableMap[]
SvXMLEnumMapEntry< sal_Int16 > const aBibliographyDataFieldMap[]
constexpr sal_uInt16 XML_NAMESPACE_OOOW
Definition: xmlnmspe.hxx:63
void ExportMasterDocHeadingDummies()
export a heading for every level.
constexpr sal_uInt16 XML_NAMESPACE_XLINK
Definition: xmlnmspe.hxx:35
constexpr sal_uInt16 XML_NAMESPACE_FO
Definition: xmlnmspe.hxx:34
void ExportSectionStart(const css::uno::Reference< css::text::XTextSection > &rSection, bool bAutoStyles)
export section or index start and source elements.
Map an XMLTokenEnum to an enum value.
Definition: ximpshap.hxx:40
void IgnorableWhitespace()
Definition: xmlexp.cxx:2224
DefTokenId nToken
std::unique_ptr< char[]> aBuffer
void EndElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
Definition: xmlexp.cxx:2185
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3366
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.
Handling of tokens in XML:
void Characters(const OUString &rChars)
Definition: xmlexp.cxx:2163
void ExportBibliographyStart(const css::uno::Reference< css::beans::XPropertySet > &rIndex)
export the bibliography (and source element)
OReadImagesDocumentHandler::Image_XML_Namespace nNamespace
QPRO_FUNC_TYPE nType
void ExportTableIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export a table index (and source element)
bool IsSaveLinkedSections() const
Definition: xmlexp.hxx:474
void ExportLevelParagraphStyles(css::uno::Reference< css::container::XIndexReplace > const &xStyles)
export level paragraph styles
static const XMLTokenEnum * aTypeLevelNameMap[]
void ExportIndexHeaderStart(const css::uno::Reference< css::text::XTextSection > &rSection)
export an index header start element.
static const XMLTokenEnum aTypeLevelAttrMap[]
static const char * aLevelStylePropNameAlphaMap[]
void ExportIllustrationIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an illustration index (and source element)
void AddAttributeXmlId(css::uno::Reference< css::uno::XInterface > const &i_xIfc)
add xml:id attribute (for RDF metadata)
Definition: xmlexp.cxx:2338
void ExportBaseIndexSource(SectionTypeEnum eType, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index source element (common for all index types).
css::uno::Any const SvXMLExport & rExport
Definition: ImageStyle.hxx:38
void convertMeasureToXML(OUStringBuffer &rBuffer, sal_Int32 nMeasure) const
convert measure to string: from meCoreMeasureUnit to meXMLMeasureUnit
Definition: xmluconv.cxx:181
void ExportBaseIndexStart(::xmloff::token::XMLTokenEnum eElement, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index element start (for all index types).
static void ExportBibliographyConfiguration(SvXMLExport &rExport)
Export the configuration element for bibliography indices.
static const XMLTokenEnum aLevelNameAlphaMap[]
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
Definition: xmlnmspe.hxx:29
static const XMLTokenEnum aTypeElementNameMap[]
#define ENUM_STRING_MAP_ENTRY(name, tok)
Definition: xmlement.hxx:62