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/xmlnamespace.hxx>
45 #include <xmloff/families.hxx>
46 #include <xmloff/xmluconv.hxx>
47 #include <xmloff/namespacemap.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  return;
187 
188  enum XMLTokenEnum eElement = XML_TOKEN_INVALID;
189 
190  // export index or regular section end
191  Reference<XDocumentIndex> xIndex;
192  if (GetIndex(rSection, xIndex))
193  {
194  if (xIndex.is())
195  {
196  // index end: close index body element
198  true );
200 
201  switch (MapSectionType(xIndex->getServiceName()))
202  {
204  eElement = XML_TABLE_OF_CONTENT;
205  break;
206 
208  eElement = XML_ILLUSTRATION_INDEX;
209  break;
210 
212  eElement = XML_ALPHABETICAL_INDEX;
213  break;
214 
216  eElement = XML_TABLE_INDEX;
217  break;
218 
220  eElement = XML_OBJECT_INDEX;
221  break;
222 
224  eElement = XML_USER_INDEX;
225  break;
226 
228  eElement = XML_BIBLIOGRAPHY;
229  break;
230 
231  default:
232  OSL_FAIL("unknown index type");
233  // default: skip index!
234  break;
235  }
236  }
237  else
238  {
239  eElement = XML_INDEX_TITLE;
240  }
241  }
242  else
243  {
244  eElement = XML_SECTION;
245  }
246 
247  if (XML_TOKEN_INVALID != eElement)
248  {
249  // any old attributes?
251 
252  // element surrounded by whitespace
253  GetExport().EndElement( XML_NAMESPACE_TEXT, eElement, true);
255  }
256  else
257  {
258  OSL_FAIL("Need element name!");
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  {
1316  || eType == TEXT_SECTION_TYPE_OBJECT
1317  || eType == TEXT_SECTION_TYPE_TABLE
1318  || eType == TEXT_SECTION_TYPE_USER);
1319  // ODF 1.3 OFFICE-3941
1320  nNamespace = (SvtSaveOptions::ODFSVER_013 <= aODFVersion)
1323  }
1324  else
1325  {
1326  eElement = XML_TOKEN_INVALID; // not allowed in ODF <= 1.2
1327  }
1328  break;
1329  default:
1330  break;
1331  }
1332  }
1333 
1334  //--->i90246
1335  //check the ODF version being exported
1336  if (aODFVersion == SvtSaveOptions::ODFSVER_011
1337  || aODFVersion == SvtSaveOptions::ODFSVER_010)
1338  {
1339  bLevelOK = false;
1340  if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1341  {
1342  //if we are emitting for ODF 1.1 or 1.0, this information can be used for alphabetical index only
1343  //it's not permitted in other indexes
1344  if (eType != TEXT_SECTION_TYPE_ALPHABETICAL)
1345  {
1346  eElement = XML_TOKEN_INVALID; //not permitted, invalidate the element
1347  }
1348  else //maps format for 1.1 & 1.0
1349  {
1350  // a few word here: OOo up to 2.4 uses the field chapter info in Alphabetical index
1351  // in a way different from the ODF 1.1/1.0 specification:
1352 
1353  // ODF1.1/1.0 OOo display in chapter info ODF1.2
1354  // (used in alphabetical index only
1355 
1356  // number chapter number without pre/postfix plain-number
1357  // number-and-name chapter number without pre/postfix plus title plain-number-and-name
1358 
1359  // with issue i89791 the reading of ODF 1.1 and 1.0 was corrected
1360  // this one corrects the writing back from ODF 1.2 to ODF 1.1/1.0
1361  // unfortunately if there is another application which interprets correctly ODF1.1/1.0,
1362  // the resulting alphabetical index will be rendered wrong by OOo 2.4 version
1363 
1364  switch( nChapterFormat )
1365  {
1366  case ChapterFormat::DIGIT:
1367  nChapterFormat = ChapterFormat::NUMBER;
1368  break;
1369  case ChapterFormat::NO_PREFIX_SUFFIX:
1370  nChapterFormat = ChapterFormat::NAME_NUMBER;
1371  break;
1372  }
1373  }
1374  }
1375  else if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1376  {
1377  //in case of ODF 1.1 or 1.0 the only allowed number format is "number"
1378  //so, force it...
1379  // The only expected 'foreign' nChapterFormat is
1380  // ' ChapterFormat::DIGIT', forced to 'none, since the
1381  // 'value allowed in ODF 1.1 and 1.0 is 'number' the default
1382  // this can be obtained by simply disabling the chapter format
1383  bChapterFormatOK = false;
1384  }
1385  }
1386 
1387  // ... and write Element
1388  if (eElement == XML_TOKEN_INVALID)
1389  return;
1390 
1391  // character style (for most templates)
1392  if (bCharStyleOK)
1393  {
1394  switch (nTokenType)
1395  {
1396  case TOK_TTYPE_ENTRY_TEXT:
1397  case TOK_TTYPE_TEXT:
1398  case TOK_TTYPE_PAGE_NUMBER:
1399  case TOK_TTYPE_ENTRY_NUMBER:
1400  case TOK_TTYPE_HYPERLINK_START:
1401  case TOK_TTYPE_HYPERLINK_END:
1402  case TOK_TTYPE_BIBLIOGRAPHY:
1403  case TOK_TTYPE_CHAPTER_INFO:
1404  case TOK_TTYPE_TAB_STOP:
1407  GetExport().EncodeStyleName( sCharStyle) );
1408  break;
1409  default:
1410  ; // nothing: no character style
1411  break;
1412  }
1413  }
1414 
1415  // tab properties
1416  if (TOK_TTYPE_TAB_STOP == nTokenType)
1417  {
1418  // tab type
1420  bRightAligned ? XML_RIGHT : XML_LEFT);
1421 
1422  if (bTabPositionOK && (! bRightAligned))
1423  {
1424  // position for left tabs (convert to measure)
1425  OUStringBuffer sBuf;
1427  nTabPosition);
1429  XML_POSITION,
1430  sBuf.makeStringAndClear());
1431  }
1432 
1433  // fill char ("leader char")
1434  if (bFillCharOK && !sFillChar.isEmpty())
1435  {
1437  XML_LEADER_CHAR, sFillChar);
1438  }
1439 
1440  // #i21237#
1441  if (bWithTabStopOK && ! bWithTabStop)
1442  {
1444  XML_WITH_TAB,
1445  XML_FALSE);
1446  }
1447  }
1448 
1449  // bibliography data
1450  if (TOK_TTYPE_BIBLIOGRAPHY == nTokenType)
1451  {
1452  OSL_ENSURE(bBibliographyDataOK, "need bibl data");
1453  OUStringBuffer sBuf;
1454  if (SvXMLUnitConverter::convertEnum( sBuf, nBibliographyData,
1455  aBibliographyDataFieldMap ) )
1456  {
1459  sBuf.makeStringAndClear());
1460  }
1461  }
1462 
1463  // chapter info
1464  if (TOK_TTYPE_CHAPTER_INFO == nTokenType)
1465  {
1466  OSL_ENSURE(bChapterFormatOK, "need chapter info");
1470 //---> i53420
1471  if (bLevelOK)
1473  OUString::number(nLevel));
1474  }
1475 
1476 //--->i53420
1477  if (TOK_TTYPE_ENTRY_NUMBER == nTokenType)
1478  {
1479  if (bChapterFormatOK)
1483 
1484  if (bLevelOK)
1486  OUString::number(nLevel));
1487  }
1488  // export template
1489  SvXMLElementExport aTemplateElement(GetExport(), nNamespace,
1490  GetXMLToken(eElement),
1491  true, false)
1492  ;
1493 
1494  // entry text or span element: write text
1495  if (TOK_TTYPE_TEXT == nTokenType)
1496  {
1497  GetExport().Characters(sText);
1498  }
1499 }
1500 
1502  Reference<XIndexReplace> const & xLevelParagraphStyles)
1503 {
1504  // iterate over levels
1505  sal_Int32 nPLevelCount = xLevelParagraphStyles->getCount();
1506  for(sal_Int32 nLevel = 0; nLevel < nPLevelCount; nLevel++)
1507  {
1508  Any aAny = xLevelParagraphStyles->getByIndex(nLevel);
1509  Sequence<OUString> aStyleNames;
1510  aAny >>= aStyleNames;
1511 
1512  // export only if at least one style is contained
1513  if (aStyleNames.hasElements())
1514  {
1515  // level attribute; we count 1..10; API 0..9
1516  sal_Int32 nLevelPlusOne = nLevel + 1;
1519  OUString::number(nLevelPlusOne));
1520 
1521  // source styles element
1522  SvXMLElementExport aParaStyles(GetExport(),
1525  true, true);
1526 
1527  // iterate over styles in this level
1528  for(const auto& rStyleName : std::as_const(aStyleNames))
1529  {
1530  // stylename attribute
1533  GetExport().EncodeStyleName(rStyleName) );
1534 
1535  // element
1536  SvXMLElementExport aParaStyle(GetExport(),
1539  true, false);
1540  }
1541  }
1542  }
1543 }
1544 
1546  const Reference<XPropertySet> & rPropSet,
1547  const OUString& sPropertyName,
1548  enum XMLTokenEnum eAttributeName,
1549  bool bDefault,
1550  bool bInvert)
1551 {
1552  OSL_ENSURE(eAttributeName != XML_TOKEN_INVALID, "Need attribute name");
1553 
1554  Any aAny = rPropSet->getPropertyValue(sPropertyName);
1555  bool bTmp = *o3tl::doAccess<bool>(aAny);
1556 
1557  // value = value ^ bInvert
1558  // omit if value == default
1559  if ( (bTmp != bInvert) != bDefault )
1560  {
1561  // export non-default value (since default is omitted)
1563  eAttributeName,
1564  bDefault ? XML_FALSE : XML_TRUE);
1565  }
1566 }
1567 
1569 {
1570  // first: get field master (via text field supplier)
1571  Reference<XTextFieldsSupplier> xTextFieldsSupp( rExport.GetModel(),
1572  UNO_QUERY );
1573  if ( !xTextFieldsSupp.is() )
1574  return;
1575 
1576  const OUString sFieldMaster_Bibliography("com.sun.star.text.FieldMaster.Bibliography");
1577 
1578  // get bibliography field master
1579  Reference<XNameAccess> xMasters =
1580  xTextFieldsSupp->getTextFieldMasters();
1581  if ( !xMasters->hasByName(sFieldMaster_Bibliography) )
1582  return;
1583 
1584  Any aAny =
1585  xMasters->getByName(sFieldMaster_Bibliography);
1586  Reference<XPropertySet> xPropSet;
1587  aAny >>= xPropSet;
1588 
1589  OSL_ENSURE( xPropSet.is(), "field master must have XPropSet" );
1590 
1591  OUString sTmp;
1592 
1593  aAny = xPropSet->getPropertyValue("BracketBefore");
1594  aAny >>= sTmp;
1595  rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_PREFIX, sTmp);
1596 
1597  aAny = xPropSet->getPropertyValue("BracketAfter");
1598  aAny >>= sTmp;
1599  rExport.AddAttribute(XML_NAMESPACE_TEXT, XML_SUFFIX, sTmp);
1600 
1601  aAny = xPropSet->getPropertyValue("IsNumberEntries");
1602  if (*o3tl::doAccess<bool>(aAny))
1603  {
1606  }
1607 
1608  aAny = xPropSet->getPropertyValue("IsSortByPosition");
1609  if (! *o3tl::doAccess<bool>(aAny))
1610  {
1613  }
1614 
1615  // sort algorithm
1616  aAny = xPropSet->getPropertyValue("SortAlgorithm");
1617  OUString sAlgorithm;
1618  aAny >>= sAlgorithm;
1619  if( !sAlgorithm.isEmpty() )
1620  {
1622  XML_SORT_ALGORITHM, sAlgorithm );
1623  }
1624 
1625  // locale
1626  aAny = xPropSet->getPropertyValue("Locale");
1627  Locale aLocale;
1628  aAny >>= aLocale;
1630 
1631  // configuration element
1632  SvXMLElementExport aElement(rExport, XML_NAMESPACE_TEXT,
1634  true, true);
1635 
1636  // sort keys
1637  aAny = xPropSet->getPropertyValue("SortKeys");
1638  Sequence<Sequence<PropertyValue> > aKeys;
1639  aAny >>= aKeys;
1640  for(const Sequence<PropertyValue> & rKey : std::as_const(aKeys))
1641  {
1642  for(const PropertyValue& rValue : rKey)
1643  {
1644  if (rValue.Name == "SortKey")
1645  {
1646  sal_Int16 nKey = 0;
1647  rValue.Value >>= nKey;
1648  OUStringBuffer sBuf;
1649  if (SvXMLUnitConverter::convertEnum( sBuf, nKey,
1650  aBibliographyDataFieldMap ) )
1651  {
1653  sBuf.makeStringAndClear());
1654  }
1655  }
1656  else if (rValue.Name == "IsSortAscending")
1657  {
1658  bool bTmp = *o3tl::doAccess<bool>(rValue.Value);
1661  bTmp ? XML_TRUE : XML_FALSE);
1662  }
1663  }
1664 
1665  SvXMLElementExport aKeyElem(rExport,
1667  true, true);
1668  }
1669 }
1670 
1671 
1673  const Reference<XTextSection> & rSection) const
1674 {
1675  bool bRet = false;
1676 
1677  // a section is mute if
1678  // 1) it exists
1679  // 2) the SaveLinkedSections flag (at the export) is false
1680  // 3) the IsGlobalDocumentSection property is true
1681  // 4) it is not an Index
1682 
1683  if ( (!rExport.IsSaveLinkedSections()) && rSection.is() )
1684  {
1685  // walk the section chain and set bRet if any is linked
1686  for(Reference<XTextSection> aSection(rSection);
1687  aSection.is();
1688  aSection = aSection->getParentSection())
1689  {
1690  // check if it is a global document section (linked or index)
1691  Reference<XPropertySet> xPropSet(aSection, UNO_QUERY);
1692  if (xPropSet.is())
1693  {
1694  Any aAny = xPropSet->getPropertyValue("IsGlobalDocumentSection");
1695 
1696  if ( *o3tl::doAccess<bool>(aAny) )
1697  {
1698  Reference<XDocumentIndex> xIndex;
1699  if (! GetIndex(rSection, xIndex))
1700  {
1701  bRet = true;
1702 
1703  // early out if result is known
1704  break;
1705  }
1706  }
1707  }
1708  // section has no properties: ignore
1709  }
1710  }
1711  // else: no section, or always save sections: default (false)
1712 
1713  return bRet;
1714 }
1715 
1717  const Reference<XTextContent> & rSection,
1718  bool bDefault) const
1719 {
1720  // default: like default argument
1721  bool bRet = bDefault;
1722 
1723  Reference<XPropertySet> xPropSet(rSection->getAnchor(), UNO_QUERY);
1724  if (xPropSet.is())
1725  {
1726  if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1727  {
1728  Any aAny = xPropSet->getPropertyValue("TextSection");
1729  Reference<XTextSection> xSection;
1730  aAny >>= xSection;
1731 
1732  bRet = IsMuteSection(xSection);
1733  }
1734  // else: return default
1735  }
1736  // else: return default
1737 
1738  return bRet;
1739 }
1740 
1742  const Reference<XTextSection> & rEnclosingSection,
1743  const Reference<XTextContent> & rContent,
1744  bool bDefault)
1745 {
1746  // default: like default argument
1747  bool bRet = bDefault;
1748  OSL_ENSURE(rEnclosingSection.is(), "enclosing section expected");
1749 
1750  Reference<XPropertySet> xPropSet(rContent, UNO_QUERY);
1751  if (xPropSet.is())
1752  {
1753  if (xPropSet->getPropertySetInfo()->hasPropertyByName("TextSection"))
1754  {
1755  Any aAny = xPropSet->getPropertyValue("TextSection");
1756  Reference<XTextSection> xSection;
1757  aAny >>= xSection;
1758 
1759  // now walk chain of text sections (if we have one)
1760  if (xSection.is())
1761  {
1762  do
1763  {
1764  bRet = (rEnclosingSection == xSection);
1765  xSection = xSection->getParentSection();
1766  }
1767  while (!bRet && xSection.is());
1768  }
1769  else
1770  bRet = false; // no section -> can't be inside
1771  }
1772  // else: no TextSection property -> return default
1773  }
1774  // else: no XPropertySet -> return default
1775 
1776  return bRet;
1777 }
1778 
1779 
1781 {
1783  return;
1784 
1785  Reference< XChapterNumberingSupplier > xCNSupplier( rExport.GetModel(),
1786  UNO_QUERY );
1787 
1788  Reference< XIndexReplace > xChapterNumbering;
1789  if( xCNSupplier.is() )
1790  xChapterNumbering = xCNSupplier->getChapterNumberingRules();
1791 
1792  if( !xChapterNumbering.is() )
1793  return;
1794 
1795  sal_Int32 nCount = xChapterNumbering->getCount();
1796  for( sal_Int32 nLevel = 0; nLevel < nCount; nLevel++ )
1797  {
1798  OUString sStyle;
1799  Sequence<PropertyValue> aProperties;
1800  xChapterNumbering->getByIndex( nLevel ) >>= aProperties;
1801  auto pProp = std::find_if(aProperties.begin(), aProperties.end(),
1802  [](const PropertyValue& rProp) { return rProp.Name == "HeadingStyleName"; });
1803  if (pProp != aProperties.end())
1804  pProp->Value >>= sStyle;
1805 
1806  if( !sStyle.isEmpty() )
1807  {
1809  GetExport().EncodeStyleName( sStyle ) );
1810 
1812  OUString::number( nLevel + 1 ) );
1814  true, false );
1815  }
1816  }
1817 
1818  bHeadingDummiesExported = true;
1819 }
1820 
1821 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
const XMLTokenEnum aTypeSourceElementNameMap[]
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
constexpr sal_uInt16 XML_NAMESPACE_OFFICE
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:394
void CheckAttrList()
Definition: xmlexp.cxx:1030
static enum::xmloff::token::XMLTokenEnum MapReferenceType(sal_Int16 nType)
map ReferenceFieldPart to XML string
Definition: txtflde.cxx:3098
constexpr sal_uInt16 XML_NAMESPACE_XLINK
const char * pPropName
void ExportSectionEnd(const css::uno::Reference< css::text::XTextSection > &rSection, bool bAutoStyles)
export section or index end elements
constexpr sal_uInt16 XML_NAMESPACE_LO_EXT
void ExportRegularSectionStart(const css::uno::Reference< css::text::XTextSection > &rSection)
export a proper section (and source elements)
XMLTextParagraphExport & GetParaExport()
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:3039
css::uno::Any const & rValue
Definition: ImageStyle.hxx:38
const css::uno::Reference< css::frame::XModel > & GetModel() const
Definition: xmlexp.hxx:414
PropertiesInfo aProperties
void ExportObjectIndexStart(const css::uno::Reference< css::beans::XPropertySet > &rSection)
export an object index (and source element)
SvXMLEnumStringMapEntry< SectionTypeEnum > const aIndexTypeMap[]
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
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:959
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:909
void StartElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSOutside)
Definition: xmlexp.cxx:2123
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:49
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:2297
Map a const char* (with length) to a sal_uInt16 value.
Definition: xmlement.hxx:70
constexpr sal_uInt16 XML_NAMESPACE_FO
int i
SvXMLExport & rExport
constexpr sal_uInt16 XML_NAMESPACE_TEXT
SvXMLEnumStringMapEntry< TemplateTypeEnum > const aTemplateTypeMap[]
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
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:391
static const char * aLevelStylePropNameTableMap[]
SvXMLEnumMapEntry< sal_Int16 > const aBibliographyDataFieldMap[]
void ExportMasterDocHeadingDummies()
export a heading for every level.
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:2219
DefTokenId nToken
std::unique_ptr< char[]> aBuffer
void EndElement(sal_uInt16 nPrefix, enum::xmloff::token::XMLTokenEnum eName, bool bIgnWSInside)
Definition: xmlexp.cxx:2180
const OUString & GetXMLToken(enum XMLTokenEnum eToken)
return the OUString representation for eToken
Definition: xmltoken.cxx:3378
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:2158
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:473
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.
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:2323
void ExportBaseIndexSource(SectionTypeEnum eType, const css::uno::Reference< css::beans::XPropertySet > &rSection)
Export the index source element (common for all index types).
constexpr sal_uInt16 XML_NAMESPACE_OOOW
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).
constexpr sal_uInt16 XML_NAMESPACE_STYLE
static void ExportBibliographyConfiguration(SvXMLExport &rExport)
Export the configuration element for bibliography indices.
const XMLTokenEnum aLevelNameAlphaMap[]
const XMLTokenEnum aTypeElementNameMap[]
#define ENUM_STRING_MAP_ENTRY(name, tok)
Definition: xmlement.hxx:62