1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 /***************************************************************************
8 begin : Jun 2005
9 copyright : (C) 2005 by Craig Bradney
10 email : cbradney@zip.com.au
11 ***************************************************************************/
12
13 /***************************************************************************
14 * *
15 * This program is free software; you can redistribute it and/or modify *
16 * it under the terms of the GNU General Public License as published by *
17 * the Free Software Foundation; either version 2 of the License, or *
18 * (at your option) any later version. *
19 * *
20 ***************************************************************************/
21 #include "tocgenerator.h"
22
23 #include <QMap>
24 #include <QString>
25
26 #include "gtframestyle.h"
27 #include "gtparagraphstyle.h"
28 #include "gtwriter.h"
29 #include "pageitem.h"
30 #include "pageitemiterator.h"
31 #include "pagestructs.h"
32 #include "scpage.h"
33 #include "scribusdoc.h"
34
TOCGenerator(QObject * parent,ScribusDoc * doc)35 TOCGenerator::TOCGenerator(QObject *parent, ScribusDoc *doc) : QObject(parent)
36 {
37 m_doc = doc;
38 }
39
setDoc(ScribusDoc * doc)40 void TOCGenerator::setDoc(ScribusDoc *doc)
41 {
42 m_doc = doc;
43 }
44
findTargetFrame(const QString & targetFrameName)45 PageItem* TOCGenerator::findTargetFrame(const QString &targetFrameName)
46 {
47 PageItem* targetFrame=nullptr;
48 if (m_doc != nullptr)
49 {
50 for (int d = 0; d < m_doc->DocItems.count(); ++d)
51 {
52 if (m_doc->DocItems.at(d) != nullptr)
53 {
54 if (m_doc->DocItems.at(d)->itemType()==PageItem::TextFrame && m_doc->DocItems.at(d)->itemName()==targetFrameName)
55 {
56 targetFrame=m_doc->DocItems.at(d);
57 break;
58 }
59 }
60 }
61 }
62 return targetFrame;
63 }
64
generateDefault()65 void TOCGenerator::generateDefault()
66 {
67 if (m_doc == nullptr)
68 return;
69 Q_ASSERT(!m_doc->masterPageMode());
70
71 const ToCSetupVector& topSetups = m_doc->tocSetups();
72 for (auto tocSetupIt = topSetups.cbegin(); tocSetupIt != topSetups.cend(); ++tocSetupIt)
73 {
74 PageItem* tocFrame = findTargetFrame(tocSetupIt->frameName);
75 if (tocFrame == nullptr)
76 continue;
77
78 PageItem *currentDocItem;
79 QMap<QString, QString> tocMap;
80
81 int *pageCounter = new int[m_doc->DocPages.count()];
82 if (pageCounter == nullptr)
83 return;
84 int pageNumberWidth = QString("%1").arg(m_doc->DocPages.count()).length();
85 for (int i = 0; i < m_doc->DocPages.count(); ++i)
86 pageCounter[i] = 0;
87
88 for (PageItemIterator itemIter(m_doc->DocItems); *itemIter; ++itemIter)
89 {
90 currentDocItem = itemIter.current();
91 if (currentDocItem == nullptr)
92 continue;
93 //Item not on a page, continue
94 if (currentDocItem->OwnPage == -1)
95 continue;
96 //If we don't want to list non printing frames and this one is set to not print, continue
97 if (!tocSetupIt->listNonPrintingFrames && !currentDocItem->printEnabled())
98 continue;
99
100 ObjectAttribute objAttr;
101 QList<ObjectAttribute> objAttrs = currentDocItem->getObjectAttributes(tocSetupIt->itemAttrName);
102 if (objAttrs.count() <= 0)
103 continue;
104
105 QString pageID = QString("%1").arg(currentDocItem->OwnPage + m_doc->FirstPnum, pageNumberWidth);
106 QString sectionID = m_doc->getSectionPageNumberForPageIndex(currentDocItem->OwnPage);
107
108 for (int i = 0; i < objAttrs.count(); ++i)
109 {
110 objAttr = objAttrs.at(i);
111 if (objAttr.name.isNull())
112 continue;
113
114 //The key is generated to produce a sequence of numbers for the page numbers
115 //First is the page of the item
116 //Second is an incremented counter for the item so multiple per page works
117 //Third is the section based page number which is actually used in the TOC.
118 QString tocID = QString("%1").arg(pageCounter[currentDocItem->OwnPage]++, 3 , 10, QChar('0'));
119 QString key = QString("%1,%2,%3").arg(pageID, tocID, sectionID);
120 tocMap.insert(key, objAttr.value);
121 }
122 }
123
124 //Set up the gtWriter instance with the selected paragraph style
125 gtWriter writer(false, tocFrame);
126 writer.setUpdateParagraphStyles(false);
127 writer.setOverridePStyleFont(false);
128 gtFrameStyle* fstyle = writer.getDefaultStyle();
129 gtParagraphStyle* pstyle = new gtParagraphStyle(*fstyle);
130 pstyle->setName(tocSetupIt->textStyle);
131 writer.setParagraphStyle(pstyle);
132
133 QString oldTocPage;
134 for (QMap<QString, QString>::Iterator tocIt=tocMap.begin(); tocIt != tocMap.end();++tocIt)
135 {
136 QString tocPage(tocIt.key().section( ',', 2, 2 ).trimmed());
137 QString tocLine;
138 //Start with text or numbers
139 if (tocSetupIt->pageLocation == End || tocSetupIt->pageLocation == NotShown)
140 tocLine = tocIt.value();
141 if (tocSetupIt->pageLocation == Beginning && oldTocPage != tocPage)
142 tocLine = tocPage;
143 //Add in the tab for the leaders
144 tocLine += "\t";
145 //End with text or numbers
146 if (tocSetupIt->pageLocation == Beginning)
147 tocLine += tocIt.value();
148 if (tocSetupIt->pageLocation == End && oldTocPage != tocPage)
149 tocLine += tocPage;
150 tocLine += "\n";
151 writer.append(tocLine);
152 }
153
154 delete[] pageCounter;
155 }
156 }
157