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 #include <QCheckBox>
9 #include <QComboBox>
10 #include <QMessageBox>
11 
12 #include "prefs_documentsections.h"
13 #include "commonstrings.h"
14 #include "prefsstructs.h"
15 #include "scribusdoc.h"
16 #include "ui/numformatcombo.h"
17 #include "ui/scmessagebox.h"
18 
Prefs_DocumentSections(QWidget * parent,ScribusDoc * doc)19 Prefs_DocumentSections::Prefs_DocumentSections(QWidget* parent, ScribusDoc* doc)
20 	: Prefs_Pane(parent),
21 	m_doc(doc), m_maxPageIndex(0)
22 {
23 	setupUi(this);
24 	languageChange();
25 
26 	m_caption = tr("Sections");
27 	m_icon = "tabtocindex_16.png";
28 
29 	connect(sectionsTable, SIGNAL(cellChanged(int,int)), this, SLOT(tableItemChanged(int,int)));
30 	connect(addButton, SIGNAL(clicked()), this, SLOT(addEntry()));
31 	connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteEntry()));
32 }
33 
~Prefs_DocumentSections()34 Prefs_DocumentSections::~Prefs_DocumentSections()
35 {
36 }
37 
languageChange()38 void Prefs_DocumentSections::languageChange()
39 {
40 }
41 
restoreDefaults(struct ApplicationPrefs * prefsData)42 void Prefs_DocumentSections::restoreDefaults(struct ApplicationPrefs *prefsData)
43 {
44 	m_localSections = prefsData->docSectionMap;
45 	m_maxPageIndex = m_doc->DocPages.count()-1;
46 	m_styles.clear();
47 	m_styles = getFormatList();
48 	m_styles << CommonStrings::tr_None;
49 //	styles << tr("1, 2, 3, ...") << tr("i, ii, iii, ...") << tr("I, II, III, ...") << tr("a, b, c, ...") << tr("A, B, C, ...") << tr("*") << tr("CJK") << CommonStrings::tr_None;
50 
51 	updateTable();
52 }
53 
saveGuiToPrefs(struct ApplicationPrefs * prefsData) const54 void Prefs_DocumentSections::saveGuiToPrefs(struct ApplicationPrefs *prefsData) const
55 {
56 	prefsData->docSectionMap=m_localSections;
57 }
58 
updateTable()59 void Prefs_DocumentSections::updateTable()
60 {
61 	sectionsTable->setRowCount(m_localSections.count());
62 	int row=0;
63 	for (DocumentSectionMap::Iterator it = m_localSections.begin(); it!= m_localSections.end(); ++it)
64 	{
65 		uint i=0;
66 		//Name
67 		QTableWidgetItem *item0 = new QTableWidgetItem(it->name);
68 		sectionsTable->setItem(row, i++, item0);
69 		//Active
70 		QTableWidgetItem *item1 = new QTableWidgetItem();
71 		item1->setCheckState(it->active ? Qt::Checked : Qt::Unchecked);
72 		sectionsTable->setItem(row, i++, item1);
73 		//Reversed
74 		QTableWidgetItem *item2 = new QTableWidgetItem();
75 		item2->setCheckState(it->reversed ? Qt::Checked : Qt::Unchecked);
76 		sectionsTable->setItem(row, i++, item2);
77 		//FromIndex
78 		QTableWidgetItem *item3 = new QTableWidgetItem(QString::number(it->fromindex + 1));
79 		sectionsTable->setItem(row, i++, item3);
80 		//ToIndex
81 		QTableWidgetItem *item4 = new QTableWidgetItem(QString::number(it->toindex + 1));
82 		sectionsTable->setItem(row, i++, item4);
83 		//Style
84 		NumFormatCombo *item5 = new NumFormatCombo(nullptr, true);
85 		item5->addItems(m_styles);
86 		sectionsTable->setCellWidget(row, i++, item5);
87 		item5->setCurrentFormat(it->type);
88 		//Start Page Number
89 		QTableWidgetItem *item6 = new QTableWidgetItem(QString::number(it->sectionstartindex));
90 		sectionsTable->setItem(row, i++, item6);
91 		//End Page Number
92 		/*
93 		QTableItem *item7 = new QTableItem(sectionsTable, QTableItem::WhenCurrent, QString::number(it->sectionstartindex + it->toindex - it->fromindex));
94 		item7->setEnabled(false);
95 		sectionsTable->setItem(row, i++, item7);
96 		*/
97 		//Field Width
98 		QTableWidgetItem *item7 = new QTableWidgetItem(QString::number(it->pageNumberWidth));
99 		sectionsTable->setItem(row, i++, item7);
100 		//Fill Char
101 		QTableWidgetItem *item8 = new QTableWidgetItem(QString(it->pageNumberFillChar));
102 		sectionsTable->setItem(row, i++, item8);
103 		//
104 		QTableWidgetItem *t = sectionsTable->verticalHeaderItem(row);
105 		if (t != nullptr)
106 			t->setText(QString("%1").arg(row));
107 		row++;
108 	}
109 	deleteButton->setEnabled(m_localSections.count() > 1);
110 }
111 
tableItemChanged(int row,int col)112 void Prefs_DocumentSections::tableItemChanged( int row, int col )
113 {
114 	bool outOfRange = false;
115 	uint newDocPageSpec;
116 	switch (col)
117 	{
118 		case 0:
119 			m_localSections[row].name = sectionsTable->item(row, col)->text();
120 			break;
121 		case 1:
122 			m_localSections[row].active = (sectionsTable->item(row, col)->checkState() == Qt::Checked);
123 			break;
124 		case 2:
125 			m_localSections[row].reversed = (sectionsTable->item(row, col)->checkState() == Qt::Checked);
126 			break;
127 		case 3:
128 		case 4:
129 			// Validate to/from page specification before conversion to an index
130 			//!!!	There is still a problem here if m_maxPageIndex == MAX_UINT ;)
131 			newDocPageSpec = sectionsTable->item(row, col)->text().toUInt();
132 			if (newDocPageSpec == 0)
133 			{
134 				newDocPageSpec = 1;
135 				outOfRange = true;
136 			}
137 			else if (newDocPageSpec > m_maxPageIndex+1)
138 			{
139 				newDocPageSpec = m_maxPageIndex + 1;
140 				outOfRange = true;
141 			}
142 			// Now, since newDocPageSpec >= 1, convert to index
143 			--newDocPageSpec;
144 			if (col == 3)
145 				m_localSections[row].fromindex = newDocPageSpec;
146 			else
147 				m_localSections[row].toindex = newDocPageSpec;
148 			break;
149 		case 5:
150 			{
151 				NumFormatCombo* qcti = dynamic_cast<NumFormatCombo*>(sectionsTable->cellWidget(row,col));
152 				if (qcti != nullptr)
153 					m_localSections[row].type = qcti->currentFormat();
154 			}
155 			break;
156 		case 6:
157 			m_localSections[row].sectionstartindex = sectionsTable->item(row, col)->text().toUInt();
158 			break;
159 		case 7:
160 			m_localSections[row].pageNumberWidth = sectionsTable->item(row, col)->text().toInt();
161 			break;
162 		case 8:
163 			{
164 				QString ch=sectionsTable->item(row, col)->text();
165 				if (ch.length() > 0)
166 					m_localSections[row].pageNumberFillChar = ch.at(0);
167 				else
168 					m_localSections[row].pageNumberFillChar = QChar();
169 			}
170 			break;
171 		default:
172 			break;
173 	}
174 
175 	if (outOfRange)
176 	{
177 		updateTable();
178 		ScMessageBox::warning(parentWidget(), tr("Page Number Out Of Bounds"),"<qt>"+ tr("The value you have entered is outside the range of page numbers in the current document (%1-%2).").arg(1).arg(m_maxPageIndex+1)+"</qt>");
179 	}
180 }
181 
addEntry()182 void Prefs_DocumentSections::addEntry()
183 {
184 	int currRow=sectionsTable->currentRow();
185 	bool found=false;
186 	DocumentSectionMap::Iterator it = m_localSections.begin();
187 	int count=0;
188 	for (; it != m_localSections.end(); ++it)
189 	{
190 		if(count == currRow)
191 		{
192 			found = true;
193 			break;
194 		}
195 		++count;
196 	}
197 	if (!found) //End of map, just append
198 	{
199 		struct DocumentSection blank;
200 		uint count = m_localSections.count();
201 		blank.number = count;
202 		blank.name = QString::number(count);
203 		blank.fromindex = m_maxPageIndex+1;
204 		blank.toindex = m_maxPageIndex+1;
205 		blank.type = Type_1_2_3;
206 		blank.sectionstartindex = 1;
207 		blank.reversed = false;
208 		blank.active = true;
209 		blank.pageNumberWidth = 0;
210 		m_localSections.insert(count, blank);
211 	}
212 	else
213 	{
214 		//Now, copy to a temp map
215 		DocumentSectionMap tempSections(m_localSections);
216 		m_localSections.clear();
217 		//Copy the temp map entries over. When we find the number of the current row, also insert a new entry.
218 		uint i = 0;
219 		for (DocumentSectionMap::Iterator it2 = tempSections.begin(); it2!= tempSections.end(); ++it2)
220 		{
221 			it2.value().number = i;
222 			m_localSections.insert(i, it2.value());
223 
224 			if (it->number == i)
225 			{
226 				struct DocumentSection blank;
227 				blank.number = ++i;
228 				blank.name = QString::number(i);
229 				blank.fromindex = it->toindex+1;
230 				blank.toindex = it->toindex+2;
231 				blank.type = Type_1_2_3;
232 				blank.sectionstartindex = 1;
233 				blank.reversed = false;
234 				blank.active = true;
235 				blank.pageNumberWidth = 0;
236 				m_localSections.insert(i, blank);
237 			}
238 			++i;
239 		}
240 	}
241 	updateTable();
242 }
243 
deleteEntry()244 void Prefs_DocumentSections::deleteEntry()
245 {
246 	int currRow=sectionsTable->currentRow();
247 	if (currRow==0 && m_localSections.count()==1)
248 		return;
249 	bool found=false;
250 	DocumentSectionMap::Iterator it = m_localSections.begin();
251 	int count=0;
252 	for (; it!= m_localSections.end(); ++it)
253 	{
254 		if(count==currRow)
255 		{
256 			found=true;
257 			break;
258 		}
259 		++count;
260 	}
261 	if (found)
262 	{
263 		//If we arent at the start, copy the toindex of the current item
264 		//to the toindex of the previous item
265 		if (it!=m_localSections.begin())
266 		{
267 			DocumentSectionMap::Iterator it2(it);
268 			(*--it2).toindex=(*it).toindex;
269 		}
270 		//Delete the currently selected entry
271 		m_localSections.erase(it);
272 		//Now, copy to a temp map and reinsert with consecutive keys again
273 		DocumentSectionMap tempSections(m_localSections);
274 		m_localSections.clear();
275 		uint i=0;
276 		it = tempSections.begin();
277 		for (; it!= tempSections.end(); ++it)
278 		{
279 			it.value().number=i;
280 			m_localSections.insert(i++, it.value());
281 		}
282 		int newCount=m_localSections.count();
283 		//int preIndex=qMax(currentIndex-1, 0);
284 		m_localSections[0].fromindex=0;
285 		m_localSections[newCount-1].toindex = m_maxPageIndex;
286 		updateTable();
287 	}
288 }
289