Warning, file /office/calligra/libs/text/KoTableOfContentsGeneratorInfo.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /*
0002  * Copyright (C) 2011 Lukáš Tvrdý <lukas.tvrdy@ixonos.com>
0003  * Copyright (C) 2011 Ko GmbH <cbo@kogmbh.com>
0004  * Copyright (C) 2011 Gopalakrishna Bhat A <gopalakbhat@gmail.com>
0005  *
0006  * This library is free software; you can redistribute it and/or
0007  * modify it under the terms of the GNU Library General Public
0008  * License as published by the Free Software Foundation; either
0009  * version 2 of the License, or (at your option) any later version.
0010  *
0011  * This library is distributed in the hope that it will be useful,
0012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0014  * Library General Public License for more details.
0015  *
0016  * You should have received a copy of the GNU Library General Public License
0017  * along with this library; see the file COPYING.LIB.  If not, write to
0018  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0019  * Boston, MA 02110-1301, USA.
0020  */
0021 
0022 #include "KoTableOfContentsGeneratorInfo.h"
0023 
0024 #include <KoXmlNS.h>
0025 #include <KoTextSharedLoadingData.h>
0026 #include <KoParagraphStyle.h>
0027 #include <KoXmlWriter.h>
0028 #include <KoXmlReader.h>
0029 
0030 int KoTableOfContentsGeneratorInfo::styleNameToStyleId(KoTextSharedLoadingData *sharedLoadingData, const QString &styleName)
0031 {
0032     //find styleId of a style based on its style:name property
0033     KoParagraphStyle * style = sharedLoadingData->paragraphStyle(styleName, true);
0034     if (style) {
0035         return style->styleId();
0036     }
0037 
0038     //if the previous way of finding styles fails fall back on using style:display-name property of a style
0039     QList<KoParagraphStyle *> paragraphStyles = sharedLoadingData->paragraphStyles(true);
0040     QList<KoParagraphStyle *>::const_iterator iter = paragraphStyles.constBegin();
0041 
0042     for (; iter != paragraphStyles.constEnd(); ++iter) {
0043         if ((*iter)->name() == styleName) {
0044             return (*iter)->styleId();
0045         }
0046     }
0047 
0048     return 0;
0049 }
0050 
0051 
0052 KoTableOfContentsGeneratorInfo::KoTableOfContentsGeneratorInfo(bool generateEntryTemplate)
0053     :
0054       m_indexScope("document")
0055     , m_outlineLevel(10)
0056     , m_relativeTabStopPosition(true)
0057     , m_useIndexMarks(true)
0058     , m_useIndexSourceStyles(false)
0059     , m_useOutlineLevel(true)
0060 {
0061     // index-title-template
0062     // m_indexTitleTemplate.text = "title";
0063     if (generateEntryTemplate) {
0064         // table-of-content-entry-template
0065         for (int level = 1; level <= m_outlineLevel; level++)  {
0066             TocEntryTemplate tocEntryTemplate;
0067             tocEntryTemplate.outlineLevel = level;
0068 
0069             // index-entry-link-start
0070             IndexEntryLinkStart *link = new IndexEntryLinkStart(QString());
0071             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(link));
0072 
0073             // index-entry-chapter
0074             // use null String if the style name is not present, it means that we inherit it from the parent
0075             IndexEntryChapter *entryChapter = new IndexEntryChapter(QString());
0076             entryChapter->display = "number";
0077             entryChapter->outlineLevel = level;
0078             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryChapter));
0079 
0080             // index-entry-text
0081             IndexEntryText *entryText = new IndexEntryText(QString());
0082             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryText));
0083 
0084             // index-entry-tab-stop
0085             IndexEntryTabStop *entryTabStop = new IndexEntryTabStop(QString());
0086             entryTabStop->tab.type = QTextOption::RightTab;
0087             entryTabStop->setPosition("");
0088             entryTabStop->tab.leaderText = '.';
0089             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryTabStop));
0090 
0091             // index-entry-page-number
0092             IndexEntryPageNumber *entryPageNumber = new IndexEntryPageNumber(QString());
0093             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryPageNumber) );
0094 
0095             // index-entry-link-end
0096             IndexEntryLinkEnd *linkend = new IndexEntryLinkEnd(QString());
0097             tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(linkend));
0098 
0099             m_entryTemplate.append(tocEntryTemplate);
0100         }
0101     }
0102 }
0103 
0104 KoTableOfContentsGeneratorInfo::~KoTableOfContentsGeneratorInfo()
0105 {
0106     foreach (const TocEntryTemplate &entryTemplate, m_entryTemplate) {
0107         qDeleteAll(entryTemplate.indexEntries);
0108     }
0109 }
0110 
0111 
0112 void KoTableOfContentsGeneratorInfo::loadOdf(KoTextSharedLoadingData *sharedLoadingData, const KoXmlElement& element)
0113 {
0114     Q_ASSERT(element.localName() == "table-of-content-source" && element.namespaceURI() == KoXmlNS::text);
0115 
0116     foreach (const TocEntryTemplate &entryTemplate, m_entryTemplate) {
0117         qDeleteAll(entryTemplate.indexEntries);
0118     }
0119     m_entryTemplate.clear();
0120 
0121     m_indexScope = element.attribute("index-scope", "document"); // enum {document, chapter}
0122     m_outlineLevel = element.attribute("outline-level","1").toInt();
0123     m_relativeTabStopPosition = element.attribute("relative-tab-stop-position","true") == "true";
0124     m_useIndexMarks = element.attribute("use-index-marks","f") == "true";
0125     m_useIndexSourceStyles = element.attribute("use-index-source-styles","false") == "true";
0126     m_useOutlineLevel = element.attribute("use-outline-level","true") == "true";
0127 
0128     // three other children to visit
0129     KoXmlElement p;
0130     forEachElement(p, element) {
0131         if (p.namespaceURI() != KoXmlNS::text) {
0132             continue;
0133         }
0134 
0135         // first child
0136         if (p.localName() == "index-title-template") {
0137             m_indexTitleTemplate.styleName = p.attribute("style-name");
0138             m_indexTitleTemplate.styleId = styleNameToStyleId(sharedLoadingData, m_indexTitleTemplate.styleName);
0139             m_indexTitleTemplate.text = p.text();
0140             // second child
0141         } else if (p.localName() == "table-of-content-entry-template") {
0142             TocEntryTemplate tocEntryTemplate;
0143             tocEntryTemplate.outlineLevel = p.attribute("outline-level").toInt();
0144             tocEntryTemplate.styleName = p.attribute("style-name");
0145             tocEntryTemplate.styleId = styleNameToStyleId(sharedLoadingData, tocEntryTemplate.styleName );
0146 
0147             KoXmlElement indexEntry;
0148             forEachElement(indexEntry, p) {
0149                 if (indexEntry.namespaceURI() != KoXmlNS::text) {
0150                     continue;
0151                 }
0152 
0153                 if (indexEntry.localName() == "index-entry-chapter") {
0154                     // use null String if the style name is not present, it means that we inherit it from the parent
0155                     IndexEntryChapter *entryChapter = new IndexEntryChapter(
0156                                 indexEntry.attribute("style-name", QString())
0157                                 );
0158 
0159                     // display can be "name", "number", "number-and-name", "plain-number" or "plain-number-and-name"
0160                     // "number" is default according the specs ODF v1.2
0161                     entryChapter->display = indexEntry.attribute("display", "number");
0162                     entryChapter->outlineLevel = indexEntry.attribute("outline-level", QString::number(tocEntryTemplate.outlineLevel)).toInt();
0163                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryChapter));
0164 
0165                 } else if (indexEntry.localName() == "index-entry-text") {
0166                     IndexEntryText *entryText = new IndexEntryText(indexEntry.attribute("style-name", QString()));
0167                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryText));
0168 
0169                 } else if (indexEntry.localName() == "index-entry-page-number") {
0170                     IndexEntryPageNumber *entryPageNumber = new IndexEntryPageNumber(indexEntry.attribute("style-name", QString()));
0171                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryPageNumber) );
0172 
0173                 } else if (indexEntry.localName() == "index-entry-span") {
0174                     IndexEntrySpan *entrySpan = new IndexEntrySpan(indexEntry.attribute("style-name", QString()) );
0175                     entrySpan->text = indexEntry.text();
0176                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entrySpan));
0177 
0178                 } else if (indexEntry.localName() == "index-entry-tab-stop") {
0179                     IndexEntryTabStop *entryTabStop = new IndexEntryTabStop(indexEntry.attribute("style-name", QString()));
0180 
0181                     QString type = indexEntry.attribute("type","right"); // left or right
0182                     if (type == "left") {
0183                         entryTabStop->tab.type = QTextOption::LeftTab;
0184                     } else {
0185                         entryTabStop->tab.type = QTextOption::RightTab;
0186                     }
0187                     entryTabStop->setPosition(indexEntry.attribute("position", QString()));
0188                     entryTabStop->tab.leaderText = indexEntry.attribute("leader-char",".");
0189                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(entryTabStop));
0190 
0191                 } else if (indexEntry.localName() == "index-entry-link-start") {
0192                     IndexEntryLinkStart *link = new IndexEntryLinkStart(indexEntry.attribute("style-name", QString()));
0193                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(link));
0194                 } else if (indexEntry.localName() == "index-entry-link-end") {
0195                     IndexEntryLinkEnd *link = new IndexEntryLinkEnd(indexEntry.attribute("style-name", QString()));
0196                     tocEntryTemplate.indexEntries.append(static_cast<IndexEntry*>(link));
0197                 }
0198             }
0199             m_entryTemplate.append(tocEntryTemplate);
0200 
0201             // third child
0202         } else if (p.localName() == "index-source-styles" && p.namespaceURI() == KoXmlNS::text) {
0203             IndexSourceStyles indexStyles;
0204             indexStyles.outlineLevel = p.attribute("outline-level").toInt();
0205 
0206             IndexSourceStyle indexStyle;
0207             KoXmlElement sourceElement;
0208             forEachElement(sourceElement, p) {
0209                 if (sourceElement.localName() == "index-source-style") {
0210                     indexStyle.styleName = sourceElement.attribute("style-name");
0211                     indexStyle.styleId = styleNameToStyleId(sharedLoadingData, indexStyle.styleName);
0212                     indexStyles.styles.append(indexStyle);
0213                 }
0214             }
0215             m_indexSourceStyles.append(indexStyles);
0216         }
0217     }// forEachElement
0218 }
0219 
0220 
0221 void KoTableOfContentsGeneratorInfo::saveOdf(KoXmlWriter * writer) const
0222 {
0223     writer->startElement("text:table-of-content-source");
0224     writer->addAttribute("text:index-scope", m_indexScope);
0225     writer->addAttribute("text:outline-level", m_outlineLevel);
0226     writer->addAttribute("text:relative-tab-stop-position", m_relativeTabStopPosition);
0227     writer->addAttribute("text:use-index-marks", m_useIndexMarks);
0228     writer->addAttribute("text:use-index-source-styles", m_useIndexSourceStyles);
0229     writer->addAttribute("text:use-outline-level", m_useOutlineLevel);
0230 
0231     m_indexTitleTemplate.saveOdf(writer);
0232 
0233     foreach (const TocEntryTemplate &entry, m_entryTemplate) {
0234         entry.saveOdf(writer);
0235     }
0236 
0237     foreach (const IndexSourceStyles &sourceStyle, m_indexSourceStyles) {
0238         sourceStyle.saveOdf(writer);
0239     }
0240 
0241     writer->endElement(); // text:table-of-content-source
0242 }
0243 
0244 KoTableOfContentsGeneratorInfo *KoTableOfContentsGeneratorInfo::clone()
0245 {
0246     KoTableOfContentsGeneratorInfo *newToCInfo=new KoTableOfContentsGeneratorInfo(false);
0247     newToCInfo->m_entryTemplate.clear();
0248     newToCInfo->m_name = QString(m_name);
0249     newToCInfo->m_styleName = QString(m_styleName);
0250     newToCInfo->m_indexScope = QString(m_indexScope);
0251     newToCInfo->m_outlineLevel = m_outlineLevel;
0252     newToCInfo->m_relativeTabStopPosition = m_relativeTabStopPosition;
0253     newToCInfo->m_useIndexMarks = m_useIndexMarks;
0254     newToCInfo->m_useIndexSourceStyles = m_useIndexSourceStyles;
0255     newToCInfo->m_useOutlineLevel = m_useOutlineLevel;
0256     newToCInfo->m_indexTitleTemplate = m_indexTitleTemplate;
0257 
0258     foreach (const TocEntryTemplate &tocTemplate, m_entryTemplate) {
0259         newToCInfo->m_entryTemplate.append(tocTemplate);
0260     }
0261 
0262     foreach (const IndexSourceStyles &indexSourceStyles, m_indexSourceStyles) {
0263         newToCInfo->m_indexSourceStyles.append(indexSourceStyles);
0264     }
0265 
0266     return newToCInfo;
0267 }
0268