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 <QDebug>
9 #include <QEvent>
10 #include <QMenu>
11 #include <QToolTip>
12 #include <QMessageBox>
13 
14 #include "commonstrings.h"
15 #include "fileloader.h"
16 #include "prefsfile.h"
17 #include "prefsmanager.h"
18 #include "scraction.h"
19 #include "scribusdoc.h"
20 #include "scribusview.h"
21 #include "selection.h"
22 #include "shortcutwidget.h"
23 #include "smcellstyle.h"
24 #include "smlinestyle.h"
25 #include "smlinestylewidget.h"
26 #include "smreplacedia.h"
27 #include "smstyleimport.h"
28 #include "smtablestyle.h"
29 #include "smtextstyles.h"
30 #include "styleitem.h"
31 #include "stylemanager.h"
32 #include "ui/customfdialog.h"
33 #include "ui/scmessagebox.h"
34 #include "ui/styleview.h"
35 
36 const QString StyleManager::SEPARATOR = "$$$$"; // dumb but it works
37 
StyleManager(QWidget * parent,const char * name)38 StyleManager::StyleManager(QWidget *parent, const char *name)
39 	: ScrPaletteBase(parent, name)
40 {
41 	setupUi(this);
42 	styleView->hideColumn(SHORTCUT_COL);
43 	styleView->setSelectionMode(QAbstractItemView::ExtendedSelection);
44 	uniqueLabel->hide();
45 	rightFrame->hide();
46 
47 	applyButton->setEnabled(false);
48 	resetButton->setEnabled(false);
49 	m_layout = new QGridLayout(mainFrame);
50 	m_newPopup = new QMenu(newButton);
51 	m_rightClickPopup = new QMenu(styleView);
52 	newButton->setMenu(m_newPopup);
53 	QString pname(name);
54 	if (pname.isEmpty())
55 		pname = "styleManager";
56 	m_prefs = PrefsManager::instance().prefsFile->getContext(pname);
57 	m_editPosition.setX(m_prefs->getInt("eX", x()));
58 	m_editPosition.setY(m_prefs->getInt("eY", y()));
59 
60 	newButton->setEnabled(false);
61 	cloneButton->setEnabled(false);
62 	importButton->setEnabled(false);
63 	deleteButton->setEnabled(false);
64 	m_rightClickPopup->setEnabled(false);
65 	m_newPopup->setEnabled(false);
66 
67 	connect(m_newPopup, SIGNAL(triggered(QAction*)), this, SLOT(slotNewPopup(QAction*)));
68 	connect(okButton, SIGNAL(clicked()), this, SLOT(slotOk()));
69 	connect(importButton, SIGNAL(clicked()), this, SLOT(slotImport()));
70 	connect(resetButton, SIGNAL(clicked()), this, SLOT(slotClean()));
71 	connect(applyButton, SIGNAL(clicked()), this, SLOT(slotApply()));
72 	connect(deleteButton, SIGNAL(clicked()), this, SLOT(slotDelete()));
73 	connect(cloneButton, SIGNAL(clicked()), this, SLOT(slotClone()));
74 	connect(newButton, SIGNAL(clicked()), this, SLOT(slotNew()));
75 	connect(styleView, SIGNAL(customContextMenuRequested(const QPoint &)),
76 			this, SLOT(slotRightClick(const QPoint &)));
77 	connect(styleView, SIGNAL(itemDoubleClicked(QTreeWidgetItem *, int)),
78 			this, SLOT(slotDoubleClick(QTreeWidgetItem *, int)));
79 
80 	languageChange();
81 	slotOk();
82 }
83 
changeEvent(QEvent * e)84 void StyleManager::changeEvent(QEvent *e)
85 {
86 	if (e->type() == QEvent::LanguageChange)
87 	{
88 		languageChange();
89 	}
90 	else
91 		QWidget::changeEvent(e);
92 }
93 
languageChange()94 void StyleManager::languageChange()
95 {
96 	setWindowTitle( tr( "Style Manager" ) );
97 /***********************************/
98 /*      Begin Tooltips             */
99 /***********************************/
100 // These are for general Style Manager widgets (not for c/pstyles except the name field
101 
102 	// for the "<< Done" button when in edit mode
103 	m_exitEditModeOk = tr("Apply all changes and exit edit mode");
104 	// for the "Edit >>" button when not in edit mode
105 	m_enterEditModeOk= tr("Edit styles");
106 
107 	nameEdit->setToolTip(     tr("Name of the selected style"));
108 	resetButton->setToolTip(  tr("Reset all changes"));
109 	applyButton->setToolTip(  tr("Apply all changes"));
110 	newButton->setToolTip(    tr("Create a new style"));
111 	importButton->setToolTip( tr("Import styles from another document"));
112 	cloneButton->setToolTip(  tr("Clone selected style"));
113 	deleteButton->setToolTip( tr("Delete selected styles"));
114 
115 /***********************************/
116 /*      End Tooltips               */
117 /***********************************/
118 
119 	nameLabel->setText( tr("Name:"));
120 	resetButton->setText( tr("&Reset"));
121 	applyButton->setText( tr("&Apply"));
122 	m_doneText= tr("&Done");
123 	m_editText= tr("&Edit");
124 	setOkButtonText();
125 	newButton->setText( tr("&New"));
126 	importButton->setText( tr("&Import"));
127 	cloneButton->setText( tr("&Clone"));
128 	deleteButton->setText( tr("&Delete"));
129 
130 	if (m_isEditMode)
131 		okButton->setToolTip( m_exitEditModeOk);
132 	else
133 		okButton->setToolTip( m_enterEditModeOk);
134 
135 	if (m_shortcutWidget)
136 		m_shortcutWidget->languageChange();
137 
138 	m_newPopup->clear();
139 	QStringList popupStrings;
140 	for (int i = 0; i < m_items.count(); ++i)
141 	{
142 		popupStrings << m_items.at(i)->typeNameSingular();
143 		m_items.at(i)->languageChange();
144 		m_styleClassesPS[m_items.at(i)->typeNamePlural()] = m_items.at(i)->typeNameSingular();
145 		m_styleClassesSP[m_items.at(i)->typeNameSingular()] = m_items.at(i)->typeNamePlural();
146 	}
147 	//12193 turn off sort
148 	//popupStrings.sort();
149 	for (int i = 0; i < popupStrings.count(); ++i)
150 	{
151 		// #13088 : some desktop environment, noticeably KDE Plasma will modify action text
152 		// on the fly to add shortcut keys/text mnemonics. So we have to store the popup
153 		// strings in the action data. See also https://bugs.kde.org/show_bug.cgi?id=337491
154 		QAction* newAction = m_newPopup->addAction(popupStrings[i]);
155 		newAction->setData(popupStrings[i]);
156 	}
157 
158 	styleView->clear();
159 	for (int i = 0; i < m_items.count(); ++i)
160 		addNewType(m_items.at(i));
161 	styleView->resizeColumnToContents(0);
162 
163 	m_rightClickPopup->clear();
164 	m_rcpNewId = m_rightClickPopup->addMenu(m_newPopup);
165 	m_rcpNewId->setText( tr("New"));
166 	m_rightClickPopup->addAction( tr("Import"), this, SLOT(slotImport()));
167 	m_rightClickPopup->addSeparator();
168 	m_rcpEditId = m_rightClickPopup->addAction( tr("Edit"), this, SLOT(slotEdit()));
169 	m_rcpCloneId = m_rightClickPopup->addAction( tr("Clone"), this, SLOT(slotClone()));
170 //	m_rcpToScrapId = m_rightClickPopup->addAction( tr("Send to Scrapbook"), this, SLOT(slotScrap()));
171 	m_rightClickPopup->addSeparator();
172 	m_rcpDeleteId = m_rightClickPopup->addAction( tr("Delete"), this, SLOT(slotDelete()));
173 }
174 
unitChange()175 void StyleManager::unitChange()
176 {
177 	if (m_doc)
178 	{
179 		for (int i = 0; i < m_items.count(); ++i)
180 			m_items.at(i)->unitChange();
181 
182 		slotSetupWidget();
183 	}
184 }
185 
186 template<class ItemType>
item()187 ItemType* StyleManager::item()
188 {
189 	for (int i = 0; i < m_items.count(); ++i)
190 	{
191 		StyleItem* item = m_items[i];
192 		ItemType*  typedItem = qobject_cast<ItemType*>(item);
193 		if (typedItem)
194 			return typedItem;
195 	}
196 	return nullptr;
197 }
198 
setOkButtonText()199 void StyleManager::setOkButtonText()
200 {
201 	if (!m_isStoryEditMode)
202 		okButton->setText(m_isEditMode ? "<< " + m_doneText : m_editText + " >>");
203 	else
204 		okButton->setText(CommonStrings::tr_OK);
205 }
206 
setDoc(ScribusDoc * doc)207 void StyleManager::setDoc(ScribusDoc *doc)
208 {
209 	ScribusDoc* oldDoc = m_doc;
210 	bool hasDoc = (doc != nullptr);
211 	if (m_doc && (m_doc != doc))
212 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(slotDocSelectionChanged()));
213 	m_doc = doc;
214 	newButton->setEnabled(hasDoc);
215 	cloneButton->setEnabled(hasDoc);
216 	importButton->setEnabled(hasDoc);
217 	deleteButton->setEnabled(hasDoc);
218 	m_rightClickPopup->setEnabled(hasDoc);
219 	m_newPopup->setEnabled(hasDoc);
220 	if (m_doc && (m_doc != oldDoc) && this->isVisible())
221 		connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(slotDocSelectionChanged()));
222 
223 	// clear the style list and reload from new doc
224 	styleView->clear();
225 	if (m_selectedStyleAction)
226 	{
227 		m_rightClickPopup->removeAction(m_selectedStyleAction);
228 		m_selectedStyleAction = nullptr;
229 	}
230 	m_styleActions.clear();
231 	for (int i = 0; i < m_items.count(); ++i)
232 	{
233 		m_items.at(i)->setCurrentDoc(doc);
234 		addNewType(m_items.at(i)); // forces a reload
235 		if (m_doc)
236 			m_items.at(i)->unitChange();
237 	}
238 	styleView->resizeColumnToContents(0);
239 }
240 
updateColorList()241 void StyleManager::updateColorList()
242 {
243 	for (int i = 0; i < m_items.count(); ++i)
244 	{
245 		m_items.at(i)->setCurrentDoc(m_doc);
246 		m_items.at(i)->reload();
247 	}
248 }
249 
addStyle(StyleItem * item)250 void StyleManager::addStyle(StyleItem *item)
251 {
252 	m_items.append(item);
253 	addNewType(item);
254 	languageChange(); // upgrade the popup menu with the new item
255 	connect(item, SIGNAL(selectionDirty()), this, SLOT(slotDirty()));
256 }
257 
slotApply()258 void StyleManager::slotApply()
259 {
260 	if (applyButton->isEnabled())
261 	{
262 		// #13390 : we have to proceed with some order here
263 		SMCharacterStyle* charStyleItem = this->item<SMCharacterStyle>();
264 		if (charStyleItem)
265 			charStyleItem->apply();
266 		SMParagraphStyle* paraStyleItem = this->item<SMParagraphStyle>();
267 		if (paraStyleItem)
268 			paraStyleItem->apply();
269 		SMCellStyle* cellStyleItem = this->item<SMCellStyle>();
270 		if (cellStyleItem)
271 			cellStyleItem->apply();
272 		SMTableStyle* tableStyleItem = this->item<SMTableStyle>();
273 		if (tableStyleItem)
274 			tableStyleItem->apply();
275 
276 		for (int i = 0; i < m_items.count(); ++i)
277 		{
278 			StyleItem* item = m_items.at(i);
279 			if (item == charStyleItem || item == paraStyleItem)
280 				continue;
281 			if (item == cellStyleItem || item == tableStyleItem)
282 				continue;
283 			m_items.at(i)->apply();
284 		}
285 		if (m_doc)
286 			m_doc->view()->DrawNew();
287 	}
288 	slotClean();
289 }
290 
slotDelete()291 void StyleManager::slotDelete()
292 {
293 	if (!m_isEditMode)
294 		slotOk(); // switch to edit mode before deleting
295 
296 	QStringList selected;
297 
298 	if (!m_rcStyle.isNull())
299 		selected << m_rcStyle;
300 	else
301 	{
302 		QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selected);
303 		while (*it)
304 		{
305 			selected << (*it)->text(0);
306 			++it;
307 		}
308 	}
309 	if (!m_item || selected.isEmpty())
310 		return; // nothing to delete
311 
312 	QStringList tmp;
313 	QList<StyleName> styles = m_item->styles(false); // get list from cache
314 	for (int i = 0; i < styles.count(); ++i)
315 		tmp << styles[i].first;
316 	SMReplaceDia dia(selected, tmp, this);
317 	if (dia.exec() && m_item)
318 	{
319 		m_item->deleteStyles(dia.items());
320 		applyButton->setEnabled(true);
321 		resetButton->setEnabled(true);
322 		reloadStyleView(false);
323 		slotOk();
324 	}
325 }
326 
327 
slotImport()328 void StyleManager::slotImport()
329 {
330 	if (!m_doc)
331 		return;
332 
333 	PrefsContext* dirs = PrefsManager::instance().prefsFile->getContext("dirs");
334 	QString wdir = dirs->get("editformats", ".");
335 	CustomFDialog dia(this, wdir, tr("Open"), tr("documents (*.sla *.sla.gz *.scd *.scd.gz);;All Files (*)"));
336 	if (dia.exec() != QDialog::Accepted)
337 		return;
338 
339 	QString selectedFile = dia.selectedFile();
340 	dirs->set("editformats", selectedFile.left(selectedFile.lastIndexOf("/")));
341 
342 	StyleSet<ParagraphStyle> tmpParaStyles;
343 	StyleSet<CharStyle> tmpCharStyles;
344 	QHash<QString, multiLine> tmpLineStyles;
345 
346 	m_doc->loadStylesFromFile(selectedFile, &tmpParaStyles, &tmpCharStyles, &tmpLineStyles);
347 
348 // FIXME Once all styles are derived from Style remove this and make a proper
349 //       implementation
350 // Start hack
351 
352 	SMParagraphStyle *pstyle = nullptr;
353 	SMCharacterStyle *cstyle = nullptr;
354 	SMLineStyle      *lstyle = nullptr;
355 	for (int i = 0; i < m_items.count(); ++i)
356 	{
357 		pstyle = qobject_cast<SMParagraphStyle*>(m_items.at(i));
358 		if (pstyle)
359 			break;
360 	}
361 	for (int i = 0; i < m_items.count(); ++i)
362 	{
363 		cstyle = qobject_cast<SMCharacterStyle*>(m_items.at(i));
364 		if (cstyle)
365 			break;
366 	}
367 	for (int i = 0; i < m_items.count(); ++i)
368 	{
369 		lstyle = qobject_cast<SMLineStyle*>(m_items.at(i));
370 		if (lstyle)
371 			break;
372 	}
373 
374 	Q_ASSERT(pstyle && cstyle && lstyle);
375 
376 	SMStyleImport *dia2 = new SMStyleImport(this, &tmpParaStyles, &tmpCharStyles, &tmpLineStyles);
377 // end hack
378 
379 //#7315 		QList<QPair<QString, QString> > selected;
380 	if (dia2->exec())
381 	{
382 //#7385 			if (!m_isEditMode)
383 //#7385 				slotOk();
384 		QStringList neededColors;
385 		neededColors.clear();
386 
387 		foreach (const QString& aStyle, dia2->paragraphStyles())
388 		{
389 			ParagraphStyle& sty(tmpParaStyles[tmpParaStyles.find(aStyle)]);
390 			if (dia2->clashRename())
391 			{
392 				sty.setName(pstyle->getUniqueName(sty.name()));
393 				pstyle->tmpStyles()->create(sty);
394 			}
395 			else
396 			{
397 				if (pstyle->tmpStyles()->find(sty.name()) >= 0)
398 					(*(pstyle->tmpStyles()))[pstyle->tmpStyles()->find(/*it.data()*/aStyle)] = sty;
399 				else
400 					pstyle->tmpStyles()->create(sty);
401 			}
402 //#7315 				selected << QPair<QString, QString>(pstyle->typeName(), sty.name());
403 			if ((!m_doc->PageColors.contains(sty.charStyle().strokeColor())) && (!neededColors.contains(sty.charStyle().strokeColor())))
404 				neededColors.append(sty.charStyle().strokeColor());
405 			if ((!m_doc->PageColors.contains(sty.charStyle().fillColor())) && (!neededColors.contains(sty.charStyle().fillColor())))
406 				neededColors.append(sty.charStyle().fillColor());
407 		}
408 
409 		foreach (const QString& aStyle, dia2->characterStyles())
410 		{
411 			CharStyle& sty(tmpCharStyles[tmpCharStyles.find(/*it.data()*/aStyle)]);
412 			if (dia2->clashRename())
413 			{
414 				sty.setName(cstyle->getUniqueName(sty.name()));
415 				cstyle->tmpStyles()->create(sty);
416 			}
417 			else
418 			{
419 				if (cstyle->tmpStyles()->find(sty.name()) >= 0)
420 					(*(cstyle->tmpStyles()))[cstyle->tmpStyles()->find(/*it.data()*/aStyle)] = sty;
421 				else
422 					cstyle->tmpStyles()->create(sty);
423 			}
424 //#7315 				selected << QPair<QString, QString>(cstyle->typeName(), sty.name());
425 			if ((!m_doc->PageColors.contains(sty.strokeColor())) && (!neededColors.contains(sty.strokeColor())))
426 				neededColors.append(sty.strokeColor());
427 			if ((!m_doc->PageColors.contains(sty.fillColor())) && (!neededColors.contains(sty.fillColor())))
428 				neededColors.append(sty.fillColor());
429 		}
430 
431 		foreach (const QString& aStyle, dia2->lineStyles())
432 		{
433 			multiLine &sty = tmpLineStyles[/*it.data()*/aStyle];
434 			QString styName = aStyle;
435 
436 			if (dia2->clashRename())
437 				styName = lstyle->getUniqueName(aStyle);
438 
439 			lstyle->m_tmpLines[styName] = sty;
440 //#7315 				selected << QPair<QString, QString>(lstyle->typeName(), styName);
441 
442 			for (int i = 0; i < sty.count(); ++i)
443 			{
444 				if ((!m_doc->PageColors.contains(sty[i].Color)) && (!neededColors.contains(sty[i].Color)))
445 					neededColors.append(sty[i].Color);
446 			}
447 		}
448 
449 		if (!neededColors.isEmpty())
450 		{
451 			FileLoader fl(selectedFile);
452 			if (fl.testFile() == -1)
453 			{ //TODO put in nice user warning
454 				delete dia2;
455 				return;
456 			}
457 			ColorList LColors;
458 			if (fl.readColors(LColors))
459 			{
460 				ColorList::Iterator itc;
461 				for (itc = LColors.begin(); itc != LColors.end(); ++itc)
462 				{
463 					if (neededColors.contains(itc.key()))
464 						m_doc->PageColors.insert(itc.key(), itc.value());
465 				}
466 			}
467 		}
468 	}
469 	delete dia2;
470 // Start hack part 2
471 	pstyle->setCurrentDoc(m_doc);
472 	cstyle->setCurrentDoc(m_doc);
473 // end hack part 2
474 	reloadStyleView(false);
475 //#7315 		setSelection(selected);
476 	slotDirty();
477 //#7315		slotSetupWidget();
478 	slotApply();//#7315
479 }
480 
setSelection(const QList<QPair<QString,QString>> & selected)481 void StyleManager::setSelection(const QList<QPair<QString, QString> > &selected)
482 {
483 	styleView->clearSelection();
484 
485 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selectable);
486 	StyleViewItem *item;
487 
488 	while (*it)
489 	{
490 		item = dynamic_cast<StyleViewItem*>(*it);
491 		if (item)
492 		{
493 			for (int i = 0; i < selected.count(); ++i)
494 			{
495 				if (item->rootName() == selected[i].first && item->text(NAME_COL) == selected[i].second)
496 				{
497 					styleView->setCurrentItem(item);
498 					item->setSelected(true);
499 				}
500 			}
501 		}
502 		++it;
503 	}
504 }
505 
slotEdit()506 void StyleManager::slotEdit()
507 {
508 	if (!m_isEditMode)
509 		slotOk(); // switch to edit mode for cloning
510 
511 	if (m_rcStyle.isNull())
512 		return;
513 
514 	QTreeWidgetItemIterator it(styleView);
515 	while (*it)
516 	{
517 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
518 		if (item && !item->isRoot())
519 		{
520 			if (item->rootName() == m_styleClassesSP[m_rcType] &&
521 				item->text(0) == m_rcStyle)
522 			{
523 				styleView->setCurrentItem(item);
524 				item->setSelected(true);
525 				break;
526 			}
527 		}
528 		++it;
529 	}
530 	m_rcStyle.clear();
531 	m_rcType.clear();
532 }
533 
534 
slotClone()535 void StyleManager::slotClone()
536 {
537 	if (!m_isEditMode)
538 		slotOk(); // switch to edit mode for cloning
539 
540 	if (!m_rcStyle.isNull())
541 	{
542 		QTreeWidgetItemIterator it(styleView);
543 		while (*it)
544 		{
545 			StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
546 			if (item && !item->isRoot())
547 			{
548 				if (item->rootName() == m_styleClassesSP[m_rcType] &&
549 				    item->text(0) == m_rcStyle)
550 				{
551 					styleView->setCurrentItem(item);
552 					item->setSelected(true);
553 					break;
554 				}
555 			}
556 			++it;
557 		}
558 		m_rcStyle.clear();
559 		m_rcType.clear();
560 	}
561 
562 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selected);
563 	QList<QPair<QString, QString> > names;
564 
565 	while (*it)
566 	{ // can't create styles here cause createNewStyle() alters the selection
567 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
568 		if (item && !item->isRoot())
569 			names << QPair<QString, QString>(item->rootName(), item->text(NAME_COL));
570 		++it;
571 	}
572 
573 	for (int i = 0; i < names.count(); ++i)
574 		createNewStyle(names[i].first, names[i].second);
575 }
576 
slotScrap()577 void StyleManager::slotScrap()
578 {
579 
580 }
581 
582 
slotNew()583 void StyleManager::slotNew()
584 {
585 //#5334: Don't open into edit mdoe until user has selected a style type
586 // 	if (!m_isEditMode)
587 // 		slotOk(); // switch to edit mode for a new style
588 
589 	// TODO maybe there's something more clever for this
590 	m_newPopup->exec(newButton->mapToGlobal(QPoint(0, newButton->height() + 2)));
591 }
592 
slotNewPopup(QAction * action)593 void StyleManager::slotNewPopup(QAction *action)
594 {
595 	if (!m_isEditMode)
596 		slotOk(); // switch to edit mode for a new style
597 
598 	QString typeName = m_rcType;
599 	QString actionType = action->data().toString();
600 	if (actionType.isEmpty())
601 		actionType = action->text();
602 	if (typeName.isEmpty())
603 		typeName = actionType;
604 	else if (actionType.isEmpty())
605 		return;
606 
607 	m_rcStyle.clear();
608 	m_rcType.clear();
609 
610 	createNewStyle(typeName);
611 }
612 
slotNewPopup()613 void StyleManager::slotNewPopup()
614 {
615 	slotNewPopup(m_rcpNewId);
616 }
617 
slotRightClick(const QPoint & point)618 void StyleManager::slotRightClick(/*StyleViewItem *item, */const QPoint &point/*, int col*/)
619 {
620 	StyleViewItem *item = static_cast<StyleViewItem*>(styleView->currentItem());
621 	m_rcStyle.clear();
622 	m_rcType.clear();
623 
624 	if (m_isEditMode && item) // make item the only selection if in edit mode
625 	{                        // default behaviour for right clicking is not to select the item
626 		styleView->clearSelection();
627 		styleView->setCurrentItem(item);
628 		item->setSelected(true);
629 	}
630 
631 	if (item && !item->isRoot())
632 	{
633 		m_rightClickPopup->removeAction(m_rcpNewId);
634 		m_rcpNewId = m_rightClickPopup->addAction( tr("New %1").arg(m_styleClassesPS[item->rootName()]),
635 												this, SLOT(slotNewPopup()));
636 		m_rcpDeleteId->setEnabled(true);
637 		m_rcpEditId->setEnabled(true);
638 		m_rcpCloneId->setEnabled(true);
639 //		m_rcpToScrapId->setEnabled(true);
640 		m_rcStyle = item->text(0);
641 		m_rcType = m_styleClassesPS[item->rootName()];
642 		loadType(m_styleClassesPS[item->rootName()]);
643 
644 
645 		// Add "Apply" menu entry
646 		if (m_selectedStyleAction)
647 		{
648 			m_rightClickPopup->removeAction(m_selectedStyleAction);
649 			m_selectedStyleAction = nullptr;
650 		}
651 		if (styleView->selectedItems().count() == 1)
652 		{
653 			QString key = item->rootName() + SEPARATOR + item->text(NAME_COL);
654 			if (m_styleActions.contains(key))
655 			{
656 				m_selectedStyleAction = m_styleActions[key];
657 				if (m_selectedStyleAction)
658 				{
659 					m_rightClickPopup->insertAction(m_rightClickPopup->actions().first(), m_selectedStyleAction);
660 				}
661 			}
662 		}
663 
664 	}
665 	else if (item && item->isRoot())
666 	{
667 		m_rightClickPopup->removeAction(m_rcpNewId);
668 		m_rcpNewId = m_rightClickPopup->addAction( tr("New %1").arg(m_styleClassesPS[item->text(0)]),
669 												this, SLOT(slotNewPopup()));
670 		m_rcpDeleteId->setEnabled(false);
671 		m_rcpEditId->setEnabled(false);
672 		m_rcpCloneId->setEnabled(false);
673 //		m_rcpToScrapId->setEnabled(false);
674 		m_rcType = m_styleClassesPS[item->text(0)];
675 		loadType(m_rcType);
676 
677 		if (m_selectedStyleAction)
678 		{
679 			m_rightClickPopup->removeAction(m_selectedStyleAction);
680 			m_selectedStyleAction = nullptr;
681 		}
682 	}
683 	else
684 	{
685 		m_rightClickPopup->removeAction(m_rcpNewId);
686 		m_rcpNewId = m_rightClickPopup->addMenu(m_newPopup);
687 		m_rcpNewId->setText( tr("New"));
688 		m_rcpDeleteId->setEnabled(false);
689 		m_rcpEditId->setEnabled(false);
690 		m_rcpCloneId->setEnabled(false);
691 //		m_rcpToScrapId->setEnabled(false);
692 
693 		if (m_selectedStyleAction)
694 		{
695 			m_rightClickPopup->removeAction(m_selectedStyleAction);
696 			m_selectedStyleAction = nullptr;
697 		}
698 	}
699 
700 	m_rightClickPopup->exec(styleView->mapToGlobal(point));
701 }
702 
slotDoubleClick(QTreeWidgetItem * item,int col)703 void StyleManager::slotDoubleClick(QTreeWidgetItem *item, /*const QPoint &point, */int col)
704 {
705 	m_rcStyle.clear();
706 	m_rcType.clear();
707 
708 	if (m_isEditMode && item) // make item the only selection if in edit mode
709 	{
710 		styleView->clearSelection();
711 		styleView->setCurrentItem(item);
712 		item->setSelected(true);
713 		return; // work done, already in edit mode
714 	}
715 
716 	StyleViewItem *sitem = dynamic_cast<StyleViewItem*>(item);
717 	if (sitem && !sitem->isRoot())
718 	{
719 		m_rcType  = m_styleClassesPS[sitem->rootName()];
720 		m_rcStyle = sitem->text(0);
721 		slotEdit(); // switch to edit mode
722 	}
723 	else if (sitem && sitem->isRoot())
724 	{
725 		//slotOk will recreate all items so sitem is invalid after that call
726 		QString itext = sitem->text(0);
727 		if (!m_isEditMode)
728 			slotOk();
729 		createNewStyle(itext);
730 	}
731 	m_rcStyle.clear();
732 	m_rcType.clear();
733 }
734 
createNewStyle(const QString & typeName,const QString & fromParent)735 void StyleManager::createNewStyle(const QString &typeName, const QString &fromParent)
736 {
737 	if (!m_doc)
738 		return;
739 	loadType(typeName); // get the right style class
740 	Q_ASSERT(m_item);
741 
742 	QString newName = fromParent.isNull() ?
743 			m_item->newStyle() : m_item->newStyle(fromParent);
744 // 	qDebug() << "created new style:" << newName << " : " << m_item->isDefaultStyle(newName);
745 	if (newName.isNull())
746 		return;
747 	StyleViewItem *root = nullptr;
748 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::NotSelectable);
749 	while (*it)
750 	{
751 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
752 		if (item)
753 		{
754 			if (item->text(NAME_COL) == m_item->typeName())
755 			{
756 				root = item;
757 				break;
758 			}
759 		}
760 		++it;
761 	}
762 	assert(root);
763 	if (!fromParent.isEmpty())
764 	{
765 		QTreeWidgetItemIterator it(root, QTreeWidgetItemIterator::Selectable);
766 		while (*it)
767 		{
768 			StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
769 			if (item && item->text(NAME_COL) == fromParent)
770 			{
771 				StyleViewItem *parent = dynamic_cast<StyleViewItem*>((*it)->parent());
772 				if (parent)
773 				{
774 					root = parent;
775 					break;
776 				}
777 			}
778 			++it;
779 		}
780 	}
781 	styleView->clearSelection();
782 	StyleViewItem *newItem = new StyleViewItem(root, newName, m_item->typeName());
783 	Q_CHECK_PTR(newItem);
784 	newItem->setDirty(true);
785 	styleView->setCurrentItem(newItem);
786 	newItem->setSelected(true);
787 	slotSetupWidget();
788 	nameEdit->setFocus();
789 	nameEdit->selectAll();
790 	applyButton->setEnabled(true);
791 	resetButton->setEnabled(true);
792 }
793 
794 // open or close edit mode
slotOk()795 void StyleManager::slotOk()
796 {
797 	static bool isFirst = true;
798 	if (m_isEditMode)
799 	{
800 		disconnect(styleView, SIGNAL(itemSelectionChanged()), this, SLOT(slotSetupWidget()));
801 		slotApply();
802 
803 		okButton->setText(QString("%1 >>").arg( tr("&Edit")));
804 		editFrame->hide();
805 		applyButton->hide();
806 		resetButton->hide();
807 		rightFrame->hide();
808 		m_isEditMode = false;
809 		for (int i = 0; i < m_items.count(); ++i)
810 		{
811 			m_items.at(i)->apply();
812 			m_items.at(i)->editMode(false);
813 		}
814 		okButton->setToolTip( m_enterEditModeOk);
815 		slotClean();
816 		slotDocSelectionChanged();
817 
818 		if (!isFirst)
819 			move(m_editPosition);
820 		m_prefs->set("isEditMode", m_isEditMode);
821 // 		qDebug() <<"CONNECT slotOK";
822 // 		connect(styleView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
823 // 		        this, SLOT(slotApplyStyle(QTreeWidgetItem*,QTreeWidgetItem*)));
824 // 		connect(styleView, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
825 // 				this, SLOT(slotApplyStyle(QTreeWidgetItem*,int)));
826 		if (m_isStoryEditMode)
827 		{
828 			m_isStoryEditMode=false;
829 			hide();
830 		}
831 
832 		m_rcStyle.clear();
833 		m_rcType.clear();
834 	}
835 	else
836 	{
837 // 		qDebug() <<"DISCONNECT slotOK";
838 // 		disconnect(styleView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
839 // 				   this, SLOT(slotApplyStyle(QTreeWidgetItem*,QTreeWidgetItem*)));
840 // 		disconnect(styleView, SIGNAL(itemClicked(QTreeWidgetItem*,int)),
841 // 				   this, SLOT(slotApplyStyle(QTreeWidgetItem*,int)));
842 
843 		slotSetupWidget();
844 
845 		m_editPosition.setX(x());
846 		m_editPosition.setY(y());
847 		m_prefs->set("eX", x());
848 		m_prefs->set("eY", y());
849 		editFrame->show();
850 		applyButton->show();
851 		resetButton->show();
852 		rightFrame->show();
853 		m_isEditMode = true;
854 		for (int i = 0; i < m_items.count(); ++i)
855 			m_items.at(i)->editMode(true);
856 		okButton->setToolTip( m_exitEditModeOk);
857 		slotClean();
858 
859 		m_prefs->set("isEditMode", m_isEditMode);
860 		connect(styleView, SIGNAL(itemSelectionChanged()), this, SLOT(slotSetupWidget()));
861 	}
862 	setOkButtonText();
863 	isFirst = false;
864 
865 	resize(1, 1); // megahack to keep palette small
866 	updateGeometry();
867 	adjustSize();
868 }
869 
addNewType(StyleItem * item,bool loadFromDoc)870 void StyleManager::addNewType(StyleItem *item, bool loadFromDoc)
871 {
872 	if (!item)
873 		return;
874 
875 	m_item = item;
876 
877 	QList<StyleName> styles = m_item->styles(loadFromDoc);
878 	StyleViewItem *rootItem = new StyleViewItem(styleView, m_item->typeName());
879 	styleView->expandItem(rootItem);
880 	QMap<QString, StyleViewItem*> sitems;
881 
882 	for (int i = 0; i < styles.count(); ++i) // set the list of styles of this type
883 	{
884 		StyleViewItem *sitem;
885 		if (styles[i].second.isNull())
886 		{
887 			sitem = new StyleViewItem(rootItem, styles[i].first, m_item->typeName());
888 		}
889 		else if (sitems.contains(styles[i].second))
890 		{
891 			StyleViewItem *parent = sitems[styles[i].second];
892 			sitem = new StyleViewItem(parent, styles[i].first, m_item->typeName());
893 			styleView->expandItem(parent);
894 		}
895 		else
896 		{
897 			bool postpone = false;
898 			// search if parent is in remaining styles
899 			for (int j = i+1; j < styles.count(); ++j)
900 			{
901 				if (styles[j].first == styles[i].second)
902 				{
903 					styles.append(styles[i]); // postpone
904 					postpone = true;
905 				}
906 			}
907 			if (postpone)
908 				continue;
909 			qDebug() << QString("stylemanager: unknown parent '%1' of %2 style '%3'").arg(styles[i].second, m_item->typeName(), styles[i].first);
910 			sitem = new StyleViewItem(rootItem, styles[i].first, m_item->typeName());
911 		}
912 
913 		sitems[styles[i].first] = sitem;
914 		QString shortcutValue(m_item->shortcut(sitem->text(NAME_COL)));
915 		sitem->setText(SHORTCUT_COL, shortcutValue);
916 
917 		QString key = sitem->rootName() + SEPARATOR + sitem->text(NAME_COL);
918 		if (m_styleActions.contains(key))
919 			continue;
920 
921 		m_styleActions[key] = new ScrAction(ScrAction::DataQString, QString(), QString(), tr("&Apply"), shortcutValue, m_doc->view(), key);
922 		connect(m_styleActions[key], SIGNAL(triggeredData(QString)), this, SLOT(slotApplyStyle(QString)));
923 	}
924 }
925 
slotDirty()926 void StyleManager::slotDirty()
927 {
928 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selected);
929 
930 	while (*it)
931 	{
932 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
933 		if (item)
934 		{
935 			item->setDirty(true);
936 			applyButton->setEnabled(true);
937 			resetButton->setEnabled(true);
938 		}
939 		++it;
940 	}
941 	applyButton->setEnabled(true);
942 	resetButton->setEnabled(true);
943 }
944 
slotClean()945 void StyleManager::slotClean()
946 {
947 	QTreeWidgetItemIterator it(styleView);
948 
949 	while (*it)
950 	{
951 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
952 		if (item)
953 			item->setDirty(false);
954 		++it;
955 	}
956 
957 	if (m_isEditMode)
958 	{
959 		StyleItem *tmp = m_item;
960 
961 		for (int i = 0; i < m_items.count(); ++i)
962 		{
963 			m_item = m_items.at(i);
964 			reloadStyleView();
965 		}
966 		slotSetupWidget();
967 		m_item = tmp;
968 	}
969 	applyButton->setEnabled(false);
970 	resetButton->setEnabled(false);
971 	uniqueLabel->hide();
972 }
973 
reloadStyleView(bool loadFromDoc)974 void StyleManager::reloadStyleView(bool loadFromDoc)
975 {
976 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selected);
977 	QList<QPair<QString, QString> > selected;
978 
979 	while (*it)
980 	{
981 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it);
982 		if (item)
983 			selected << QPair<QString, QString>(item->rootName(), item->text(NAME_COL));
984 		++it;
985 	}
986 
987 	styleView->clear();
988 	if (m_item && loadFromDoc)
989 		m_item->reload();
990 
991 	for (int i = 0; i < m_items.count(); ++i)
992 		addNewType(m_items.at(i), false);
993 
994 	QTreeWidgetItemIterator it2(styleView, QTreeWidgetItemIterator::Selectable);
995 
996 	while (*it2)
997 	{
998 		StyleViewItem *item = dynamic_cast<StyleViewItem*>(*it2);
999 		if (item)
1000 		{
1001 			for (int i = 0; i < selected.count(); ++i)
1002 			{
1003 				if (selected[i].first == item->rootName() &&
1004 				    selected[i].second == item->text(NAME_COL))
1005 				{
1006 					item->setDirty(false);
1007 					styleView->setCurrentItem(item);
1008 					item->setSelected(true);
1009 					break;
1010 				}
1011 			}
1012 		}
1013 		++it2;
1014 	}
1015 
1016 //#7318 Do not auto resize vertically 	styleView->resizeColumnToContents(0);
1017 // 	styleView->repaint();
1018 }
1019 
insertShortcutPage(QTabWidget * twidget)1020 void StyleManager::insertShortcutPage(QTabWidget *twidget)
1021 {
1022 	if (!twidget)
1023 		return;
1024 
1025 	if (!m_shortcutWidget)
1026 	{
1027 		m_shortcutWidget = new ShortcutWidget(nullptr);
1028 		m_shortcutWidget->setAllowedModifiers(Qt::META|Qt::CTRL|Qt::SHIFT|Qt::ALT,0);
1029 		connect(m_shortcutWidget, SIGNAL(newKey(const QString&)),
1030 				this, SLOT(slotShortcutChanged(const QString&)));
1031 	}
1032 	twidget->addTab(m_shortcutWidget, tr("Shortcut"));
1033 }
1034 
slotNameChanged(const QString & name)1035 void StyleManager::slotNameChanged(const QString& name)
1036 {
1037 	if (m_item && name.isEmpty())
1038 	{
1039 		okButton->setEnabled(false);
1040 		applyButton->setEnabled(false);
1041 		return;
1042 	}
1043 	if (m_item && !nameIsUnique(name))
1044 	{
1045 		uniqueLabel->show();
1046 		okButton->setEnabled(false);
1047 		applyButton->setEnabled(false);
1048 		return;
1049 	}
1050 	if (uniqueLabel->isVisible())
1051 	{
1052 		uniqueLabel->hide();
1053 		okButton->setEnabled(true);
1054 		applyButton->setEnabled(true);
1055 	}
1056 
1057 	if (m_item)
1058 	{
1059 		m_item->nameChanged(name);
1060 		updateActionName(styleView->currentItem()->text(NAME_COL), name);
1061 		styleView->currentItem()->setText(NAME_COL, name);
1062 		applyButton->setEnabled(true);
1063 		resetButton->setEnabled(true);
1064 	}
1065 }
1066 
1067 
updateActionName(const QString & oldName,const QString & newName)1068 void StyleManager::updateActionName(const QString &oldName, const QString &newName)
1069 {
1070 	if (!m_item)
1071 		return;
1072 	QString oldKey = m_item->typeName() + SEPARATOR + oldName;
1073 	QString newKey = m_item->typeName() + SEPARATOR + newName;
1074 
1075 	if (m_styleActions.contains(oldKey))
1076 	{
1077 		ScrAction *a = m_styleActions[oldKey];
1078 		disconnect(a, SIGNAL(triggeredData(QString)), this, SLOT(slotApplyStyle(QString)));
1079 		ScrAction *b = new ScrAction(ScrAction::DataQString, QString(), QString(), tr("&Apply"),
1080 						   a->shortcut(), m_doc->view(), newKey);
1081 		m_styleActions.remove(oldKey);
1082 		if (m_selectedStyleAction == a)
1083 		{
1084 			m_rightClickPopup->removeAction(m_selectedStyleAction);
1085 			m_selectedStyleAction = nullptr;
1086 		}
1087 		delete a;
1088 		m_styleActions[newKey] = b;
1089 		connect(b, SIGNAL(triggeredData(QString)), this, SLOT(slotApplyStyle(QString)));
1090 	}
1091 }
1092 
slotShortcutChanged(const QString & shortcut)1093 void StyleManager::slotShortcutChanged(const QString& shortcut)
1094 {
1095 	if (!m_doc)
1096 		return;
1097 
1098 	StyleViewItem *sitem = dynamic_cast<StyleViewItem*>(styleView->currentItem());
1099 	if (!sitem)
1100 		return;
1101 
1102 	if (!shortcut.isNull() && shortcutExists(shortcut))
1103 	{
1104 		ScMessageBox::information(this, CommonStrings::trWarning,
1105 		                         tr("This key sequence is already in use"));
1106 		if (m_shortcutWidget)
1107 			m_shortcutWidget->setShortcut(m_item->shortcut(sitem->text(NAME_COL)));
1108 		return;
1109 	}
1110 
1111 	sitem->setText(SHORTCUT_COL, shortcut.isNull() ? "" : shortcut);
1112 	QString key = sitem->rootName() + SEPARATOR + sitem->text(NAME_COL);
1113 	if (m_styleActions.contains(key))
1114 		m_styleActions[key]->setShortcut(shortcut);
1115 	else
1116 	{
1117 		m_styleActions[key] = new ScrAction(ScrAction::DataQString, QString(), QString(), tr("&Apply"), shortcut, m_doc->view(), key);
1118 		connect(m_styleActions[key], SIGNAL(triggeredData(QString)), this, SLOT(slotApplyStyle(QString)));
1119 	}
1120 
1121 	if (m_item)
1122 		m_item->setShortcut(shortcut);
1123 }
1124 
shortcutExists(const QString & keys)1125 bool StyleManager::shortcutExists(const QString &keys)
1126 {
1127 	QKeySequence key(keys);
1128 
1129 	QMap<QString, QPointer<ScrAction> >::iterator it;
1130 	for (it = m_styleActions.begin(); it != m_styleActions.end(); ++it)
1131 	{
1132 		if ((*it)->shortcut() == key)
1133 			return true;
1134 	}
1135 
1136 	ApplicationPrefs *prefsData=&(PrefsManager::instance().appPrefs);
1137 	for (QMap<QString,Keys>::Iterator it=prefsData->keyShortcutPrefs.KeyActions.begin();
1138 		 it!=prefsData->keyShortcutPrefs.KeyActions.end(); ++it)
1139 	{
1140 		if (key.matches(it.value().keySequence) != QKeySequence::NoMatch)
1141 			return true;
1142 	}
1143 
1144 	return false;
1145 }
1146 
slotApplyStyle(const QString & keyString)1147 void StyleManager::slotApplyStyle(const QString& keyString)
1148 {
1149 	if (m_isEditMode)
1150 		return;
1151 
1152 	QStringList slist = keyString.split(SEPARATOR, Qt::SkipEmptyParts);
1153 	Q_ASSERT(slist.count() == 2);
1154 
1155 	loadType(slist[0]);
1156 	m_item->toSelection(slist[1]);
1157 	slotDocSelectionChanged();
1158 
1159 	m_rcStyle.clear();
1160 	m_rcType.clear();
1161 }
1162 
nameIsUnique(const QString & name)1163 bool StyleManager::nameIsUnique(const QString &name)
1164 {
1165 	QList<StyleName> names = m_item->styles(false);
1166 	for (int i = 0; i < names.count(); ++i)
1167 	{
1168 		if (names[i].first == name)
1169 			return false;
1170 	}
1171 	return true;
1172 }
1173 
1174 // setups the selected type and edit widgets related to it
slotSetupWidget()1175 void StyleManager::slotSetupWidget()
1176 {
1177 	QPair<QString, QStringList> selection = namesFromSelection();
1178 	QString typeName = selection.first;
1179 // 	qDebug()<<"slotSetupWidget"<<selection.first<<selection.second.join("|");
1180 	if (typeName.isEmpty() && m_widget)
1181 		m_widget->setEnabled(false); // nothing selected or two or more different types
1182 	else if (!m_item || (m_item->typeName() != typeName) || (m_widget != m_item->widget()))
1183 		loadType(typeName); // new type selected
1184 	else if (m_widget && !m_widget->isEnabled())
1185 		m_widget->setEnabled(true);
1186 
1187 	disconnect(nameEdit, SIGNAL(textChanged(const QString&)), this, SLOT(slotNameChanged(const QString&)));
1188 	if (!typeName.isEmpty())
1189 	{
1190 		m_item->selected(selection.second);
1191 		if (selection.second.count() > 1)
1192 		{
1193 			nameEdit->setText( tr("More than one style selected"));
1194 			nameEdit->setEnabled(false);
1195 			if (m_shortcutWidget)
1196 			{
1197 				m_shortcutWidget->setEnabled(false);
1198 				m_shortcutWidget->setShortcut(QString());
1199 			}
1200 		}
1201 		else
1202 		{
1203 			nameEdit->setText(selection.second[0]);
1204 // 			qDebug() << selection.second[0] << m_item->isDefaultStyle(selection.second[0]);
1205 			nameEdit->setEnabled(! (m_item->isDefaultStyle(selection.second[0])));
1206 			if (m_shortcutWidget)
1207 			{
1208 				m_shortcutWidget->setEnabled(true);
1209 				m_shortcutWidget->setShortcut(m_item->shortcut(selection.second[0]));
1210 			}
1211 		}
1212 	}
1213 	else
1214 	{
1215 		nameEdit->setText("");
1216 		nameEdit->setEnabled(false);
1217 	}
1218 
1219 	connect(nameEdit, SIGNAL(textChanged(const QString&)),
1220 	        this, SLOT(slotNameChanged(const QString&)));
1221 
1222 }
1223 
slotApplyStyle(QTreeWidgetItem * item)1224 void StyleManager::slotApplyStyle(QTreeWidgetItem *item)
1225 {
1226 	StyleViewItem *sitem = dynamic_cast<StyleViewItem*>(item);
1227 
1228 	if (m_isEditMode || !sitem || sitem->isRoot())
1229 		return; // don't apply a style in edit mode or if there was no item/type selected
1230 
1231 	styleView->clearSelection();
1232 
1233 	if (!m_item || m_item->typeName() != sitem->rootName())
1234 		loadType(sitem->rootName()); // load the type where we want to apply this style
1235 
1236 	Q_ASSERT(m_item);
1237 
1238 	m_item->toSelection(sitem->text(NAME_COL)); // apply selected style to the selection
1239 
1240 	slotDocSelectionChanged();
1241 
1242 	m_rcStyle.clear();
1243 	m_rcType.clear();
1244 }
1245 
slotApplyStyle(QTreeWidgetItem * newitem,QTreeWidgetItem *)1246 void StyleManager::slotApplyStyle(QTreeWidgetItem *newitem, QTreeWidgetItem *)
1247 {
1248 	slotApplyStyle(newitem);
1249 }
1250 
slotApplyStyle(QTreeWidgetItem * item,int)1251 void StyleManager::slotApplyStyle(QTreeWidgetItem *item, int)
1252 {
1253 	slotApplyStyle(item);
1254 }
1255 
slotDocSelectionChanged()1256 void StyleManager::slotDocSelectionChanged()
1257 {
1258 	if (m_isEditMode)
1259 		return; // don't track changes when in edit mode
1260 
1261 // 	qDebug() << "Style Manager : doc selection changed";
1262 
1263 // 	qDebug() <<"DISCONNECT slotDocSelectionChanged";
1264 // 	disconnect(styleView, SIGNAL(currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)),
1265 // 	           this, SLOT(slotApplyStyle(QTreeWidgetItem*, QTreeWidgetItem*)));
1266 
1267 	styleView->clearSelection();
1268 
1269 	QList<QPair<QString, QString> > selected;
1270 
1271 	for (int i = 0; i < m_items.count(); ++i)
1272 		selected << QPair<QString, QString>(m_items.at(i)->typeName(), m_items.at(i)->fromSelection());
1273 
1274 	QTreeWidgetItemIterator it(styleView, QTreeWidgetItemIterator::Selectable);
1275 	StyleViewItem *item;
1276 
1277 	while (*it)
1278 	{
1279 		item = dynamic_cast<StyleViewItem*>(*it);
1280 		if (item)
1281 		{
1282 			for (int i = 0; i < selected.count(); ++i)
1283 			{
1284 				if (item->rootName() == selected[i].first && item->text(NAME_COL) == selected[i].second)
1285 				{
1286 					styleView->setCurrentItem(item);
1287 					item->setSelected(true);
1288 				}
1289 			}
1290 		}
1291 		++it;
1292 	}
1293 // 	qDebug() <<"CONNECT slotDocSelectionChanged";
1294 // 	connect(styleView, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)),
1295 // 	        this, SLOT(slotApplyStyle(QTreeWidgetItem*,QTreeWidgetItem*)));
1296 }
1297 
slotDocStylesChanged()1298 void StyleManager::slotDocStylesChanged()
1299 {
1300 	qDebug() << "slotDocStylesChanged()";
1301 }
1302 
1303 // QPair.first == QString() if nothing is selected or if
1304 // there are items from more than one type in the selection
1305 // if selection is valid (only from single type) QPair.first will
1306 // include the type name and QPair.second will have all the selected
1307 // stylenames in it
namesFromSelection()1308 QPair<QString, QStringList> StyleManager::namesFromSelection()
1309 {
1310 	QString typeName;
1311 	QStringList styleNames;
1312 	if (m_rcStyle.isNull())
1313 	{
1314 		foreach(QTreeWidgetItem * it, styleView->selectedItems())
1315 		{
1316 			StyleViewItem *item = dynamic_cast<StyleViewItem*>(it);
1317 			if (!item)
1318 				continue;
1319 			if (typeName.isNull())
1320 				typeName = item->rootName();
1321 			else if (!typeName.isNull() && typeName != item->rootName())
1322 			{
1323 				typeName.clear();
1324 				break; // two different types selected returning null
1325 			}
1326 
1327 			if (!item->isRoot())
1328 				styleNames << item->text(NAME_COL);
1329 		}
1330 	}
1331 	else // right click selection which doesn't show in the gui
1332 	{
1333 		typeName = m_rcType;
1334 		styleNames << m_rcStyle;
1335 	}
1336 	return QPair<QString, QStringList>(typeName, styleNames);
1337 }
1338 
1339 // sets the current type to name including m_item and the main widget
1340 // for editing styles
loadType(const QString & name)1341 void StyleManager::loadType(const QString &name)
1342 {
1343 	m_item = nullptr;
1344 	for (int i = 0; i < m_items.count(); ++i)
1345 	{
1346 		if (m_items.at(i)->typeNameSingular() == name || m_items.at(i)->typeName() == name)
1347 		{
1348 			m_item = m_items.at(i);
1349 			break;
1350 		}
1351 	}
1352 	if (!m_item)
1353 		return;
1354 
1355 	if (m_widget)
1356 	{   // remove the old style type's widget
1357 		m_widget->hide();
1358 		m_layout->removeWidget(m_widget);
1359 //		m_widget->reparent(0,0, QPoint(0,0), false);
1360 		// show the widget for the new style type
1361 		if (m_shortcutWidget)
1362 			m_widget->removeTab(m_widget->indexOf(m_shortcutWidget));
1363 	}
1364 	m_widget = m_item->widget(); // show the widget for the style type
1365 	//<<#8230: Hide the shortcut page as it does not work
1366 	//insertShortcutPage(m_widget);
1367 	//>>
1368 	m_widget->setParent(mainFrame);
1369 	m_layout->setContentsMargins(0, 0, 0, 0);
1370 	m_layout->addWidget(m_widget, 0, 0);
1371 	layout()->activate();
1372 	m_widget->resize(m_widget->minimumSizeHint());
1373 	m_widget->setEnabled(true);
1374 	m_widget->show();
1375 }
1376 
hideEvent(QHideEvent * e)1377 void StyleManager::hideEvent(QHideEvent *e)
1378 {
1379 	if (m_doc)
1380 		disconnect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(slotDocSelectionChanged()));
1381 	m_prefs->set("eX", x());
1382 	m_prefs->set("eY", y());
1383 	m_prefs->set("isEditMode", m_isEditMode);
1384 	m_prefs->set("InitX", x());
1385 	m_prefs->set("InitY", y());
1386 	storeVisibility(false);
1387 	storePosition();
1388 	ScrPaletteBase::hideEvent(e);
1389 	emit closed();
1390 }
1391 
closeEvent(QCloseEvent * e)1392 void StyleManager::closeEvent(QCloseEvent *e)
1393 {
1394 	m_prefs->set("eX", x());
1395 	m_prefs->set("eY", y());
1396 	m_prefs->set("isEditMode", m_isEditMode);
1397 	m_prefs->set("InitX", x());
1398 	m_prefs->set("InitY", y());
1399 	storeVisibility(false);
1400 	storePosition();
1401 	ScrPaletteBase::closeEvent(e);
1402 	emit closed();
1403 }
1404 
showEvent(QShowEvent * e)1405 void StyleManager::showEvent(QShowEvent *e)
1406 {
1407 	static bool isFirst = true;
1408 	if (isModal())
1409 	{
1410 		m_isStoryEditMode=true;
1411 		applyButton->setEnabled(false);
1412 		slotEdit();
1413 	}
1414 	setOkButtonText();
1415 	ScrPaletteBase::showEvent(e);
1416 	if (isFirst)
1417 	{
1418 		QPoint p(m_prefs->getInt("InitX", x()), m_prefs->getInt("InitY", y()));
1419 		move(p);
1420 		isFirst = false;
1421 	}
1422 	if (m_doc)
1423 		connect(m_doc->m_Selection, SIGNAL(selectionChanged()), this, SLOT(slotDocSelectionChanged()));
1424 }
1425 
~StyleManager()1426 StyleManager::~StyleManager()
1427 {
1428 	m_prefs->set("eX", x());
1429 	m_prefs->set("eY", y());
1430 	m_prefs->set("isEditMode", m_isEditMode);
1431 	m_prefs->set("InitX", x());
1432 	m_prefs->set("InitY", y());
1433 	storeVisibility(this->isVisible());
1434 	storePosition();
1435 
1436 	while (m_items.count() > 0)
1437 	{
1438 		StyleItem* styleItem = m_items.takeAt(0);
1439 		delete styleItem;
1440 	}
1441 }
1442