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 
9 #include <QApplication>
10 #include <QBitmap>
11 #include <QComboBox>
12 #include <QCursor>
13 #include <QDrag>
14 #include <QEvent>
15 #include <QHeaderView>
16 #include <QLabel>
17 #include <QList>
18 #include <QMenu>
19 #include <QMimeData>
20 #include <QMessageBox>
21 #include <QPainter>
22 
23 #include "commonstrings.h"
24 #include "iconmanager.h"
25 #include "pagelayout.h"
26 #include "pagepalette_pages.h"
27 #include "pagepalette_widgets.h"
28 #include "scpage.h"
29 #include "scribusapp.h"
30 #include "scribuscore.h"
31 #include "scribusdoc.h"
32 #include "scribusview.h"
33 
PagePalette_Pages(QWidget * parent)34 PagePalette_Pages::PagePalette_Pages(QWidget* parent) : QWidget(parent)
35 {
36 	currView = nullptr;
37 	m_scMW = ScCore->primaryMainWindow();
38 
39 	setupUi(this);
40 
41 	setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Expanding));
42 
43 	masterPageList->setMinimumSize(QSize(200, 40));
44 	masterPageList->m_thumb = false;
45 	masterPageList->setIconSize(QSize(60, 60));
46 
47 	QHeaderView *Header = pageView->verticalHeader();
48 	Header->setSectionsMovable(false);
49 	Header->setSectionResizeMode(QHeaderView::Fixed);
50 	Header->hide();
51 	Header = pageView->horizontalHeader();
52 	Header->setSectionsMovable(false);
53 	Header->setSectionResizeMode(QHeaderView::Fixed);
54 	Header->hide();
55 	pageView->setSortingEnabled(false);
56 	pageView->setSelectionMode( QAbstractItemView::NoSelection );
57 	pageView->setRowCount(1);
58 	pageView->setColumnCount(1);
59 	pageView->setIconSize(QSize(60, 60));
60 
61 	trash->setMinimumSize(QSize(32,32));
62 	trash->setMaximumSize(QSize(32,32));
63 
64 	pix = IconManager::instance().loadPixmap("32/page-simple.png");
65 
66 	rebuild();
67 	languageChange();
68 
69 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
70 
71 	connect(masterPageList, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(selMasterPage()));
72 	connect(masterPageList, SIGNAL(thumbnailChanged()), this, SLOT(rebuildMasters()));
73 	connect(masterPageList, SIGNAL(delMasterRequest(QString)), this, SLOT(deleteMasterPage(QString)));
74 
75 	connect(pageLayout, SIGNAL(selectedLayout(int))   , this, SLOT(handlePageLayout(int)));
76 	connect(pageLayout, SIGNAL(selectedFirstPage(int)), this, SLOT(handleFirstPage(int)));
77 	connect(pageView  , SIGNAL(Click(int,int,int))    , this, SLOT(pageView_gotoPage(int,int,int)));
78 	connect(pageView  , SIGNAL(movePage(int,int))     , this, SLOT(pageView_movePage(int,int)));
79 	connect(pageView  , SIGNAL(delPageRequest(int))   , this, SLOT(pageView_deletePage(int)));
80 	connect(pageView  , SIGNAL(UseTemp(QString,int))  , this, SLOT(pageView_applyMasterPage(QString,int)));
81 	connect(pageView  , SIGNAL(NewPage(int,QString))  , m_scMW, SLOT(slotNewPageP(int,QString)));
82 	connect(trash     , SIGNAL(delPageRequest(int))   , m_scMW, SLOT(deletePage2(int)));
83 	connect(trash     , SIGNAL(delMasterRequest(QString))    , this, SLOT(deleteMasterPage(QString)));
84 
85 	connect(this, SIGNAL(gotoPage(int))          , m_scMW, SLOT(selectPagesFromOutlines(int)));
86 }
87 
deleteMasterPage(const QString & tmp)88 void PagePalette_Pages::deleteMasterPage(const QString& tmp)
89 {
90 	if (tmp == CommonStrings::trMasterPageNormal)
91 		return;
92 	QString extraWarn = "";
93 	for (int i=0; i < currView->m_doc->DocPages.count(); ++i )
94 	{
95 		if (currView->m_doc->DocPages[i]->masterPageName() == tmp)
96 			extraWarn = tr("This master page is used at least once in the document.");
97 	}
98 	int exit = ScMessageBox::warning(this,
99 									  CommonStrings::trWarning,
100 									  tr("Do you really want to delete this master page?")+"\n"+extraWarn,
101 									  QMessageBox::Yes | QMessageBox::No,
102 									  QMessageBox::NoButton,	// GUI default
103 									  QMessageBox::Yes);	// batch default
104 	if (exit == QMessageBox::Yes)
105 	{
106 		bool oldMPMode = currView->m_doc->masterPageMode();
107 		int  storedPageNum = currView->m_doc->currentPageNumber();
108 		int  storedViewXCoor = currView->horizontalScrollBar()->value();
109 		int  storedViewYCoor = currView->verticalScrollBar()->value();
110 
111 		currView->m_doc->setMasterPageMode(true);
112 		currView->m_doc->scMW()->deletePage2(currView->m_doc->MasterNames[tmp]);
113 		//<<CB TODO Move back into ScribusDoc::deleteMasterPage();
114 		//This must happen after the pages have been reformed (view/doc)
115 		currView->m_doc->rebuildMasterNames();
116 		// Fix up any pages that refer to the deleted master page
117 		currView->m_doc->replaceMasterPage(tmp);
118 		currView->m_doc->setMasterPageMode(oldMPMode);
119 		currView->m_doc->setModified(true);
120 
121 		currView->m_doc->setCurrentPage(currView->m_doc->DocPages.at(storedPageNum));
122 		currView->reformPages(false);
123 		currView->setContentsPos(storedViewXCoor, storedViewYCoor);
124 		currView->DrawNew();
125 	}
126 }
127 
pageView_applyMasterPage(const QString & masterpageName,int pageIndex)128 void PagePalette_Pages::pageView_applyMasterPage(const QString& masterpageName, int pageIndex)
129 {
130 	m_scMW->Apply_MasterPage(masterpageName, pageIndex, false);
131 	currView->reformPages();
132 	currView->DrawNew();
133 	SeItem* pageItem = pageView->getPageItem(pageIndex);
134 	if (pageItem)
135 		pageItem->setIcon(createIcon(pageIndex, masterpageName, pix));
136 }
137 
pageView_movePage(int r,int c)138 void PagePalette_Pages::pageView_movePage(int r, int c)
139 {
140 	if ((r == c) || (r >= pageView->m_pageCount))
141 		return;
142 	if (c >= pageView->m_pageCount)
143 		currView->m_doc->movePage(r, r + 1, c, 2);
144 	else
145 		currView->m_doc->movePage(r, r + 1, c, 0);
146 	currView->reformPages();
147 	rebuildPages();
148 	currView->DrawNew();
149 }
150 
pageView_gotoPage(int r,int c,int b)151 void PagePalette_Pages::pageView_gotoPage(int r, int c, int b)
152 {
153 	if ((b == Qt::LeftButton) && (r != -1) && (c != -1))
154 	{
155 		int p;
156 		bool dummy;
157 		p = pageView->getPage(r, c, &dummy);
158 		emit gotoPage(p);
159 	}
160 }
161 
pageView_deletePage(int pageIndex)162 void PagePalette_Pages::pageView_deletePage(int pageIndex)
163 {
164 	int exit = ScMessageBox::question(this, tr("Delete Page?"),
165 			                          "<qt>" + tr("Are you sure you want to delete this page?") + "</qt>",
166 			                          QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
167 	if (exit != QMessageBox::Yes)
168 		return;
169 	m_scMW->deletePage2(pageIndex);
170 }
171 
enablePalette(const bool enabled)172 void PagePalette_Pages::enablePalette(const bool enabled)
173 {
174 	pageView->setEnabled(enabled);
175 	masterPageList->setEnabled(enabled);
176 	pageLayout->setEnabled(enabled);
177 }
178 
handlePageLayout(int layout)179 void PagePalette_Pages::handlePageLayout(int layout)
180 {
181 	pageLayout->selectFirstP(currView->m_doc->pageSets()[layout].FirstPage);
182 	currView->m_doc->setPagePositioning(layout);
183 	currView->reformPages();
184 	currView->DrawNew();
185 	currView->GotoPage(currView->m_doc->currentPageNumber());
186 	rebuildPages();
187 }
188 
handleFirstPage(int fp)189 void PagePalette_Pages::handleFirstPage(int fp)
190 {
191 	currView->m_doc->setPageSetFirstPage(currView->m_doc->pagePositioning(), fp);
192 	currView->reformPages();
193 	currView->DrawNew();
194 	currView->GotoPage(currView->m_doc->currentPageNumber());
195 	rebuildPages();
196 }
197 
rebuildMasters()198 void PagePalette_Pages::rebuildMasters()
199 {
200 	if (m_scMW->scriptIsRunning())
201 		return;
202 	masterPageList->clear();
203 	if (currView == nullptr)
204 		return;
205 	QPixmap pm;
206 	QListWidgetItem* item;
207 	QMap<QString,int>::Iterator it;
208 	for (it = currView->m_doc->MasterNames.begin(); it != currView->m_doc->MasterNames.end(); ++it)
209 	{
210 		const QString& pageName = it.key();
211 		QString pageLabel = (pageName == CommonStrings::masterPageNormal) ? CommonStrings::trMasterPageNormal : pageName;
212 		if (masterPageList->m_thumb)
213 		{
214 			pm = QPixmap::fromImage(currView->MPageToPixmap(pageName, 60));
215 			item = new QListWidgetItem(QIcon(pm), pageLabel, masterPageList);
216 		}
217 		else
218 			item = new QListWidgetItem(pageLabel, masterPageList);
219 		item->setData(Qt::UserRole, pageName);
220 	}
221 }
222 
rebuildPages()223 void PagePalette_Pages::rebuildPages()
224 {
225 	if (m_scMW->scriptIsRunning())
226 		return;
227 	QString str;
228 	disconnect(pageLayout, SIGNAL(selectedLayout(int)), this, SLOT(handlePageLayout(int)));
229 	disconnect(pageLayout, SIGNAL(selectedFirstPage(int)), this, SLOT(handleFirstPage(int)));
230 	pageView->clearContents();
231 	pageView->setRowCount(1);
232 	pageView->setColumnCount(1);
233 	if (currView == nullptr)
234 	{
235 		connect(pageLayout, SIGNAL(selectedLayout(int)), this, SLOT(handlePageLayout(int)));
236 		connect(pageLayout, SIGNAL(selectedFirstPage(int)), this, SLOT(handleFirstPage(int)));
237 		return;
238 	}
239 	pageLayout->updateLayoutSelector(currView->m_doc->pageSets());
240 	pageLayout->selectItem(currView->m_doc->pagePositioning());
241 	pageLayout->firstPage->setCurrentIndex(currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].FirstPage);
242 	pageView->m_pageCount = currView->m_doc->DocPages.count();
243 	int counter = currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].FirstPage;
244 	int cols = currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].Columns;
245 	int rows = (currView->m_doc->DocPages.count()+counter) / currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].Columns;
246 	if (((currView->m_doc->DocPages.count()+counter) % currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].Columns) != 0)
247 		rows++;
248 	int rowcounter = 0;
249 	int colmult, rowmult, coladd, rowadd;
250 	if (cols == 1)
251 	{
252 		pageView->setColumnCount(cols);
253 		pageView->setRowCount(rows*2+1);
254 		colmult = 1;
255 		coladd = 0;
256 		rowmult = 2;
257 		rowadd = 1;
258 	}
259 	else
260 	{
261 		pageView->setColumnCount(cols*2);
262 		pageView->setRowCount(rows+1);
263 		colmult = 2;
264 		coladd = 1;
265 		rowmult = 1;
266 		rowadd = 0;
267 	}
268 	for (int rr = 0; rr < pageView->rowCount(); rr++)
269 	{
270 		for (int cc = 0; cc < pageView->columnCount(); cc++)
271 		{
272 			QTableWidgetItem *tW = new QTableWidgetItem(1001);
273 			tW->setFlags(Qt::ItemIsEnabled);
274 			pageView->setItem(rr, cc, tW);
275 		}
276 	}
277 	pageView->m_coladd = coladd;
278 	pageView->m_colmult = colmult;
279 	pageView->m_rowadd = rowadd;
280 	pageView->m_rowmult = rowmult;
281 	pageView->m_firstPage = counter;
282 	pageView->m_cols = currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].Columns;
283 	pageList.clear();
284 	for (int a = 0; a < currView->m_doc->DocPages.count(); ++a)
285 	{
286 		str = currView->m_doc->DocPages.at(a)->masterPageName();
287 		SeItem *it = new SeItem(str, a, createIcon(a, str, pix));
288 		pageList.append(it);
289 		pageView->setItem(rowcounter*rowmult+rowadd, counter*colmult+coladd, (QTableWidgetItem *)it);
290 		pageView->setColumnWidth(counter*colmult+coladd, pix.width());
291 		if (cols == 1)
292 		{
293 			pageView->setRowHeight(rowcounter*rowmult, 10);
294 			pageView->setRowHeight(rowcounter*rowmult+rowadd, pix.height());
295 		}
296 		else
297 			pageView->setRowHeight(rowcounter*rowmult+rowadd, pix.height()+5);
298 		counter++;
299 		if (counter > currView->m_doc->pageSets()[currView->m_doc->pagePositioning()].Columns-1)
300 		{
301 			counter = 0;
302 			rowcounter++;
303 		}
304 	}
305 	pageView->setRowHeight(pageView->rowCount()-1, 10);
306 	counter = 0;
307 	if (cols != 1)
308 	{
309 		for (int c = 0; c < pageView->columnCount(); ++c)
310 		{
311 			if ((counter % 2) == 0)
312 				pageView->setColumnWidth(counter, 10);
313 			else
314 				pageView->setColumnWidth(counter, pix.width());
315 			counter++;
316 		}
317 	}
318 	pageView->repaint();
319 	if (currView != nullptr)
320 		markPage(currView->m_doc->currentPageNumber());
321 	connect(pageLayout, SIGNAL(selectedLayout(int)), this, SLOT(handlePageLayout(int)));
322 	connect(pageLayout, SIGNAL(selectedFirstPage(int)), this, SLOT(handleFirstPage(int)));
323 }
324 
rebuild()325 void PagePalette_Pages::rebuild()
326 {
327 	rebuildMasters();
328 	rebuildPages();
329 	enablePalette(currView != nullptr);
330 }
331 
markPage(uint nr)332 void PagePalette_Pages::markPage(uint nr)
333 {
334 	if (currView == nullptr)
335 		return;
336 
337 	SeItem *it;
338 	for (int i = 0; i < pageList.count(); i++)
339 	{
340 		it = pageList.at(i);
341 		if (it->pageNumber == nr)
342 		{
343 			pageView->clearSelection();
344 			pageView->item(it->row(), it->column())->setSelected(true);
345 			pageView->scrollToItem(pageView->item(it->row(), it->column()), QAbstractItemView::EnsureVisible);
346 			break;
347 		}
348 	}
349 }
350 
setView(ScribusView * view)351 void PagePalette_Pages::setView(ScribusView *view)
352 {
353 	if (m_scMW->scriptIsRunning())
354 		return;
355 	currView = view;
356 }
357 
selMasterPage()358 void PagePalette_Pages::selMasterPage()
359 {
360 	if (masterPageList->m_currItem == nullptr)
361 		return;
362 	QVariant pageVar = masterPageList->m_currItem->data(Qt::UserRole);
363 	emit gotoMasterPage(pageVar.toString());
364 }
365 
createIcon(int number,QString masterPage,const QPixmap & pixin)366 QPixmap PagePalette_Pages::createIcon(int number, QString masterPage, const QPixmap& pixin)
367 {
368 	QPainter p;
369 	// Necessary on windows to ensure the pixmap is drawable
370 	QPixmap ret(pixin.width(), pixin.height()); // Qt4, pixin.depth());
371 	if (p.begin(&ret))
372 	{
373 		p.drawPixmap( 0, 0, pixin );
374 //		if( !pixin.mask().isNull() )
375 //			ret.setMask( pixin.mask() );
376 		p.setBrush(Qt::white);
377 		p.setBackground(Qt::white);
378 		p.setBackgroundMode(Qt::OpaqueMode);
379 		p.setPen(QPen(Qt::black, 0, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin));
380 		//p.setFont(QFont("Helvetica", 12, QFont::Bold));
381 		//QString tmp = tmp.setNum(nr+1);
382 		QString tmp(currView->m_doc->getSectionPageNumberForPageIndex(number));
383 		if (tmp.isEmpty())
384 			tmp = tmp.setNum(number + 1);
385 		QRegExp Exp ("([A-Z]*[0-9]*)( *[\\.|\\-|_] *)(.*)");
386 		if (Exp.indexIn(masterPage) != -1)
387 			masterPage = Exp.cap(1);
388 		QRect d = QRect(0, 0, ret.width(), ret.height());
389 	//	p.fillRect(d.adjusted(-1, -1, -1, -1), color);
390 		p.setFont(QFont("Helvetica", 7, QFont::Normal));
391 		p.drawText(d, Qt::AlignCenter, tmp+"\n"+masterPage);
392 		p.end();
393 		if( !pixin.mask().isNull() )
394 			ret.setMask( pixin.mask() );
395 	}
396 	return ret;
397 }
398 
changeEvent(QEvent * e)399 void PagePalette_Pages::changeEvent(QEvent *e)
400 {
401 	if (e->type() == QEvent::LanguageChange)
402 	{
403 		languageChange();
404 		return;
405 	}
406 
407 	QWidget::changeEvent(e);
408 }
409 
iconSetChange()410 void PagePalette_Pages::iconSetChange()
411 {
412 	pix = IconManager::instance().loadPixmap("32/page-simple.png");
413 	if (currView != nullptr)
414 		rebuild();
415 }
416 
languageChange()417 void PagePalette_Pages::languageChange()
418 {
419 	retranslateUi(this);
420 }
421