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 <QBuffer>
9 #include <QEvent>
10 #include <QHeaderView>
11 #include <QHelpEvent>
12 #include <QImage>
13 #include <QLabel>
14 #include <QLayout>
15 #include <QList>
16 #include <QMenu>
17 #include <QMessageBox>
18 #include <QResizeEvent>
19 #include <QToolTip>
20 #include <QVariant>
21 #include <QWidgetAction>
22 #include <QSignalMapper>
23 #include <QShortcut>
24 #include <QDebug>
25 
26 #include "actionmanager.h"
27 #include "appmodes.h"
28 #include "canvasmode.h"
29 #include "commonstrings.h"
30 #include "contentpalette.h"
31 #include "contextmenu.h"
32 #include "iconmanager.h"
33 #include "layers.h"
34 #include "outlinepalette.h"
35 #include "propertiespalette.h"
36 #include "scpage.h"
37 #include "scribus.h"
38 #include "scribusapp.h"
39 #include "scribusdoc.h"
40 #include "scribusview.h"
41 #include "selection.h"
42 #include "undomanager.h"
43 #include "units.h"
44 #include "util.h"
45 #include "util_color.h"
46 #include "util_formats.h"
47 
OutlineTreeItem(OutlineTreeItem * parent,OutlineTreeItem * after)48 OutlineTreeItem::OutlineTreeItem(OutlineTreeItem* parent, OutlineTreeItem* after) : QTreeWidgetItem(parent, after)
49 {
50 	PageObject = nullptr;
51 	PageItemObject = nullptr;
52 	DocObject = nullptr;
53 	type = -1;
54 	LayerID = -1;
55 }
56 
OutlineTreeItem(QTreeWidget * parent,OutlineTreeItem * after)57 OutlineTreeItem::OutlineTreeItem(QTreeWidget* parent, OutlineTreeItem* after) : QTreeWidgetItem(parent, after)
58 {
59 	PageObject = nullptr;
60 	PageItemObject = nullptr;
61 	DocObject = nullptr;
62 	type = -1;
63 	LayerID = -1;
64 }
65 
OutlineWidget(QWidget * parent)66 OutlineWidget::OutlineWidget(QWidget* parent) : QTreeWidget(parent)
67 {
68 	setDragDropMode(QAbstractItemView::InternalMove);
69 }
70 
selectItems(const QList<QTreeWidgetItem * > & items)71 void OutlineWidget::selectItems(const QList<QTreeWidgetItem*>& items)
72 {
73 	QItemSelection itemSelection;
74 	for (int i = 0; i < items.count(); ++i)
75 	{
76 		QModelIndex index = this->indexFromItem(items.at(i));
77 		if (index.isValid())
78 		{
79 			itemSelection.select(index, index);
80 		}
81 	}
82 	selectionModel()->select(itemSelection, QItemSelectionModel::Select);
83 }
84 
dropEvent(QDropEvent * e)85 void OutlineWidget::dropEvent(QDropEvent *e)
86 {
87 	bool haveLayers = false;
88 	QModelIndex id;
89 	QList<QTreeWidgetItem*> its;
90 	QList<OutlineTreeItem*> itemPars;
91 	QList<QModelIndex> idxs = selectedIndexes();
92 	for (int i = 0; i < idxs.count(); ++i)
93 	{
94 		id = idxs.at(i);
95 		QTreeWidgetItem* it = id.isValid() ? itemFromIndex(id) : nullptr;
96 		OutlineTreeItem *itemPar = it ? dynamic_cast<OutlineTreeItem*>(it->parent()) : nullptr;
97 		while (itemPar && (itemPar->type != 2))
98 		{
99 			if (itemPar->type == 5)
100 				haveLayers = true;
101 			itemPar = dynamic_cast<OutlineTreeItem*>(itemPar->parent());
102 		}
103 		its.append(it);
104 		itemPars.append(itemPar);
105 	}
106 
107 	QTreeWidget::dropEvent(e);
108 
109 	QList<QTreeWidgetItem*> selList;
110 	for (int i = 0; i < its.count(); ++i)
111 	{
112 		QTreeWidgetItem* it = its.at(i);
113 		if (it == nullptr)
114 			continue;
115 		OutlineTreeItem *itemPar = itemPars.at(i);
116 		OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(it);
117 		if (!item)
118 			qFatal("OutlineWidget::dropEvent !item");
119 		OutlineTreeItem *itemPl = dynamic_cast<OutlineTreeItem*>(it->parent());
120 		if (!itemPl)
121 			qFatal("OutlineWidget::dropEvent !itemPl");
122 		OutlineTreeItem *itemPg;
123 		if (itemPl->type == 5)
124 		{
125 			itemPg = dynamic_cast<OutlineTreeItem*>(it->parent()->parent());
126 			if (!itemPg)
127 				qFatal("OutlineWidget::dropEvent !itemPg 1");
128 		}
129 		else if (itemPl->type == 2)
130 		{
131 			itemPg = dynamic_cast<OutlineTreeItem*>(it->parent());
132 			if (!itemPg)
133 				qFatal("OutlineWidget::dropEvent !itemPg 2");
134 			if (haveLayers)
135 			{
136 				itemPl = dynamic_cast<OutlineTreeItem*>(itemPg->child(0));
137 				if (!itemPl)
138 					qFatal("OutlineWidget::dropEvent !itemPl");
139 				for (int j = 0; j < itemPg->childCount(); ++j)
140 				{
141 					OutlineTreeItem* childItem = dynamic_cast<OutlineTreeItem*>(itemPg->child(j));
142 					if (!childItem)
143 						qFatal("OutlineWidget::dropEvent !childItem");
144 					if (item->PageItemObject->m_layerID == childItem->LayerID)
145 					{
146 						itemPl = childItem;
147 						break;
148 					}
149 				}
150 				itemPg->removeChild(it);
151 				itemPl->addChild(it);
152 			}
153 		}
154 		else
155 		{
156 			itemPg = (OutlineTreeItem*)it->parent();
157 			while (itemPg->type != 2)
158 			{
159 				itemPg = dynamic_cast<OutlineTreeItem*>(itemPg->parent());
160 				if (!itemPg)
161 					qFatal("OutlineWidget::dropEvent !itemPg 3");
162 			}
163 		}
164 		if (itemPl->indexOfChild(it) != itemPl->childCount() - 1)
165 		{
166 			OutlineTreeItem *itemBe = dynamic_cast<OutlineTreeItem*>(itemPl->child(itemPl->indexOfChild(it) + 1));
167 			if (!itemBe)
168 				qFatal("OutlineWidget::dropEvent !itemBe");
169 			if ((itemBe->type == 1) || (itemBe->type == 3) || (itemBe->type == 4))
170 			{
171 				if (item->PageItemObject->isGroupChild())
172 					item->DocObject->removeFromGroup(item->PageItemObject);
173 				else
174 					item->DocObject->Items->removeOne(item->PageItemObject);
175 				if (itemBe->PageItemObject->isGroupChild())
176 				{
177 					PageItem* group = itemBe->PageItemObject->Parent;
178 					int d = group->groupItemList.indexOf(itemBe->PageItemObject);
179 					double xx = item->PageItemObject->xPos() - itemPar->PageObject->xOffset() + itemPg->PageObject->xOffset();
180 					double yy = item->PageItemObject->yPos() - itemPar->PageObject->yOffset() + itemPg->PageObject->yOffset();
181 					item->PageItemObject->setXYPos(xx, yy);
182 					item->DocObject->addToGroup(group, item->PageItemObject);
183 					group->groupItemList.insert(d, item->PageItemObject);
184 					item->PageItemObject->setLayer(group->m_layerID);
185 				}
186 				else
187 				{
188 					int d = item->DocObject->Items->indexOf(itemBe->PageItemObject);
189 					item->DocObject->Items->insert(d+1, item->PageItemObject);
190 					if (itemPl->type == 5)
191 						item->PageItemObject->setLayer(itemPl->LayerID);
192 					double xx = item->PageItemObject->xPos() - itemPar->PageObject->xOffset() + itemPg->PageObject->xOffset();
193 					double yy = item->PageItemObject->yPos() - itemPar->PageObject->yOffset() + itemPg->PageObject->yOffset();
194 					item->PageItemObject->setXYPos(xx, yy);
195 				}
196 				item->PageItemObject->setRedrawBounding();
197 				item->DocObject->setModified(true);
198 				item->DocObject->scMW()->showLayer();
199 				item->DocObject->scMW()->closeActiveWindowMasterPageEditor();
200 				if (item->PageItemObject->isGroup())
201 				{
202 					item->DocObject->GroupOnPage(item->PageItemObject);
203 					item->DocObject->scMW()->selectItemsFromOutlines(item->PageItemObject, false);
204 				}
205 				else
206 				{
207 					item->PageItemObject->OwnPage = item->DocObject->OnPage(item->PageItemObject);
208 					item->DocObject->scMW()->selectItemsFromOutlines(item->PageItemObject, true);
209 				}
210 				selList.append(it);
211 			}
212 		}
213 		else
214 		{
215 	//		itemPl->insertChild(0, itemPl->takeChild(itemPl->indexOfChild(it)));
216 			if ((itemPl->type == 2) || (itemPl->type == 5))
217 			{
218 				if (item->PageItemObject->isGroupChild())
219 				{
220 					item->DocObject->removeFromGroup(item->PageItemObject);
221 					item->DocObject->Items->append(item->PageItemObject);
222 				}
223 				if (itemPl->type == 5)
224 					item->PageItemObject->setLayer(itemPl->LayerID);
225 				double xx = item->PageItemObject->xPos() - itemPar->PageObject->xOffset() + itemPg->PageObject->xOffset();
226 				double yy = item->PageItemObject->yPos() - itemPar->PageObject->yOffset() + itemPg->PageObject->yOffset();
227 				item->PageItemObject->setXYPos(xx, yy);
228 			}
229 			else
230 			{
231 				OutlineTreeItem *itemBe = dynamic_cast<OutlineTreeItem*>(it->parent());
232 				if (!itemBe)
233 					qFatal("OutlineWidget::dropEvent !itemBe 2");
234 				if ((itemBe->type == 1) || (itemBe->type == 3) || (itemBe->type == 4))
235 				{
236 					if (item->PageItemObject->isGroupChild())
237 						item->DocObject->removeFromGroup(item->PageItemObject);
238 					else
239 						item->DocObject->Items->removeOne(item->PageItemObject);
240 					PageItem* group = itemBe->PageItemObject;
241 					double xx = item->PageItemObject->xPos() - itemPar->PageObject->xOffset() + itemPg->PageObject->xOffset();
242 					double yy = item->PageItemObject->yPos() - itemPar->PageObject->yOffset() + itemPg->PageObject->yOffset();
243 					item->PageItemObject->setXYPos(xx, yy);
244 					item->DocObject->addToGroup(group, item->PageItemObject);
245 					group->groupItemList.append(item->PageItemObject);
246 					item->PageItemObject->setLayer(group->m_layerID);
247 				}
248 			}
249 			item->PageItemObject->setRedrawBounding();
250 			item->DocObject->setModified(true);
251 			item->DocObject->scMW()->showLayer();
252 			item->DocObject->scMW()->closeActiveWindowMasterPageEditor();
253 			if (item->PageItemObject->isGroup())
254 			{
255 				item->DocObject->GroupOnPage(item->PageItemObject);
256 				item->DocObject->scMW()->selectItemsFromOutlines(item->PageItemObject, false);
257 			}
258 			else
259 			{
260 				item->PageItemObject->OwnPage = item->DocObject->OnPage(item->PageItemObject);
261 				item->DocObject->scMW()->selectItemsFromOutlines(item->PageItemObject, true, 1);
262 			}
263 			selList.append(it);
264 		}
265 	}
266 	selectItems(selList);
267 }
268 
keyPressEvent(QKeyEvent * e)269 void OutlineWidget::keyPressEvent(QKeyEvent *e)
270 {
271 	if (e->key() != Qt::Key_Backspace && e->key() != Qt::Key_Delete)
272 		return;
273 
274 	foreach (QTreeWidgetItem * twItem, selectedItems())
275 	{
276 		if (!twItem)
277 			continue;
278 		OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(twItem);
279 		if (!item)
280 			continue;
281 		switch (item->type)
282 		{
283 			case 1: //PageItem on master page
284 				{
285 					PageItem* pageItem = item->PageItemObject;
286 					if (!pageItem->isGroupChild())
287 						item->DocObject->itemSelection_DeleteItem();
288 				}
289 				break;
290 			case 3: //PageItem on normal page
291 				{
292 					PageItem* pageItem = item->PageItemObject;
293 					if (!pageItem->isGroupChild())
294 						item->DocObject->itemSelection_DeleteItem();
295 				}
296 				break;
297 			default:
298 				{
299 					//qDebug()<<item->type;
300 				}
301 				break;
302 		}
303 	}
304 }
305 
viewportEvent(QEvent * event)306 bool OutlineWidget::viewportEvent(QEvent *event)
307 {
308 	if (event->type() != QEvent::ToolTip)
309 		return QTreeWidget::viewportEvent(event);
310 
311 	QHelpEvent *helpEvent = static_cast<QHelpEvent *>(event);
312 	QTreeWidgetItem* it = itemAt(helpEvent->pos());
313 	if (!it)
314 		return QTreeWidget::viewportEvent(event);
315 
316 	OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(it);
317 	if (!item)
318 		return QTreeWidget::viewportEvent(event);
319 
320 	QString tipText;
321 	if (item->type == 5)
322 	{
323 		tipText += "<b>" + tr("Layer is:") + "</b><br><br>";
324 		if (item->DocObject->activeLayer() == item->LayerID)
325 			tipText += tr("active") + "<br>";
326 		if (item->DocObject->layerVisible(item->LayerID))
327 			tipText += tr("visible") + "<br>";
328 		else
329 			tipText += tr("invisible") + "<br>";
330 		if (item->DocObject->layerPrintable(item->LayerID))
331 			tipText += tr("printing");
332 		else
333 			tipText += tr("non printing");
334 		if (item->DocObject->layerLocked(item->LayerID))
335 			tipText += "<br>" + tr("locked");
336 	}
337 	else if ((item->type == 1) || (item->type == 3) || (item->type == 4))
338 	{
339 		PageItem *pgItem = item->PageItemObject;
340 		QPainter p;
341 		QImage pm = QImage(80, 80, QImage::Format_ARGB32_Premultiplied);
342 		QBrush b(QColor(205,205,205), IconManager::instance().loadPixmap("testfill.png"));
343 		p.begin(&pm);
344 		p.fillRect(QRectF(0, 0, 80, 80), b);
345 		QImage thumb = pgItem->DrawObj_toImage(80);
346 		p.drawImage((80 - thumb.width()) / 2, (80 - thumb.height()) / 2, thumb);
347 		p.end();
348 		QBuffer buffer;
349 		buffer.open(QIODevice::WriteOnly);
350 		pm.save(&buffer, "PNG");
351 		QByteArray ba = buffer.buffer().toBase64();
352 		buffer.close();
353 		tipText = "<p align=\"center\"><img src=\"data:image/png;base64," + QString(ba) + "\"></p><p>";
354 		switch (pgItem->itemType())
355 		{
356 			case PageItem::ImageFrame:
357 				if (pgItem->isLatexFrame())
358 					tipText += CommonStrings::itemType_LatexFrame;
359 				else if (pgItem->isOSGFrame())
360 					tipText += CommonStrings::itemType_OSGFrame;
361 				else
362 					tipText += CommonStrings::itemType_ImageFrame;
363 				break;
364 			case PageItem::TextFrame:
365 				switch (pgItem->annotation().Type())
366 				{
367 					case Annotation::Button:
368 						tipText += CommonStrings::itemSubType_PDF_PushButton;
369 						break;
370 					case Annotation::Textfield:
371 						tipText += CommonStrings::itemSubType_PDF_TextField;
372 						break;
373 					case Annotation::Checkbox:
374 						tipText += CommonStrings::itemSubType_PDF_CheckBox;
375 						break;
376 					case Annotation::Combobox:
377 						tipText += CommonStrings::itemSubType_PDF_ComboBox;
378 						break;
379 					case Annotation::Listbox:
380 						tipText += CommonStrings::itemSubType_PDF_ListBox;
381 						break;
382 					case Annotation::Text:
383 						tipText += CommonStrings::itemSubType_PDF_TextAnnotation;
384 						break;
385 					case Annotation::Link:
386 						tipText += CommonStrings::itemSubType_PDF_LinkAnnotation;
387 						break;
388 					case Annotation::RadioButton:
389 						tipText += CommonStrings::itemSubType_PDF_RadioButton;
390 						break;
391 					default:
392 						tipText += CommonStrings::itemType_TextFrame;
393 						break;
394 				}
395 				break;
396 			case PageItem::Line:
397 				tipText += CommonStrings::itemType_Line;
398 				break;
399 			case PageItem::Arc:
400 				tipText += CommonStrings::itemType_Arc;
401 				break;
402 			case PageItem::Polygon:
403 				tipText += CommonStrings::itemType_Polygon;
404 				break;
405 			case PageItem::RegularPolygon:
406 				tipText += CommonStrings::itemType_RegularPolygon;
407 				break;
408 			case PageItem::PolyLine:
409 				tipText += CommonStrings::itemType_Polyline;
410 				break;
411 			case PageItem::Spiral:
412 				tipText += CommonStrings::itemType_Spiral;
413 				break;
414 			case PageItem::PathText:
415 				tipText += CommonStrings::itemType_PathText;
416 				break;
417 			case PageItem::Symbol:
418 				tipText += CommonStrings::itemType_Symbol;
419 				break;
420 			case PageItem::Group:
421 				tipText += CommonStrings::itemType_Group;
422 				break;
423 			case PageItem::Table:
424 				tipText += CommonStrings::itemType_Table;
425 				break;
426 			default:
427 				break;
428 		}
429 		tipText +="<br>" + tr("X-Pos:") + " ";
430 		if (pgItem->OwnPage != -1)
431 			tipText += value2String(pgItem->xPos() - item->PageObject->xOffset(), pgItem->doc()->unitIndex(), true, true);
432 		else
433 			tipText += value2String(pgItem->xPos(), pgItem->doc()->unitIndex(), true, true);
434 		tipText +="<br>" + tr("Y-Pos:") + " ";
435 		if (pgItem->OwnPage != -1)
436 			tipText += value2String(pgItem->yPos() - item->PageObject->yOffset(), pgItem->doc()->unitIndex(), true, true);
437 		else
438 			tipText += value2String(pgItem->yPos(), pgItem->doc()->unitIndex(), true, true);
439 		tipText += "</p>";
440 	}
441 	QToolTip::showText(helpEvent->globalPos(), tipText, this);
442 	return true;
443 }
444 
OutlinePalette(QWidget * parent)445 OutlinePalette::OutlinePalette( QWidget* parent) : ScDockPalette(parent, "Tree", Qt::WindowFlags())
446 {
447 //	resize( 220, 240 );
448 	setMinimumSize( QSize( 220, 240 ) );
449 	setObjectName(QString::fromLocal8Bit("Tree"));
450 	setSizePolicy( QSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum));
451 	containerWidget = new QWidget(this);
452 
453 	filterEdit = new QLineEdit;
454 	filterEdit->setToolTip( tr("Enter a keyword or regular expression to filter the outline") );
455 //	QShortcut* filterShortcut = new QShortcut( QKeySequence( tr( "Ctrl+F", "Filter the Outline using a keyword" ) ), this );
456 	filterLabel = new QLabel( tr("Filter:") );
457 	filterLabel->setBuddy( filterEdit );
458 
459 	reportDisplay = new OutlineWidget( this );
460 
461 //	reportDisplay->setGeometry( QRect( 0, 0, 220, 240 ) );
462 //	reportDisplay->setMinimumSize( QSize( 220, 240 ) );
463 	reportDisplay->setRootIsDecorated( true );
464 	reportDisplay->setColumnCount(1);
465 	reportDisplay->setHeaderLabel( tr("Element"));
466 	reportDisplay->header()->setSectionsClickable(false );
467 	reportDisplay->header()->setSectionResizeMode(QHeaderView::ResizeToContents);
468 	reportDisplay->setSortingEnabled(false);
469 	reportDisplay->setSelectionMode(QAbstractItemView::ExtendedSelection);
470 	reportDisplay->setContextMenuPolicy(Qt::CustomContextMenu);
471 
472 	QGridLayout* layout = new QGridLayout;
473 	layout->addWidget( filterLabel, 0, 0 );
474 	layout->addWidget( filterEdit, 0, 1 );
475 	layout->addWidget( reportDisplay, 1, 0, 1, 2 );
476 	layout->setSpacing(3);
477 	layout->setContentsMargins(3, 3, 3, 3);
478 	containerWidget->setLayout( layout );
479 	setWidget( containerWidget );
480 
481 	unsetDoc();
482 
483 	selectionTriggered = false;
484 	m_MainWindow  = nullptr;
485 	freeObjects   = nullptr;
486 	rootObject    = nullptr;
487 	currentObject = nullptr;
488 
489 	iconSetChange();
490 	languageChange();
491 
492 	// signals and slots connections
493 	connect(ScQApp, SIGNAL(iconSetChanged()), this, SLOT(iconSetChange()));
494 
495 	connect(reportDisplay, SIGNAL(customContextMenuRequested (const QPoint &)), this, SLOT(slotRightClick(QPoint)));
496 	connect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
497 	connect(reportDisplay, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotDoRename(QTreeWidgetItem*, int)));
498 	connect(filterEdit, SIGNAL(textChanged(const QString&)), this, SLOT(filterTree(const QString&)));
499 //	connect(filterShortcut, SIGNAL(activated()), filterEdit, SLOT(setFocus()));
500 	connect(reportDisplay, SIGNAL(itemDoubleClicked(QTreeWidgetItem*, int)), this, SLOT(slotDoubleClick(QTreeWidgetItem*, int)));
501 }
502 
setMainWindow(ScribusMainWindow * mw)503 void OutlinePalette::setMainWindow(ScribusMainWindow *mw)
504 {
505 	m_MainWindow=mw;
506 	if (m_MainWindow==nullptr)
507 		clearPalette();
508 }
509 
setDoc(ScribusDoc * newDoc)510 void OutlinePalette::setDoc(ScribusDoc *newDoc)
511 {
512 	if (m_MainWindow==nullptr)
513 		currDoc=nullptr;
514 	else
515 		currDoc=newDoc;
516 	if (currDoc==nullptr)
517 		clearPalette();
518 }
519 
unsetDoc()520 void OutlinePalette::unsetDoc()
521 {
522 	currDoc=nullptr;
523 	clearPalette();
524 }
525 
setPaletteShown(bool visible)526 void OutlinePalette::setPaletteShown(bool visible)
527 {
528 	ScDockPalette::setPaletteShown(visible);
529 	if ((visible) && (currDoc != nullptr))
530 		BuildTree();
531 }
532 
slotRightClick(QPoint point)533 void OutlinePalette::slotRightClick(QPoint point)
534 {
535 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
536 		return;
537 	QTreeWidgetItem *ite = reportDisplay->itemAt(point);
538 	if (ite == nullptr)
539 		return;
540 	if (!ite->isSelected())
541 		slotMultiSelect();
542 	if (currDoc->drawAsPreview)
543 		return;
544 
545 	OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(ite);
546 	if (!item)
547 		return;
548 
549 	if ((item->type == 0) || (item->type == 2))
550 		createContextMenu(nullptr, point.x(), point.y());
551 	else if ((item->type == 1) || (item->type == 3) || (item->type == 4))
552 	{
553 		PageItem *currItem = item->PageItemObject;
554 		if (currItem!=nullptr)
555 		{
556 			currentObject = ite;
557 			createContextMenu(currItem, point.x(), point.y());
558 		}
559 	}
560 	else if (item->type == 5)
561 	{
562 		QMenu *pmenu = new QMenu();
563 		QAction *actVis;
564 		QAction *actPrint;
565 		QAction *actLock;
566 		if (item->DocObject->activeLayer() != item->LayerID)
567 		{
568 			QAction *actActive;
569 			QSignalMapper *signalMapper = new QSignalMapper(this);
570 			actActive = pmenu->addAction( tr("Active"));
571 			actActive->setCheckable(true);
572 			actActive->setChecked(false);
573 			signalMapper->setMapping(actActive, item->LayerID);
574 			connect(actActive, SIGNAL(triggered()), signalMapper, SLOT(map()));
575 			connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(setActiveLayer(int)));
576 		}
577 		QSignalMapper *signalMapper2 = new QSignalMapper(this);
578 		actVis = pmenu->addAction( tr("Visible"));
579 		actVis->setCheckable(true);
580 		actVis->setChecked(item->DocObject->layerVisible(item->LayerID));
581 		signalMapper2->setMapping(actVis, item->LayerID);
582 		connect(actVis, SIGNAL(triggered()), signalMapper2, SLOT(map()));
583 		connect(signalMapper2, SIGNAL(mapped(int)), this, SLOT(setLayerVisible(int)));
584 
585 		QSignalMapper *signalMapper3 = new QSignalMapper(this);
586 		actPrint = pmenu->addAction( tr("Printing"));
587 		actPrint->setCheckable(true);
588 		actPrint->setChecked(item->DocObject->layerPrintable(item->LayerID));
589 		signalMapper3->setMapping(actPrint, item->LayerID);
590 		connect(actPrint, SIGNAL(triggered()), signalMapper3, SLOT(map()));
591 		connect(signalMapper3, SIGNAL(mapped(int)), this, SLOT(setLayerPrintable(int)));
592 
593 		QSignalMapper *signalMapper4 = new QSignalMapper(this);
594 		actLock = pmenu->addAction( tr("Locked"));
595 		actLock->setCheckable(true);
596 		actLock->setChecked(item->DocObject->layerLocked(item->LayerID));
597 		signalMapper4->setMapping(actLock, item->LayerID);
598 		connect(actLock, SIGNAL(triggered()), signalMapper4, SLOT(map()));
599 		connect(signalMapper4, SIGNAL(mapped(int)), this, SLOT(setLayerLocked(int)));
600 //		qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
601 		pmenu->exec(QCursor::pos());
602 		delete pmenu;
603 	}
604 }
605 
setActiveLayer(int layerID)606 void OutlinePalette::setActiveLayer(int layerID)
607 {
608 	currDoc->setActiveLayer(layerID);
609 	currDoc->scMW()->changeLayer(currDoc->activeLayer());
610 }
611 
setLayerVisible(int layerID)612 void OutlinePalette::setLayerVisible(int layerID)
613 {
614 	bool isLayerVisible = !currDoc->layerVisible(layerID);
615 	currDoc->setLayerVisible(layerID, isLayerVisible);
616 	if (!isLayerVisible)
617 		currDoc->m_Selection->removeItemsOfLayer(layerID);
618 	currDoc->scMW()->showLayer();
619 	currDoc->scMW()->layerPalette->rebuildList();
620 	currDoc->scMW()->layerPalette->markActiveLayer();
621 }
622 
setLayerLocked(int layerID)623 void OutlinePalette::setLayerLocked(int layerID)
624 {
625 	bool isLayerLocked = !currDoc->layerLocked(layerID);
626 	currDoc->setLayerLocked(layerID, isLayerLocked);
627 	if (isLayerLocked)
628 		currDoc->m_Selection->removeItemsOfLayer(layerID);
629 	currDoc->scMW()->layerPalette->rebuildList();
630 	currDoc->scMW()->layerPalette->markActiveLayer();
631 }
632 
setLayerPrintable(int layerID)633 void OutlinePalette::setLayerPrintable(int layerID)
634 {
635 	currDoc->setLayerPrintable(layerID, !currDoc->layerPrintable(layerID));
636 	currDoc->scMW()->layerPalette->rebuildList();
637 	currDoc->scMW()->layerPalette->markActiveLayer();
638 }
639 
slotRenameItem()640 void OutlinePalette::slotRenameItem()
641 {
642 	activateWindow();
643 	reportDisplay->setFocus();
644 	reportDisplay->editItem(currentObject);
645 }
646 
slotDoRename(QTreeWidgetItem * ite,int col)647 void OutlinePalette::slotDoRename(QTreeWidgetItem *ite , int col)
648 {
649 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
650 		return;
651 	disconnect(reportDisplay, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotDoRename(QTreeWidgetItem*, int)));
652 	OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(ite);
653 	if (item != nullptr)
654 	{
655 		if ((item->type == 1) || (item->type == 3) || (item->type == 4))
656 		{
657 			QString NameOld = item->PageItemObject->itemName();
658 			QString NameNew = ite->text(col);
659 			if (NameOld != NameNew)
660 			{
661 				if (NameNew == "")
662 					ite->setText(col, NameOld);
663 				else
664 				{
665 					bool found = false;
666 					QList<PageItem*> allItems;
667 					for (int a = 0; a < currDoc->Items->count(); ++a)
668 					{
669 						PageItem *currItem = currDoc->Items->at(a);
670 						if (currItem->isGroup())
671 							allItems = currItem->getAllChildren();
672 						else
673 							allItems.append(currItem);
674 						for (int ii = 0; ii < allItems.count(); ii++)
675 						{
676 							PageItem* ite = allItems.at(ii);
677 							if ((NameNew == ite->itemName()) && (ite != item->PageItemObject))
678 							{
679 								found = true;
680 								break;
681 							}
682 						}
683 						allItems.clear();
684 					}
685 					if (found)
686 					{
687 						ScMessageBox::warning(this, CommonStrings::trWarning, "<qt>"+ tr("Name \"%1\" isn't unique.<br/>Please choose another.").arg(NameNew)+"</qt>");
688 						ite->setText(col, NameOld);
689 					}
690 					else
691 					{
692 						item->PageItemObject->setItemName(NameNew);
693 						m_MainWindow->propertiesPalette->setCurrentItem(item->PageItemObject);
694 						m_MainWindow->contentPalette->setCurrentItem(item->PageItemObject);
695 						currDoc->setModified(true);
696 					}
697 				}
698 			}
699 		}
700 		filterTree();
701 	}
702 	connect(reportDisplay, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotDoRename(QTreeWidgetItem*, int)));
703 }
704 
getListItem(int pageNr,PageItem * pageItem)705 QTreeWidgetItem* OutlinePalette::getListItem(int pageNr, PageItem *pageItem)
706 {
707 	OutlineTreeItem *item = nullptr;
708 	QTreeWidgetItem *retVal = nullptr;
709 	if (currDoc->masterPageMode())
710 	{
711 		if (pageItem == nullptr)
712 		{
713 			for (QTreeWidgetItemIterator it(reportDisplay); *it; ++it)
714 			{
715 				item = dynamic_cast<OutlineTreeItem*>(*it);
716 				if (item && (item->type == 0) && (item->PageObject->pageNr() == pageNr))
717 				{
718 					retVal = (*it);
719 					break;
720 				}
721 			}
722 		}
723 		else
724 		{
725 			for (QTreeWidgetItemIterator it(reportDisplay); *it; ++it)
726 			{
727 				item = dynamic_cast<OutlineTreeItem*>(*it);
728 				if (item && (item->type == 1) && (item->PageItemObject == pageItem))
729 				{
730 					retVal = (*it);
731 					break;
732 				}
733 			}
734 		}
735 	}
736 	else
737 	{
738 		if (pageItem == nullptr)
739 		{
740 			for (QTreeWidgetItemIterator it(reportDisplay); *it; ++it)
741 			{
742 				item = dynamic_cast<OutlineTreeItem*>(*it);
743 				if (item && (item->type == 2) && (item->PageObject->pageNr() == pageNr))
744 				{
745 					retVal = (*it);
746 					break;
747 				}
748 			}
749 		}
750 		else
751 		{
752 			for (QTreeWidgetItemIterator it(reportDisplay); *it; ++it)
753 			{
754 				item = dynamic_cast<OutlineTreeItem*>(*it);
755 				if (item && ((item->type == 3) || (item->type == 4)) && (item->PageItemObject == pageItem))
756 				{
757 					retVal = (*it);
758 					break;
759 				}
760 			}
761 		}
762 	}
763 	return retVal;
764 }
765 
slotShowSelect(int pageNr,PageItem * pageItem)766 void OutlinePalette::slotShowSelect(int pageNr, PageItem *pageItem)
767 {
768 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
769 		return;
770 	if (currDoc==nullptr)
771 		return;
772 	if (currDoc->isLoading())
773 		return;
774 	if (selectionTriggered)
775 		return;
776 	disconnect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
777 	reportDisplay->clearSelection();
778 	if (currDoc->m_Selection->count() > 0)
779 	{
780 		QList<QTreeWidgetItem*> itemSelection;
781 		int docSelectionCount = currDoc->m_Selection->count();
782 		for (int i = 0; i < docSelectionCount; i++)
783 		{
784 			PageItem *item = currDoc->m_Selection->itemAt(i);
785 			QTreeWidgetItem *retVal = getListItem(item->OwnPage, item);
786 			if (retVal != nullptr && !retVal->isHidden())
787 				itemSelection.append(retVal);
788 		}
789 		reportDisplay->selectItems(itemSelection);
790 	}
791 	else
792 	{
793 		QTreeWidgetItem *retVal = getListItem(pageNr, pageItem);
794 		if (retVal != nullptr && !retVal->isHidden())
795 			retVal->setSelected(true);
796 	}
797 	QList<QTreeWidgetItem *> items = reportDisplay->selectedItems();
798 	if (items.count() > 0)
799 		reportDisplay->scrollToItem(items[0], QAbstractItemView::EnsureVisible);
800 	connect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
801 }
802 
setItemIcon(QTreeWidgetItem * item,PageItem * pgItem)803 void OutlinePalette::setItemIcon(QTreeWidgetItem *item, PageItem *pgItem)
804 {
805 	switch (pgItem->itemType())
806 	{
807 	case PageItem::ImageFrame:
808 		if (pgItem->isLatexFrame())
809 			item->setIcon( 0, latexIcon );
810 		else if (pgItem->isOSGFrame())
811 			item->setIcon( 0, annot3DIcon );
812  		else
813 			item->setIcon( 0, imageIcon );
814 		break;
815 	case PageItem::TextFrame:
816 		switch (pgItem->annotation().Type())
817 		{
818 			case Annotation::Button:
819 				item->setIcon( 0, buttonIcon );
820 				break;
821 			case Annotation::RadioButton:
822 				item->setIcon( 0, radiobuttonIcon );
823 				break;
824 			case Annotation::Textfield:
825 				item->setIcon( 0, textFieldIcon );
826 				break;
827 			case Annotation::Checkbox:
828 				item->setIcon( 0, checkBoxIcon );
829 				break;
830 			case Annotation::Combobox:
831 				item->setIcon( 0, comboBoxIcon );
832 				break;
833 			case Annotation::Listbox:
834 				item->setIcon( 0, listBoxIcon );
835 				break;
836 			case Annotation::Text:
837 				item->setIcon( 0, annotTextIcon );
838 				break;
839 			case Annotation::Link:
840 				item->setIcon( 0, annotLinkIcon );
841 				break;
842 			default:
843 				item->setIcon( 0, textIcon );
844 				break;
845 		}
846 		break;
847 	case PageItem::Line:
848 		item->setIcon( 0, lineIcon );
849 		break;
850 	case PageItem::Arc:
851 		item->setIcon( 0, arcIcon );
852 		break;
853 	case PageItem::Spiral:
854 		item->setIcon( 0, spiralIcon );
855 		break;
856 	case PageItem::Polygon:
857 	case PageItem::RegularPolygon:
858 		item->setIcon( 0, polygonIcon );
859 		break;
860 	case PageItem::PolyLine:
861 		item->setIcon( 0, polylineIcon );
862 		break;
863 	case PageItem::PathText:
864 		item->setIcon( 0, textIcon );
865 		break;
866 	case PageItem::Symbol:
867 		item->setIcon( 0, polygonIcon );
868 		break;
869 	case PageItem::Table:
870 		item->setIcon( 0, tableIcon );
871 		break;
872 	default:
873 		break;
874 	}
875 }
876 
reopenTree()877 void OutlinePalette::reopenTree()
878 {
879 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
880 		return;
881 	if (currDoc->OpenNodes.count() == 0)
882 		return;
883 	OutlineTreeItem *item = nullptr;
884 	QTreeWidgetItemIterator it( reportDisplay );
885 	while ( (*it) )
886 	{
887 		item = dynamic_cast<OutlineTreeItem*>(*it);
888 		if (!item)
889 			qFatal("OutlinePalette::reopenTree !item");
890 		for (int olc = 0; olc < currDoc->OpenNodes.count(); olc++)
891 		{
892 			if (item->type == currDoc->OpenNodes[olc].type)
893 			{
894 				if ((item->type == -3) || (item->type == -2))
895 					reportDisplay->expandItem((*it));
896 				else if ((item->type == 0) || (item->type == 2))
897 				{
898 					if (item->PageObject == currDoc->OpenNodes[olc].page)
899 						reportDisplay->expandItem((*it));
900 				}
901 				else if ((item->type == 2) || (item->type == 3) || (item->type == 4))
902 				{
903 					if (item->PageItemObject == currDoc->OpenNodes[olc].item)
904 						reportDisplay->expandItem((*it));
905 				}
906 			}
907 		}
908 		++it;
909 	}
910 }
911 
buildReopenVals()912 void OutlinePalette::buildReopenVals()
913 {
914 	ScribusDoc::OpenNodesList ol;
915 	if (reportDisplay->model()->rowCount() == 0)
916 		return;
917 	currDoc->OpenNodes.clear();
918 	OutlineTreeItem *item = nullptr;
919 	QTreeWidgetItemIterator it( reportDisplay );
920 	while ( (*it) )
921 	{
922 		item = dynamic_cast<OutlineTreeItem*>(*it);
923 		if (!item)
924 			qFatal("OutlinePalette::buildReopenVals !item");
925 		if (item->isExpanded())
926 		{
927 			ol.type = item->type;
928 			ol.page = item->PageObject;
929 			ol.item = item->PageItemObject;
930 			currDoc->OpenNodes.append(ol);
931 		}
932 		++it;
933 	}
934 }
935 
slotMultiSelect()936 void OutlinePalette::slotMultiSelect()
937 {
938 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
939 		return;
940 	if (currDoc==nullptr)
941 		return;
942 	disconnect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
943 	selectionTriggered = true;
944 	QList<QTreeWidgetItem *> items = reportDisplay->selectedItems();
945 	if (items.count() != 1)
946 	{
947 		if (currDoc->drawAsPreview)
948 			return;
949 		if (currDoc->appMode == modeEditClip)
950 			currDoc->view()->requestMode(submodeEndNodeEdit);
951 		currDoc->m_Selection->delaySignalsOn();
952 		currDoc->view()->deselectItems(true);
953 		for (int a = 0; a < items.count(); a++)
954 		{
955 			QTreeWidgetItem* ite = items[a];
956 			OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(ite);
957 			if (!item)
958 				qFatal("OutlineWidget::slotMultiSelect !item");
959 			PageItem *pgItem = nullptr;
960 			switch (item->type)
961 			{
962 				case 0:
963 				case 1:
964 				case 2:
965 				case 5:
966 					ite->setSelected(false);
967 					break;
968 				case 3:
969 				case 4:
970 					pgItem = item->PageItemObject;
971 					if (!pgItem->isSelected())
972 					{
973 						m_MainWindow->closeActiveWindowMasterPageEditor();
974 						currDoc->view()->selectItem(pgItem, false, false);
975 					}
976 					break;
977 				default:
978 					break;
979 			}
980 		}
981 		currDoc->m_Selection->delaySignalsOff();
982 		currDoc->view()->DrawNew();
983 	}
984 	else
985 		slotSelect(items[0], 0);
986 	selectionTriggered = false;
987 	connect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
988 }
989 
slotSelect(QTreeWidgetItem * ite,int)990 void OutlinePalette::slotSelect(QTreeWidgetItem* ite, int)
991 {
992 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
993 		return;
994 	selectionTriggered = true;
995 	OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(ite);
996 	if (!item)
997 		qFatal("OutlineWidget::slotSelect !item");
998 	PageItem *pgItem = nullptr;
999 	switch (item->type)
1000 	{
1001 		case 0:
1002 			emit selectMasterPage(item->PageObject->pageName());
1003 			break;
1004 		case 1:
1005 			if (!currDoc->masterPageMode())
1006 				emit selectMasterPage(item->PageItemObject->OnMasterPage);
1007 			pgItem = item->PageItemObject;
1008 			currDoc->setActiveLayer(pgItem->m_layerID);
1009 			m_MainWindow->changeLayer(currDoc->activeLayer());
1010 			if (item->PageItemObject->isGroup())
1011 				emit selectElementByItem(pgItem, false);
1012 			else
1013 				emit selectElementByItem(pgItem, true);
1014 			break;
1015 		case 2:
1016 			if (currDoc->drawAsPreview)
1017 				return;
1018 			if (!currDoc->symbolEditMode())
1019 			{
1020 				int pg = item->PageObject->pageNr();
1021 				m_MainWindow->closeActiveWindowMasterPageEditor();
1022 				emit selectPage(pg);
1023 			}
1024 			break;
1025 		case 3:
1026 		case 4:
1027 			if (currDoc->drawAsPreview)
1028 				return;
1029 			pgItem = item->PageItemObject;
1030 			m_MainWindow->closeActiveWindowMasterPageEditor();
1031 			currDoc->setActiveLayer(pgItem->m_layerID);
1032 			m_MainWindow->changeLayer(currDoc->activeLayer());
1033 			if (pgItem->isGroup())
1034 				emit selectElementByItem(pgItem, false);
1035 			else
1036 				emit selectElementByItem(pgItem, true);
1037 			break;
1038 		case 5:
1039 			if (currDoc->drawAsPreview)
1040 				return;
1041 			currDoc->setActiveLayer(item->LayerID);
1042 			m_MainWindow->changeLayer(currDoc->activeLayer());
1043 			break;
1044 		default:
1045 			break;
1046 	}
1047 	selectionTriggered = false;
1048 }
1049 
slotDoubleClick(QTreeWidgetItem * ite,int)1050 void OutlinePalette::slotDoubleClick(QTreeWidgetItem* ite, int)
1051 {
1052 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
1053 		return;
1054 	OutlineTreeItem *item = dynamic_cast<OutlineTreeItem*>(ite);
1055 	if (!item)
1056 		qFatal("OutlinePalette::slotDoubleClick !item");
1057 	PageItem *pgItem = nullptr;
1058 	switch (item->type)
1059 	{
1060 		case 1:
1061 			if (!currDoc->masterPageMode())
1062 				emit selectMasterPage(item->PageItemObject->OnMasterPage);
1063 			pgItem = item->PageItemObject;
1064 			emit editElementByItem(pgItem);
1065 			break;
1066 		case 3:
1067 		case 4:
1068 			if (currDoc->drawAsPreview)
1069 				return;
1070 			pgItem = item->PageItemObject;
1071 			m_MainWindow->closeActiveWindowMasterPageEditor();
1072 			emit editElementByItem(pgItem);
1073 			break;
1074 		default:
1075 			break;
1076 	}
1077 }
1078 
BuildTree(bool storeVals)1079 void OutlinePalette::BuildTree(bool storeVals)
1080 {
1081 	if (!m_MainWindow || m_MainWindow->scriptIsRunning())
1082 		return;
1083 	if (currDoc==nullptr)
1084 		return;
1085 	if (selectionTriggered)
1086 		return;
1087 	disconnect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
1088 	disconnect(reportDisplay, SIGNAL(itemChanged(QTreeWidgetItem*, int)), this, SLOT(slotDoRename(QTreeWidgetItem*, int)));
1089 	setUpdatesEnabled(false);
1090 	if (storeVals)
1091 		buildReopenVals();
1092 	clearPalette();
1093 	OutlineTreeItem * item = new OutlineTreeItem( reportDisplay, nullptr );
1094 	rootObject = item;
1095 	item->setText( 0, currDoc->documentFileName().section( '/', -1 ) );
1096 	item->type = -2;
1097 	item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
1098 	OutlineTreeItem * pagep = nullptr;
1099 	freeObjects = nullptr;
1100 	PageItem* pgItem;
1101 	QString tmp;
1102 	if (currDoc->symbolEditMode() || currDoc->inlineEditMode())
1103 	{
1104 		OutlineTreeItem *page = new OutlineTreeItem( item, pagep );
1105 		page->PageObject = currDoc->Pages->at(0);
1106 		page->type = 2;
1107 		page->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
1108 		pagep = page;
1109 		for (int b = 0; b < currDoc->Items->count(); ++b)
1110 		{
1111 			pgItem = currDoc->Items->at(b);
1112 			if (!pgItem->isGroup())
1113 			{
1114 				OutlineTreeItem *object = new OutlineTreeItem( page, nullptr );
1115 				object->PageItemObject = pgItem;
1116 				object->PageObject = currDoc->DocPages.at(0);
1117 				object->DocObject = currDoc;
1118 				object->type = 3;
1119 				object->setText(0, pgItem->itemName());
1120 				setItemIcon(object, pgItem);
1121 				object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
1122 			}
1123 			else
1124 			{
1125 				OutlineTreeItem *object = new OutlineTreeItem( page, nullptr );
1126 				object->PageItemObject = pgItem;
1127 				object->PageObject = currDoc->DocPages.at(0);
1128 				object->DocObject = currDoc;
1129 				object->type = 3;
1130 				object->setText(0, pgItem->itemName());
1131 				object->setIcon( 0, groupIcon );
1132 				object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
1133 				parseSubGroup(object, &pgItem->groupItemList, 3, currDoc->Pages->at(0));
1134 			}
1135 		}
1136 		if (currDoc->symbolEditMode())
1137 			page->setText(0, currDoc->getEditedSymbol());
1138 		else
1139 			page->setText(0, tr("Inline Frame"));
1140 	}
1141 	else
1142 	{
1143 		for (int a = 0; a < static_cast<int>(currDoc->MasterPages.count()); ++a)
1144 		{
1145 			OutlineTreeItem *page = new OutlineTreeItem( item, pagep );
1146 			page->PageObject = currDoc->MasterPages.at(a);
1147 			page->type = 0;
1148 			page->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1149 			QString pageNam = currDoc->MasterPages.at(a)->pageName();
1150 			pagep = page;
1151 			for (int b = 0; b < currDoc->MasterItems.count(); ++b)
1152 			{
1153 				pgItem = currDoc->MasterItems.at(b);
1154 				if (((pgItem->OwnPage == a) || (pgItem->OnMasterPage == pageNam)))
1155 				{
1156 					if (!pgItem->isGroup())
1157 					{
1158 						OutlineTreeItem *object = new OutlineTreeItem( page, nullptr );
1159 						object->PageItemObject = pgItem;
1160 						object->PageObject = currDoc->MasterPages.at(a);
1161 						object->DocObject = currDoc;
1162 						object->type = 1;
1163 						object->setText(0, pgItem->itemName());
1164 						setItemIcon(object, pgItem);
1165 						object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1166 					}
1167 					else
1168 					{
1169 						OutlineTreeItem * object = new OutlineTreeItem(page, nullptr);
1170 						object->PageItemObject = pgItem;
1171 						object->PageObject = currDoc->MasterPages.at(a);
1172 						object->DocObject = currDoc;
1173 						object->type = 1;
1174 						object->setText(0, pgItem->itemName());
1175 						object->setIcon( 0, groupIcon );
1176 						object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1177 						parseSubGroup(object, &pgItem->groupItemList, 1, currDoc->MasterPages.at(a));
1178 					}
1179 				}
1180 			}
1181 			page->setText(0, currDoc->MasterPages.at(a)->pageName());
1182 		}
1183 		bool hasfreeItems = false;
1184 		for (int a = 0; a < static_cast<int>(currDoc->DocPages.count()); ++a)
1185 		{
1186 			OutlineTreeItem *page = new OutlineTreeItem( item, pagep );
1187 			page->PageObject = currDoc->DocPages.at(a);
1188 			page->type = 2;
1189 			page->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
1190 			pagep = page;
1191 			int layerCount = currDoc->layerCount();
1192 			if (layerCount > 1)
1193 			{
1194 				QList<PageItem*> pgItems;
1195 				for (int b = 0; b < currDoc->DocItems.count(); ++b)
1196 				{
1197 					pgItem = currDoc->DocItems.at(b);
1198 					if (pgItem->OwnPage == -1)
1199 						hasfreeItems = true;
1200 					if (pgItem->OwnPage == a)
1201 						pgItems.append(pgItem);
1202 				}
1203 				ScLayer layer;
1204 				layer.ID = 0;
1205 				for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
1206 				{
1207 					currDoc->Layers.levelToLayer(layer, layerLevel);
1208 					OutlineTreeItem *ObjLayer = new OutlineTreeItem(page, nullptr);
1209 					ObjLayer->type = 5;
1210 					ObjLayer->LayerID = layer.ID;
1211 					ObjLayer->DocObject = currDoc;
1212 					ObjLayer->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDropEnabled);
1213 					ObjLayer->setText(0, tr("Layer: \"") + layer.Name + "\"");
1214 					for (int it = 0; it < pgItems.count(); ++it)
1215 					{
1216 						pgItem = pgItems.at(it);
1217 						if (pgItem->m_layerID != layer.ID)
1218 							continue;
1219 						if (!pgItem->isGroup())
1220 						{
1221 							OutlineTreeItem *object = new OutlineTreeItem(ObjLayer, nullptr);
1222 							object->PageItemObject = pgItem;
1223 							object->PageObject = currDoc->DocPages.at(a);
1224 							object->DocObject = currDoc;
1225 							object->type = 3;
1226 							object->setText(0, pgItem->itemName());
1227 							setItemIcon(object, pgItem);
1228 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
1229 						}
1230 						else
1231 						{
1232 							OutlineTreeItem *object = new OutlineTreeItem(ObjLayer, nullptr);
1233 							object->PageItemObject = pgItem;
1234 							object->PageObject = currDoc->DocPages.at(a);
1235 							object->DocObject = currDoc;
1236 							object->type = 3;
1237 							object->setText(0, pgItem->itemName());
1238 							object->setIcon( 0, groupIcon );
1239 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
1240 							parseSubGroup(object, &pgItem->groupItemList, 3, currDoc->DocPages.at(a));
1241 						}
1242 					}
1243 				}
1244 			}
1245 			else
1246 			{
1247 				for (int b = 0; b < currDoc->DocItems.count(); ++b)
1248 				{
1249 					pgItem = currDoc->DocItems.at(b);
1250 					if (pgItem->OwnPage == -1)
1251 						hasfreeItems = true;
1252 					if (pgItem->OwnPage == a)
1253 					{
1254 						if (!pgItem->isGroup())
1255 						{
1256 							OutlineTreeItem *object = new OutlineTreeItem(page, nullptr);
1257 							object->PageItemObject = pgItem;
1258 							object->PageObject = currDoc->DocPages.at(a);
1259 							object->DocObject = currDoc;
1260 							object->type = 3;
1261 							object->setText(0, pgItem->itemName());
1262 							setItemIcon(object, pgItem);
1263 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
1264 						}
1265 						else
1266 						{
1267 							OutlineTreeItem *object = new OutlineTreeItem(page, nullptr);
1268 							object->PageItemObject = pgItem;
1269 							object->PageObject = currDoc->DocPages.at(a);
1270 							object->DocObject = currDoc;
1271 							object->type = 3;
1272 							object->setText(0, pgItem->itemName());
1273 							object->setIcon( 0, groupIcon );
1274 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
1275 							parseSubGroup(object, &pgItem->groupItemList, 3, currDoc->DocPages.at(a));
1276 						}
1277 					}
1278 				}
1279 			}
1280 			page->setText(0, tr("Page ")+tmp.setNum(a+1));
1281 		}
1282 		if (hasfreeItems)
1283 		{
1284 			OutlineTreeItem *page = new OutlineTreeItem( item, pagep );
1285 			pagep = page;
1286 			freeObjects = page;
1287 			page->type = -3;
1288 			page->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1289 			int layerCount = currDoc->layerCount();
1290 			if (layerCount > 1)
1291 			{
1292 				QList<PageItem*> pgItems;
1293 				for (int b = 0; b < currDoc->DocItems.count(); ++b)
1294 				{
1295 					pgItem = currDoc->DocItems.at(b);
1296 					if (pgItem->OwnPage == -1)
1297 						pgItems.append(pgItem);
1298 				}
1299 				ScLayer layer;
1300 				layer.ID = 0;
1301 				for (int layerLevel = 0; layerLevel < layerCount; ++layerLevel)
1302 				{
1303 					currDoc->Layers.levelToLayer(layer, layerLevel);
1304 					OutlineTreeItem *ObjLayer = new OutlineTreeItem(page, nullptr);
1305 					ObjLayer->type = 5;
1306 					ObjLayer->LayerID = layer.ID;
1307 					ObjLayer->DocObject = currDoc;
1308 					ObjLayer->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1309 					ObjLayer->setText(0, tr("Layer: \"") + layer.Name + "\"");
1310 					for (int it = 0; it < pgItems.count(); ++it)
1311 					{
1312 						pgItem = pgItems.at(it);
1313 						if (pgItem->m_layerID != layer.ID)
1314 							continue;
1315 						if (!pgItem->isGroup())
1316 						{
1317 							OutlineTreeItem *object = new OutlineTreeItem(ObjLayer, nullptr);
1318 							object->PageItemObject = pgItem;
1319 							object->PageObject = nullptr;
1320 							object->DocObject = currDoc;
1321 							object->type = 4;
1322 							object->setText(0, pgItem->itemName());
1323 							setItemIcon(object, pgItem);
1324 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1325 						}
1326 						else
1327 						{
1328 							OutlineTreeItem *object = new OutlineTreeItem(ObjLayer, nullptr);
1329 							object->PageItemObject = pgItem;
1330 							object->PageObject = nullptr;
1331 							object->DocObject = currDoc;
1332 							object->type = 4;
1333 							object->setText(0, pgItem->itemName());
1334 							object->setIcon( 0, groupIcon );
1335 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1336 							parseSubGroup(object, &pgItem->groupItemList, 4, nullptr);
1337 						}
1338 					}
1339 				}
1340 			}
1341 			else
1342 			{
1343 				for (int b = 0; b < currDoc->DocItems.count(); ++b)
1344 				{
1345 					pgItem = currDoc->DocItems.at(b);
1346 					if (pgItem->OwnPage == -1)
1347 					{
1348 						if (!pgItem->isGroup())
1349 						{
1350 							OutlineTreeItem *object = new OutlineTreeItem(page, nullptr);
1351 							object->PageItemObject = pgItem;
1352 							object->PageObject = nullptr;
1353 							object->DocObject = currDoc;
1354 							object->type = 4;
1355 							object->setText(0, pgItem->itemName());
1356 							setItemIcon(object, pgItem);
1357 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1358 						}
1359 						else
1360 						{
1361 							OutlineTreeItem *object = new OutlineTreeItem(page, nullptr);
1362 							object->PageItemObject = pgItem;
1363 							object->PageObject = nullptr;
1364 							object->DocObject = currDoc;
1365 							object->type = 4;
1366 							object->setText(0, pgItem->itemName());
1367 							object->setIcon( 0, groupIcon );
1368 							object->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1369 							parseSubGroup(object, &pgItem->groupItemList, 4, nullptr);
1370 						}
1371 					}
1372 				}
1373 			}
1374 			page->setText(0, tr("Free Objects"));
1375 		}
1376 	}
1377 	if (storeVals)
1378 		reopenTree();
1379 	reportDisplay->invisibleRootItem()->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
1380 	setUpdatesEnabled(true);
1381 	filterTree();
1382 	if (currDoc->m_Selection->count() > 0)
1383 		slotShowSelect(0, nullptr);
1384 	update();
1385 	connect(reportDisplay, SIGNAL(itemSelectionChanged()), this, SLOT(slotMultiSelect()));
1386 	connect(reportDisplay, SIGNAL(itemChanged(QTreeWidgetItem*,int)), this, SLOT(slotDoRename(QTreeWidgetItem*,int)));
1387 }
1388 
filterTree(const QString & keyword)1389 void OutlinePalette::filterTree(const QString& keyword)
1390 {
1391 	OutlineTreeItem *item = nullptr;
1392 	QTreeWidgetItemIterator it( reportDisplay );
1393 	while ( (*it) )
1394 	{
1395 		item = dynamic_cast<OutlineTreeItem*>(*it);
1396 		if (item != nullptr)
1397 		{
1398 			if ((item->type == 1) || (item->type == 3) || (item->type == 4))
1399 			{
1400 				if (item->PageItemObject->itemName().contains(QRegExp(keyword, Qt::CaseInsensitive)))
1401 					item->setHidden(false);
1402 				else
1403 					item->setHidden(true);
1404 			}
1405 			else
1406 				item->setHidden(false);
1407 		}
1408 		++it;
1409 	}
1410 }
1411 
filterTree()1412 void OutlinePalette::filterTree()
1413 {
1414 	if ( !filterEdit->text().isEmpty() )
1415 		filterTree( filterEdit->text() );
1416 }
1417 
parseSubGroup(OutlineTreeItem * object,QList<PageItem * > * subGroupList,int itemType,ScPage * a)1418 void OutlinePalette::parseSubGroup(OutlineTreeItem* object, QList<PageItem*> *subGroupList, int itemType, ScPage *a)
1419 {
1420 	PageItem *pgItem;
1421 	for (int b = 0; b < subGroupList->count(); ++b)
1422 	{
1423 		pgItem = subGroupList->at(b);
1424 		if (!pgItem->isGroup())
1425 		{
1426 			OutlineTreeItem *grp = new OutlineTreeItem(object, nullptr);
1427 			grp->PageItemObject = pgItem;
1428 			grp->PageObject = a;
1429 			grp->DocObject = currDoc;
1430 			grp->type = itemType;
1431 			grp->setText(0, pgItem->itemName());
1432 			setItemIcon(grp, pgItem);
1433 			if (itemType == 3)
1434 				grp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled);
1435 			else
1436 				grp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1437 		}
1438 		else
1439 		{
1440 			OutlineTreeItem *grp = new OutlineTreeItem(object, nullptr);
1441 			grp->PageItemObject = pgItem;
1442 			grp->PageObject = a;
1443 			grp->DocObject = currDoc;
1444 			grp->type = itemType;
1445 			grp->setText(0, pgItem->itemName());
1446 			grp->setIcon( 0, groupIcon );
1447 			if (itemType == 3)
1448 				grp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled);
1449 			else
1450 				grp->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);
1451 			parseSubGroup(grp, &pgItem->groupItemList, itemType, a);
1452 		}
1453 	}
1454 }
1455 
changeEvent(QEvent * e)1456 void OutlinePalette::changeEvent(QEvent *e)
1457 {
1458 	if (e->type() == QEvent::LanguageChange)
1459 		languageChange();
1460 	else
1461 		ScDockPalette::changeEvent(e);
1462 }
1463 
iconSetChange()1464 void OutlinePalette::iconSetChange()
1465 {
1466 	IconManager& im = IconManager::instance();
1467 	imageIcon = im.loadPixmap("22/insert-image.png");
1468 	latexIcon = im.loadPixmap("22/insert-latex.png");
1469 	lineIcon = im.loadPixmap("stift.png");
1470 	textIcon = im.loadPixmap("22/insert-text-frame.png");
1471 	polylineIcon = im.loadPixmap("22/draw-path.png");
1472 	polygonIcon = im.loadPixmap("22/draw-polygon.png");
1473 	arcIcon = im.loadPixmap("22/draw-arc.png");
1474 	spiralIcon = im.loadPixmap("22/draw-spiral.png");
1475 	tableIcon = im.loadPixmap("22/insert-table.png");
1476 	groupIcon = im.loadPixmap("u_group.png");
1477 	buttonIcon = im.loadPixmap("22/insert-button.png");
1478 	radiobuttonIcon = im.loadPixmap("22/radiobutton.png");
1479 	textFieldIcon = im.loadPixmap("22/text-field.png");
1480 	checkBoxIcon = im.loadPixmap("22/checkbox.png");
1481 	comboBoxIcon = im.loadPixmap("22/combobox.png");
1482 	listBoxIcon = im.loadPixmap("22/list-box.png");
1483 	annotTextIcon = im.loadPixmap("22/pdf-annotations.png");
1484 	annotLinkIcon = im.loadPixmap("goto.png");
1485 	annot3DIcon = im.loadPixmap("22/annot3d.png");
1486 
1487 	if (this->isVisible() && (currDoc != nullptr))
1488 		BuildTree();
1489 }
1490 
languageChange()1491 void OutlinePalette::languageChange()
1492 {
1493 	setWindowTitle( tr("Outline"));
1494 	reportDisplay->setHeaderLabel( tr("Element"));
1495 	filterLabel->setText( tr("Filter:") );
1496 }
1497 
clearPalette()1498 void OutlinePalette::clearPalette()
1499 {
1500 	reportDisplay->clear();
1501 }
1502 
createContextMenu(PageItem * currItem,double,double)1503 void OutlinePalette::createContextMenu(PageItem * currItem, double /*mx*/, double /*my*/)
1504 {
1505 	if (m_MainWindow==nullptr || currDoc==nullptr)
1506 		return;
1507 	ContextMenu* cmen=nullptr;
1508 //	qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
1509 	if (currItem!=nullptr)
1510 		cmen = new ContextMenu(*(currDoc->m_Selection), m_MainWindow, currDoc);
1511 	else
1512 		cmen = new ContextMenu(m_MainWindow, currDoc, currDoc->currentPage()->xOffset(), currDoc->currentPage()->yOffset());
1513 	if (cmen)
1514 		cmen->exec(QCursor::pos());
1515 	delete cmen;
1516 }
1517