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 **
10 ** Created: Son Jun 2 11:23:14 2002
11 **      by:  Franz Schmid
12 **
13 **
14 ****************************************************************************/
15 
16 #include "layers.h"
17 
18 #include <QCheckBox>
19 #include <QColorDialog>
20 #include <QComboBox>
21 #include <QEvent>
22 #include <QHBoxLayout>
23 #include <QHeaderView>
24 #include <QLabel>
25 #include <QMessageBox>
26 #include <QPixmap>
27 #include <QSignalBlocker>
28 #include <QSpacerItem>
29 #include <QTableWidget>
30 #include <QTableWidgetItem>
31 #include <QToolButton>
32 #include <QToolTip>
33 #include <QVBoxLayout>
34 
35 #include "iconmanager.h"
36 #include "sclayer.h"
37 #include "scribus.h"
38 #include "scribusapp.h"
39 #include "scribusdoc.h"
40 #include "selection.h"
41 #include "ui/scrspinbox.h"
42 #include "undomanager.h"
43 
LayerPalette(QWidget * parent)44 LayerPalette::LayerPalette(QWidget* parent) : ScDockPalette(parent, "Layers", Qt::WindowFlags()), m_Doc(nullptr)
45 {
46 	setObjectName(QString::fromLocal8Bit("Layers"));
47 	setMinimumSize( QSize(220, 240) );
48 	setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
49 	containerWidget = new QWidget(this);
50 	LayerPaletteLayout = new QVBoxLayout();
51 	LayerPaletteLayout->setContentsMargins(3, 3, 3, 3);
52 	LayerPaletteLayout->setSpacing(3);
53 
54 	layout1 = new QHBoxLayout;
55 	layout1->setContentsMargins(0, 0, 0, 0);
56 	layout1->setSpacing(3);
57 	textLabel1 = new QLabel( this);
58 	layout1->addWidget( textLabel1 );
59 	blendMode = new QComboBox( this);
60 	layout1->addWidget( blendMode );
61 	textLabel2 = new QLabel( this);
62 	textLabel2->setText( tr( "Opacity:" ) );
63 	layout1->addWidget( textLabel2 );
64 	opacitySpinBox = new ScrSpinBox( this);
65 	opacitySpinBox->setMinimum(0);
66 	opacitySpinBox->setMaximum(100);
67 	opacitySpinBox->setSingleStep(10);
68 	opacitySpinBox->setDecimals(0);
69 	opacitySpinBox->setSuffix( tr(" %"));
70 	opacitySpinBox->setFocusPolicy(Qt::ClickFocus);
71 	layout1->addWidget( opacitySpinBox );
72 	LayerPaletteLayout->addLayout( layout1 );
73 
74 	IconManager& im = IconManager::instance();
75 	Table = new QTableWidget(0, 8, this );
76 	Table->setHorizontalHeaderItem(0, new QTableWidgetItem(""));
77 	Table->setHorizontalHeaderItem(1, new QTableWidgetItem(im.loadIcon("16/show-object.png"), ""));
78 	Table->setHorizontalHeaderItem(2, new QTableWidgetItem(im.loadIcon("16/document-print.png"), ""));
79 	Table->setHorizontalHeaderItem(3, new QTableWidgetItem(im.loadIcon("16/lock.png"), ""));
80 	Table->setHorizontalHeaderItem(4, new QTableWidgetItem(im.loadIcon("16/layer-flow-around.png"), ""));
81 	Table->setHorizontalHeaderItem(5, new QTableWidgetItem(im.loadIcon("layer-outline.png"), ""));
82 	Table->setHorizontalHeaderItem(6, new QTableWidgetItem(im.loadIcon("16/pointer.png"), ""));
83 	Table->setHorizontalHeaderItem(7, new QTableWidgetItem( tr("Name")));
84 
85 	QHeaderView *header = Table->horizontalHeader();
86 	header->setStretchLastSection(true);
87 	header->setSectionsClickable(false );
88 	header->setSectionsMovable( false );
89 	header->setSectionResizeMode(QHeaderView::Fixed);
90 	header->setHighlightSections(false);
91 	header->setMaximumSectionSize(24);
92 
93 	Table->setColumnWidth(0, 24);
94 	Table->setColumnWidth(1, 24);
95 	Table->setColumnWidth(2, 24);
96 	Table->setColumnWidth(3, 24);
97 	Table->setColumnWidth(4, 24);
98 	Table->setColumnWidth(5, 24);
99 	Table->setColumnWidth(6, 24);
100 	Table->setSortingEnabled(false);
101 	Table->setSelectionBehavior( QAbstractItemView::SelectRows );
102 	QHeaderView *Header = Table->verticalHeader();
103 	Header->setSectionsMovable( false );
104 	Header->setSectionResizeMode(QHeaderView::Fixed);
105 	Header->hide();
106 	LayerPaletteLayout->addWidget( Table );
107 
108 	Layout1 = new QHBoxLayout;
109 	Layout1->setContentsMargins(0, 0, 0, 0);
110 	Layout1->setSpacing(3);
111 	QSpacerItem* spacer = new QSpacerItem( 0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum );
112 	Layout1->addItem( spacer );
113 
114 	newLayerButton = new QToolButton( this );
115 	newLayerButton->setIconSize(QSize(16, 16));
116 	newLayerButton->setMinimumSize( QSize( 48, 0 ) );
117 	newLayerButton->setMaximumSize( QSize( 48, 16777215 ) );
118 	newLayerButton->setText( "" );
119 	newLayerButton->setIcon(IconManager::instance().loadIcon("16/list-add.png"));
120 	Layout1->addWidget( newLayerButton );
121 
122 	deleteLayerButton = new QToolButton( this );
123 	deleteLayerButton->setIconSize(QSize(16, 16));
124 	deleteLayerButton->setMinimumSize( QSize( 48, 0 ) );
125 	deleteLayerButton->setMaximumSize( QSize( 48, 16777215 ) );
126 	deleteLayerButton->setText( "" );
127 	deleteLayerButton->setIcon(IconManager::instance().loadIcon("16/list-remove.png"));
128 	Layout1->addWidget( deleteLayerButton );
129 
130 	duplicateLayerButton = new QToolButton( this );
131 	duplicateLayerButton->setIconSize(QSize(16, 16));
132 	duplicateLayerButton->setMinimumSize( QSize( 48, 0 ) );
133 	duplicateLayerButton->setMaximumSize( QSize( 48, 16777215 ) );
134 	duplicateLayerButton->setText( "" );
135 	duplicateLayerButton->setIcon(IconManager::instance().loadIcon("16/edit-copy.png"));
136 	Layout1->addWidget( duplicateLayerButton );
137 
138 	raiseLayerButton = new QToolButton( this );
139 	raiseLayerButton->setIconSize(QSize(16, 16));
140 	raiseLayerButton->setMinimumSize( QSize( 48, 0 ) );
141 	raiseLayerButton->setMaximumSize( QSize( 48, 16777215 ) );
142 	raiseLayerButton->setText( "" );
143 	raiseLayerButton->setIcon(IconManager::instance().loadIcon("16/go-up.png"));
144 	Layout1->addWidget( raiseLayerButton );
145 
146 	lowerLayerButton = new QToolButton( this );
147 	lowerLayerButton->setIconSize(QSize(16, 16));
148 	lowerLayerButton->setMinimumSize( QSize( 48, 0 ) );
149 	lowerLayerButton->setMaximumSize( QSize( 48, 16777215 ) );
150 	lowerLayerButton->setText( "" );
151 	lowerLayerButton->setIcon(IconManager::instance().loadIcon("16/go-down.png"));
152 	Layout1->addWidget( lowerLayerButton );
153 
154 	LayerPaletteLayout->addLayout( Layout1 );
155 	containerWidget->setLayout( LayerPaletteLayout );
156 	setWidget( containerWidget );
157 	clearContent();
158 	languageChange();
159 
160 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
161 
162 	connect(newLayerButton, SIGNAL(clicked()), this, SLOT(addLayer()));
163 	connect(duplicateLayerButton, SIGNAL(clicked()), this, SLOT(dupLayer()));
164 	connect(deleteLayerButton, SIGNAL(clicked()), this, SLOT(removeLayer()));
165 	connect(raiseLayerButton, SIGNAL(clicked()), this, SLOT(upLayer()));
166 	connect(lowerLayerButton, SIGNAL(clicked()), this, SLOT(downLayer()));
167 	connect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
168 	connect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
169 	connect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
170 	connect(header, SIGNAL(sectionClicked(int)), this, SLOT(toggleAllfromHeader(int)));
171 }
172 
installEventFilter(QObject * obj)173 void LayerPalette::installEventFilter(QObject *obj)
174 {
175 	ScDockPalette::installEventFilter(obj);
176 	Table->installEventFilter(obj);
177 }
178 
clearContent()179 void LayerPalette::clearContent()
180 {
181 	disconnect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
182 	disconnect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
183 	disconnect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
184 	disconnect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
185 	Table->clearContents();
186 	Table->setRowCount(0);
187 	m_Doc = nullptr;
188 	newLayerButton->setEnabled(false);
189 	deleteLayerButton->setEnabled(false);
190 	raiseLayerButton->setEnabled(false);
191 	lowerLayerButton->setEnabled(false);
192 }
193 
setDoc(ScribusDoc * doc)194 void LayerPalette::setDoc(ScribusDoc* doc)
195 {
196 	m_Doc=doc;
197 	disconnect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
198 	disconnect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
199 	disconnect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
200 	disconnect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
201 	if (!m_Doc)
202 	{
203 		layers = nullptr;
204 		newLayerButton->setEnabled(false);
205 		duplicateLayerButton->setEnabled(false);
206 		deleteLayerButton->setEnabled(false);
207 		raiseLayerButton->setEnabled(false);
208 		lowerLayerButton->setEnabled(false);
209 		markActiveLayer(0);
210 	}
211 	layers = &m_Doc->Layers;
212 	rebuildList();
213 
214 	markActiveLayer(m_Doc->activeLayer());
215 	newLayerButton->setEnabled(true);
216 	duplicateLayerButton->setEnabled(true);
217 
218 	connect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
219 	connect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
220 	connect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
221 	connect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
222 }
223 
rebuildList()224 void LayerPalette::rebuildList()
225 {
226 	disconnect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
227 	disconnect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
228 	disconnect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
229 	disconnect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
230 	QString tmp;
231 	int layerCount = m_Doc->layerCount();
232 	Table->setRowCount(layerCount);
233 	for (auto it = layers->begin(); it != layers->end(); ++it)
234 	{
235 		int layerID = it->ID;
236 		//TODO once "layers" is not set anymore, need to get layer number differently
237 		int layerLevel = m_Doc->layerLevelFromID(layerID);
238 		tmp = tmp.setNum(layerLevel);
239 		int row = layerCount-layerLevel - 1;
240 		QToolButton *pb = new QToolButton(this);
241 		pb->setObjectName(tmp);
242 		pb->setAutoRaise(true);
243 		pb->setText( "" );
244 		QPixmap pm(20,15);
245 		pm.fill(m_Doc->layerMarker(layerID));
246 		pb->setIcon(pm);
247 		Table->setCellWidget(row, 0, pb);
248 		connect(pb, SIGNAL(clicked()), this, SLOT(markLayer()));
249 
250 		QWidget *cw1 = new QWidget(Table);
251 		QCheckBox *cp1 = new QCheckBox(cw1);
252 		cp1->setObjectName(tmp);
253 		QHBoxLayout *cl1 = new QHBoxLayout(cw1);
254 		cl1->addWidget(cp1);
255 		cl1->setAlignment(Qt::AlignCenter);
256 		cl1->setContentsMargins(0, 0, 0, 0);
257 		Table->setCellWidget(row, 1, cw1);
258 		cp1->setChecked(m_Doc->layerVisible(layerID));
259 		connect(cp1, SIGNAL(clicked()), this, SLOT(visibleLayer()));
260 
261 		QWidget *cw2 = new QWidget(Table);
262 		QCheckBox *cp2 = new QCheckBox(cw2);
263 		cp2->setObjectName(tmp);
264 		cp2->setChecked(m_Doc->layerPrintable(layerID));
265 		QHBoxLayout *cl2 = new QHBoxLayout(cw2);
266 		cl2->addWidget(cp2);
267 		cl2->setAlignment(Qt::AlignCenter);
268 		cl2->setContentsMargins(0, 0, 0, 0);
269 		Table->setCellWidget(row, 2, cw2);
270 		connect(cp2, SIGNAL(clicked()), this, SLOT(printLayer()));
271 
272 		QWidget *cw3 = new QWidget(Table);
273 		QCheckBox *cp3 = new QCheckBox(cw3);
274 		cp3->setObjectName(tmp);
275 		cp3->setChecked(m_Doc->layerLocked(layerID));
276 		QHBoxLayout *cl3 = new QHBoxLayout(cw3);
277 		cl3->addWidget(cp3);
278 		cl3->setAlignment(Qt::AlignCenter);
279 		cl3->setContentsMargins(0, 0, 0, 0);
280 		Table->setCellWidget(row, 3, cw3);
281 		connect(cp3, SIGNAL(clicked()), this, SLOT(lockLayer()));
282 
283 		QWidget *cw4 = new QWidget(Table);
284 		QCheckBox *cp4 = new QCheckBox(cw4);
285 		cp4->setObjectName(tmp);
286 		cp4->setChecked(m_Doc->layerFlow(layerID));
287 		QHBoxLayout *cl4 = new QHBoxLayout(cw4);
288 		cl4->addWidget(cp4);
289 		cl4->setAlignment(Qt::AlignCenter);
290 		cl4->setContentsMargins(0, 0, 0, 0);
291 		Table->setCellWidget(row, 4, cw4);
292 		connect(cp4, SIGNAL(clicked()), this, SLOT(flowToggleLayer()));
293 
294 		QWidget *cw5 = new QWidget(Table);
295 		QCheckBox *cp5 = new QCheckBox(cw5);
296 		cp5->setObjectName(tmp);
297 		cp5->setChecked(m_Doc->layerOutline(layerID));
298 		QHBoxLayout *cl5 = new QHBoxLayout(cw5);
299 		cl5->addWidget(cp5);
300 		cl5->setAlignment(Qt::AlignCenter);
301 		cl5->setContentsMargins(0, 0, 0, 0);
302 		Table->setCellWidget(row, 5, cw5);
303 		connect(cp5, SIGNAL(clicked()), this, SLOT(outlineToggleLayer()));
304 
305 		QWidget *cw6 = new QWidget(Table);
306 		QCheckBox *cp6 = new QCheckBox(cw6);
307 		cp6->setObjectName(tmp);
308 		cp6->setChecked(m_Doc->layerSelectable(layerID));
309 		QHBoxLayout *cl6 = new QHBoxLayout(cw6);
310 		cl6->addWidget(cp6);
311 		cl6->setAlignment(Qt::AlignCenter);
312 		cl6->setContentsMargins(0, 0, 0, 0);
313 		Table->setCellWidget(row, 6, cw6);
314 		connect(cp6, SIGNAL(clicked()), this, SLOT(selectToggleLayer()));
315 
316 		Table->setItem(row, 7, new QTableWidgetItem(m_Doc->layerName(layerID)));
317 	}
318 	connect(Table, SIGNAL(cellChanged(int,int)), this, SLOT(changeName(int,int)));
319 	connect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
320 	connect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
321 	connect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
322 }
323 
addLayer()324 void LayerPalette::addLayer()
325 {
326 	if (!m_Doc)
327 		return;
328 	m_Doc->addLayer(QString(), true);
329 	rebuildList();
330 	markActiveLayer();
331 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
332 }
333 
dupLayer()334 void LayerPalette::dupLayer()
335 {
336 	if (!m_Doc)
337 		return;
338 	UndoTransaction copyTransaction;
339 	if (UndoManager::undoEnabled())
340 		copyTransaction = UndoManager::instance()->beginTransaction("", Um::ILayerAction, Um::DuplicateLayer.arg(m_Doc->activeLayerName()) , "", Um::ICreate);
341 
342 	int current = m_Doc->activeLayer();
343 
344 	m_Doc->addLayer(QString(), true);
345 	rebuildList();
346 	markActiveLayer();
347 	m_Doc->copyLayer(current, m_Doc->activeLayer());
348 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
349 	if (copyTransaction)
350 		copyTransaction.commit();
351 }
352 
removeLayer()353 void LayerPalette::removeLayer()
354 {
355 	if (!m_Doc)
356 		return;
357 	int layerCount = m_Doc->layerCount();
358 	if (layerCount < 2)
359 		return;
360 	int level = layerCount-1-Table->currentRow();
361 	int layerID = m_Doc->layerIDFromLevel(level);
362 	bool delToo = false;
363 	if (m_Doc->layerContainsItems(layerID))
364 	{
365 		int scmReturn = ScMessageBox::warning(this, tr("Delete Layer"),
366 									tr("Do you want to delete all objects on this layer too?"),
367 									QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel,
368 									QMessageBox::No,	// GUI default
369 									QMessageBox::Yes);	// batch default
370 		if (scmReturn == QMessageBox::Cancel)
371 			return;
372 		delToo = (scmReturn != QMessageBox::No);
373 	}
374 
375 	if (!m_Doc->deleteLayer(layerID, delToo))
376 		return;
377 
378 	rebuildList();
379 	markActiveLayer();
380 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
381 }
382 
upLayer()383 void LayerPalette::upLayer()
384 {
385 	if (!m_Doc)
386 		return;
387 	int layerCount = m_Doc->layerCount();
388 	if ((layerCount < 2) || (Table->currentRow() == 0))
389 		return;
390 	int layerLevel = layerCount-1-Table->currentRow();
391 	m_Doc->raiseLayerByLevel(layerLevel);
392 	rebuildList();
393 	markActiveLayer();
394 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
395 	emit LayerChanged();
396 	m_Doc->changed();
397 }
398 
downLayer()399 void LayerPalette::downLayer()
400 {
401 	if (!m_Doc)
402 		return;
403 	int layerCount = m_Doc->layerCount();
404 	if ((layerCount < 2) || (Table->currentRow() == static_cast<int>(layerCount) - 1))
405 		return;
406 	int layerLevel = layerCount-1-Table->currentRow();
407 	m_Doc->lowerLayerByLevel(layerLevel);
408 	rebuildList();
409 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
410 	emit LayerChanged();
411 	markActiveLayer();
412 	m_Doc->changed();
413 }
414 
changeName(int row,int col)415 void LayerPalette::changeName(int row, int col)
416 {
417 	if (!m_Doc)
418 		return;
419 	if (col == 7)
420 	{
421 		int layerLevel = m_Doc->layerCount()-1-row;
422 		int layerID = m_Doc->layerIDFromLevel(layerLevel);
423 		if (layerID != -1)
424 			m_Doc->changeLayerName(layerID, Table->item(row, col)->text());
425 	}
426 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
427 }
428 
visibleLayer()429 void LayerPalette::visibleLayer()
430 {
431 	if (!m_Doc)
432 		return;
433 	int level = sender()->objectName().toInt();
434 	int layerID = m_Doc->layerIDFromLevel(level);
435 	if (layerID == -1)
436 		return;
437 	const QObject* senderBox = sender();
438 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
439 	{
440 		bool isLayerVisible = ((QCheckBox*)(senderBox))->isChecked();
441 		m_Doc->setLayerVisible(layerID, isLayerVisible);
442 		if (!isLayerVisible)
443 			m_Doc->m_Selection->removeItemsOfLayer(layerID);
444 		setActiveLayer(Table->currentRow(), -1);
445 		emit LayerChanged();
446 	}
447 }
448 
printLayer()449 void LayerPalette::printLayer()
450 {
451 	if (!m_Doc)
452 		return;
453 	int level = sender()->objectName().toInt();
454 	int layerID = m_Doc->layerIDFromLevel(level);
455 	if (layerID == -1)
456 		return;
457 	const QObject* senderBox = sender();
458 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
459 	{
460 		m_Doc->setLayerPrintable(layerID, ((QCheckBox*)(senderBox))->isChecked());
461 		setActiveLayer(Table->currentRow(), -1);
462 		emit LayerChanged();
463 	}
464 }
465 
lockLayer()466 void LayerPalette::lockLayer()
467 {
468 	if (!m_Doc)
469 		return;
470 	int level = sender()->objectName().toInt();
471 	int layerID = m_Doc->layerIDFromLevel(level);
472 	if (layerID == -1)
473 		return;
474 	const QObject* senderBox = sender();
475 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
476 	{
477 		bool isLayerLocked = ((QCheckBox*)(senderBox))->isChecked();
478 		m_Doc->setLayerLocked(layerID, isLayerLocked);
479 		if (isLayerLocked)
480 			m_Doc->m_Selection->removeItemsOfLayer(layerID);
481 		deleteLayerButton->setEnabled(!isLayerLocked);
482 		setActiveLayer(Table->currentRow(), -1);
483 	}
484 	m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
485 }
486 
flowToggleLayer()487 void LayerPalette::flowToggleLayer()
488 {
489 	if (!m_Doc)
490 		return;
491 	int level = sender()->objectName().toInt();
492 	int layerID = m_Doc->layerIDFromLevel(level);
493 	if (layerID == -1)
494 		return;
495 	const QObject* senderBox = sender();
496 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
497 	{
498 		m_Doc->setLayerFlow(layerID, ((QCheckBox*)(senderBox))->isChecked());
499 		emit LayerChanged();
500 		setActiveLayer(Table->currentRow(), -1);
501 	}
502 }
503 
outlineToggleLayer()504 void LayerPalette::outlineToggleLayer()
505 {
506 	if (!m_Doc)
507 		return;
508 	int level = sender()->objectName().toInt();
509 	int layerID = m_Doc->layerIDFromLevel(level);
510 	if (layerID == -1)
511 		return;
512 	const QObject* senderBox = sender();
513 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
514 	{
515 		m_Doc->setLayerOutline(layerID, ((QCheckBox*)(senderBox))->isChecked());
516 		emit LayerChanged();
517 		setActiveLayer(Table->currentRow(), -1);
518 	}
519 }
520 
selectToggleLayer()521 void LayerPalette::selectToggleLayer()
522 {
523 	if (!m_Doc)
524 		return;
525 	int level = sender()->objectName().toInt();
526 	int layerID = m_Doc->layerIDFromLevel(level);
527 	if (layerID == -1)
528 		return;
529 	const QObject* senderBox = sender();
530 	if (strcmp(senderBox->metaObject()->className(), "QCheckBox") == 0)
531 	{
532 		bool isLayerSelectable = ((QCheckBox*)(senderBox))->isChecked();
533 		m_Doc->setLayerSelectable(layerID, isLayerSelectable);
534 		emit LayerChanged();
535 		setActiveLayer(Table->currentRow(), -1);
536 	}
537 }
538 
toggleAllfromHeader(int index)539 void LayerPalette::toggleAllfromHeader(int index)
540 {
541 	if (!m_Doc)
542 		return;
543 
544 	int layerCount = m_Doc->layerCount();
545 	for (auto it = layers->begin(); it != layers->end(); ++it)
546 	{
547 		int row = layerCount - m_Doc->layerLevelFromID(it->ID) - 1;
548 		if (index == 1)
549 		{
550 			(dynamic_cast<QCheckBox*>(Table->cellWidget(row, 1)))->toggle();
551 			it->isViewable = ((QCheckBox*)(Table->cellWidget(row, 1)))->isChecked();
552 		}
553 		if (index == 2)
554 		{
555 			(dynamic_cast<QCheckBox*>(Table->cellWidget(row, 2)))->toggle();
556 			it->isPrintable = ((QCheckBox*)(Table->cellWidget(row, 2)))->isChecked();
557 		}
558 		if (index == 3)
559 		{
560 			(dynamic_cast<QCheckBox*>(Table->cellWidget(row, 3)))->toggle();
561 			it->isEditable = !((QCheckBox*)(Table->cellWidget(row, 3)))->isChecked();
562 		}
563 		if (index == 4)
564 		{
565 			(dynamic_cast<QCheckBox*>(Table->cellWidget(row, 4)))->toggle();
566 			it->flowControl = ((QCheckBox*)(Table->cellWidget(row, 4)))->isChecked();
567 		}
568 		else if (index == 5)
569 		{
570 			(dynamic_cast<QCheckBox*>(Table->cellWidget(row, 5)))->toggle();
571 			it->outlineMode = ((QCheckBox*)(Table->cellWidget(row, 5)))->isChecked();
572 		}
573 	}
574 	emit LayerChanged();
575 }
576 
markLayer()577 void LayerPalette::markLayer()
578 {
579 	if (!m_Doc)
580 		return;
581 	int level = sender()->objectName().toInt();
582 	int layerID = m_Doc->layerIDFromLevel(level);
583 	if (layerID == -1)
584 		return;
585 	const QObject* senderBox = sender();
586 	if (strcmp(senderBox->metaObject()->className(), "QToolButton") == 0)
587 	{
588 		QColor neu(QColorDialog::getColor(m_Doc->layerMarker(layerID), this));
589 		if (neu.isValid())
590 		{
591 			QPixmap pm(20,15);
592 			pm.fill(neu);
593 			((QToolButton*)(senderBox))->setIcon(pm);
594 			m_Doc->setLayerMarker(layerID, neu);
595 			m_Doc->scMW()->updateLayerMenu();
596 			m_Doc->scMW()->rebuildLayersList();
597 			emit LayerChanged();
598 		}
599 		setActiveLayer(Table->currentRow(), -1);
600 	}
601 }
602 
changeOpacity()603 void LayerPalette::changeOpacity()
604 {
605 	if (!m_Doc)
606 		return;
607 	m_Doc->setLayerTransparency(m_Doc->activeLayer(), opacitySpinBox->value() / 100.0);
608 	emit LayerChanged();
609 }
610 
changeBlendMode(int blend)611 void LayerPalette::changeBlendMode(int blend)
612 {
613 	if (!m_Doc)
614 		return;
615 	m_Doc->setLayerBlendMode(m_Doc->activeLayer(), blend);
616 	emit LayerChanged();
617 }
618 
markActiveLayer(int layerID)619 void LayerPalette::markActiveLayer(int layerID)
620 {
621 	if (!m_Doc)
622 		return;
623 	disconnect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
624 	disconnect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
625 	disconnect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
626 	int layerToMark = layerID;
627 	if (layerID == -1)
628 		layerToMark = m_Doc->activeLayer();
629 	Table->setCurrentCell(m_Doc->layerCount()-1-m_Doc->layerLevelFromID(layerToMark), 6);
630 	opacitySpinBox->setValue(qRound(m_Doc->layerTransparency(layerToMark) * 100));
631 	blendMode->setCurrentIndex(m_Doc->layerBlendMode(layerToMark));
632 	deleteLayerButton->setEnabled(m_Doc->layerCount() > 1 && !m_Doc->layerLocked( m_Doc->activeLayer() ));
633 
634 	if (layers->count() > 1)
635 	{
636 		raiseLayerButton->setEnabled(Table->currentRow() != 0);
637 		lowerLayerButton->setEnabled(Table->currentRow() != Table->rowCount() - 1);
638 	}
639 	else
640 	{
641 		raiseLayerButton->setEnabled(false);
642 		lowerLayerButton->setEnabled(false);
643 	}
644 	connect(Table, SIGNAL(cellClicked(int,int)), this, SLOT(setActiveLayer(int,int)));
645 	connect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
646 	connect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
647 }
648 
setActiveLayer(int row,int col)649 void LayerPalette::setActiveLayer(int row, int col)
650 {
651 	if (!m_Doc)
652 		return;
653 	if (col != 7)
654 	{
655 		markActiveLayer(-1);
656 		return;
657 	}
658 	disconnect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
659 	disconnect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
660 	int layerID = m_Doc->layerIDFromLevel(m_Doc->layerCount()-1-row);
661 	bool found=m_Doc->setActiveLayer(layerID);
662 	if (found)
663 	{
664 		m_Doc->scMW()->changeLayer(m_Doc->activeLayer());
665 		opacitySpinBox->setValue(qRound(m_Doc->layerTransparency(m_Doc->activeLayer()) * 100));
666 		blendMode->setCurrentIndex(m_Doc->layerBlendMode(m_Doc->activeLayer()));
667 		deleteLayerButton->setEnabled(m_Doc->layerCount() > 1 && !m_Doc->layerLocked( m_Doc->activeLayer() ));
668 		if (layers->count() > 1)
669 		{
670 			raiseLayerButton->setEnabled(Table->currentRow()!= 0);
671 			lowerLayerButton->setEnabled(Table->currentRow()!= Table->rowCount()-1);
672 		}
673 		else
674 		{
675 			raiseLayerButton->setEnabled(false);
676 			lowerLayerButton->setEnabled(false);
677 		}
678 	}
679 	connect(opacitySpinBox, SIGNAL(valueChanged(double)), this, SLOT(changeOpacity()));
680 	connect(blendMode, SIGNAL(activated(int)), this, SLOT(changeBlendMode(int)));
681 }
682 
changeEvent(QEvent * e)683 void LayerPalette::changeEvent(QEvent *e)
684 {
685 	if (e->type() == QEvent::LanguageChange)
686 		languageChange();
687 	else
688 		ScDockPalette::changeEvent(e);
689 }
690 
iconSetChange()691 void LayerPalette::iconSetChange()
692 {
693 	IconManager& iconManager = IconManager::instance();
694 
695 	Table->horizontalHeaderItem(1)->setIcon(iconManager.loadIcon("16/show-object.png"));
696 	Table->horizontalHeaderItem(2)->setIcon(iconManager.loadIcon("16/document-print.png"));
697 	Table->horizontalHeaderItem(3)->setIcon(iconManager.loadIcon("16/lock.png"));
698 	Table->horizontalHeaderItem(4)->setIcon(iconManager.loadIcon("16/layer-flow-around.png"));
699 	Table->horizontalHeaderItem(5)->setIcon(iconManager.loadIcon("layer-outline.png"));
700 	Table->horizontalHeaderItem(6)->setIcon(iconManager.loadIcon("16/pointer.png"));
701 
702 	newLayerButton->setIcon(iconManager.loadIcon("16/list-add.png"));
703 	deleteLayerButton->setIcon(iconManager.loadIcon("16/list-remove.png"));
704 	duplicateLayerButton->setIcon(iconManager.loadIcon("16/edit-copy.png"));
705 	raiseLayerButton->setIcon(iconManager.loadIcon("16/go-up.png"));
706 	lowerLayerButton->setIcon(iconManager.loadIcon("16/go-down.png"));
707 }
708 
languageChange()709 void LayerPalette::languageChange()
710 {
711 	setWindowTitle( tr( "Layers" ) );
712 	textLabel1->setText( tr( "Blend Mode:" ) );
713 
714 	int  oldBlendMode = blendMode->currentIndex();
715 	QSignalBlocker signalBlocker(blendMode);
716 	blendMode->clear();
717 	blendMode->addItem( tr("Normal"));
718 	blendMode->addItem( tr("Darken"));
719 	blendMode->addItem( tr("Lighten"));
720 	blendMode->addItem( tr("Multiply"));
721 	blendMode->addItem( tr("Screen"));
722 	blendMode->addItem( tr("Overlay"));
723 	blendMode->addItem( tr("Hard Light"));
724 	blendMode->addItem( tr("Soft Light"));
725 	blendMode->addItem( tr("Difference"));
726 	blendMode->addItem( tr("Exclusion"));
727 	blendMode->addItem( tr("Color Dodge"));
728 	blendMode->addItem( tr("Color Burn"));
729 	blendMode->addItem( tr("Hue"));
730 	blendMode->addItem( tr("Saturation"));
731 	blendMode->addItem( tr("Color"));
732 	blendMode->addItem( tr("Luminosity"));
733 
734 	blendMode->setCurrentIndex(oldBlendMode);
735 
736 	textLabel2->setText( tr( "Opacity:" ) );
737 	opacitySpinBox->setSuffix( tr(" %"));
738 	Table->horizontalHeaderItem(7)->setText( tr("Name"));
739 	newLayerButton->setToolTip("");
740 	duplicateLayerButton->setToolTip("");
741 	deleteLayerButton->setToolTip("");
742 	raiseLayerButton->setToolTip("");
743 	lowerLayerButton->setToolTip("");
744 	blendMode->setToolTip("");
745 	opacitySpinBox->setToolTip("");
746 	newLayerButton->setToolTip( tr( "Add a New Layer" ) );
747 	duplicateLayerButton->setToolTip( tr( "Duplicate the Current Layer" ) );
748 	deleteLayerButton->setToolTip( tr( "Delete Layer" ) );
749 	raiseLayerButton->setToolTip( tr( "Raise Layer" ) );
750 	lowerLayerButton->setToolTip( tr( "Lower Layer" ) );
751 	blendMode->setToolTip( tr("Selects the Blendmode, works only in PDF 1.4"));
752 	opacitySpinBox->setToolTip( tr("Layer Transparency, works only in PDF 1.4 and SVG"));
753 	Table->horizontalHeaderItem(0)->setToolTip("<qt>" + tr("Color of the Layer Indicator. Each layer has a color assigned to display on the canvas when layer indicators are enabled. You can double click to edit the color.") + "</qt>");
754 	Table->horizontalHeaderItem(1)->setToolTip("<qt>" + tr("Make Layer Visible. Uncheck to hide the layer from the display.") + "</qt>" );
755 	Table->horizontalHeaderItem(2)->setToolTip("<qt>" + tr("Print Layer. Uncheck to disable printing.") + "</qt>" );
756 	Table->horizontalHeaderItem(3)->setToolTip("<qt>" + tr("Lock or Unlock Layer. Unchecked is unlocked.") + "</qt>" );
757 	Table->horizontalHeaderItem(4)->setToolTip("<qt>" + tr("Make text in lower layers flow around objects. Enabling this forces text in lower layers to flow around objects of the layer for which this option has been enabled.") + "</qt>" );
758 	Table->horizontalHeaderItem(5)->setToolTip("<qt>" + tr("Outline Mode. Toggles the 'wireframe' display of objects to speed the display of very complex objects.") + "</qt>" ) ;
759 	Table->horizontalHeaderItem(6)->setToolTip("<qt>" + tr("Select Objects on Layer. Check to enable selecting.") + "</qt>" );
760 	Table->horizontalHeaderItem(7)->setToolTip("<qt>" + tr("Name of the Layer. Double click on the name of a layer to edit the name.") + "</qt>" );
761 }
762 
763