1 // qsynthPaletteForm.cpp
2 //
3 /****************************************************************************
4    Copyright (C) 2003-2020, rncbc aka Rui Nuno Capela. All rights reserved.
5 
6    This program is free software; you can redistribute it and/or
7    modify it under the terms of the GNU General Public License
8    as published by the Free Software Foundation; either version 2
9    of the License, or (at your option) any later version.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License along
17    with this program; if not, write to the Free Software Foundation, Inc.,
18    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 
20 *****************************************************************************/
21 
22 #include "qsynthAbout.h"
23 #include "qsynthPaletteForm.h"
24 
25 #include "ui_qsynthPaletteForm.h"
26 
27 #include <QMetaProperty>
28 #include <QToolButton>
29 #include <QHeaderView>
30 #include <QLabel>
31 
32 #include <QHash>
33 
34 #include <QPainter>
35 #include <QStyle>
36 #include <QStyleOption>
37 
38 #include <QColorDialog>
39 #include <QFileDialog>
40 #include <QMessageBox>
41 
42 
43 // Local static consts.
44 static const char *ColorThemesGroup   = "/ColorThemes/";
45 
46 static const char *PaletteEditorGroup = "/PaletteEditor/";
47 static const char *DefaultDirKey      = "DefaultDir";
48 static const char *ShowDetailsKey     = "ShowDetails";
49 static const char *DefaultSuffix      = "conf";
50 
51 
52 static struct
53 {
54 	const char *key;
55 	QPalette::ColorRole value;
56 
57 } g_colorRoles[] = {
58 
59 	{ "Window",          QPalette::Window          },
60 	{ "WindowText",      QPalette::WindowText      },
61 	{ "Button",          QPalette::Button          },
62 	{ "ButtonText",      QPalette::ButtonText      },
63 	{ "Light",           QPalette::Light           },
64 	{ "Midlight",        QPalette::Midlight        },
65 	{ "Dark",            QPalette::Dark            },
66 	{ "Mid",             QPalette::Mid             },
67 	{ "Text",            QPalette::Text            },
68 	{ "BrightText",      QPalette::BrightText      },
69 	{ "Base",            QPalette::Base            },
70 	{ "AlternateBase",   QPalette::AlternateBase   },
71 	{ "Shadow",          QPalette::Shadow          },
72 	{ "Highlight",       QPalette::Highlight       },
73 	{ "HighlightedText", QPalette::HighlightedText },
74 	{ "Link",            QPalette::Link            },
75 	{ "LinkVisited",     QPalette::LinkVisited     },
76 	{ "ToolTipBase",     QPalette::ToolTipBase     },
77 	{ "ToolTipText",     QPalette::ToolTipText     },
78 #if QT_VERSION >= QT_VERSION_CHECK(5, 12, 0)
79 	{ "PlaceholderText", QPalette::PlaceholderText },
80 #endif
81 	{ "NoRole",          QPalette::NoRole          },
82 
83 	{  nullptr,          QPalette::NoRole          }
84 };
85 
86 
87 //-------------------------------------------------------------------------
88 // qsynthPaletteForm
89 
qsynthPaletteForm(QWidget * parent,const QPalette & pal)90 qsynthPaletteForm::qsynthPaletteForm ( QWidget *parent, const QPalette& pal )
91 	: QDialog(parent), p_ui(new Ui::qsynthPaletteForm), m_ui(*p_ui)
92 {
93 	m_ui.setupUi(this);
94 
95 	m_settings = nullptr;
96 	m_owner = false;
97 
98 	m_modelUpdated = false;
99 	m_paletteUpdated = false;
100 	m_dirtyCount = 0;
101 	m_dirtyTotal = 0;
102 
103 	updateGenerateButton();
104 
105 	m_paletteModel = new PaletteModel(this);
106 	m_ui.paletteView->setModel(m_paletteModel);
107 	ColorDelegate *delegate = new ColorDelegate(this);
108 	m_ui.paletteView->setItemDelegate(delegate);
109 	m_ui.paletteView->setEditTriggers(QAbstractItemView::AllEditTriggers);
110 //	m_ui.paletteView->setAlternatingRowColors(true);
111 	m_ui.paletteView->setSelectionBehavior(QAbstractItemView::SelectRows);
112 	m_ui.paletteView->setDragEnabled(true);
113 	m_ui.paletteView->setDropIndicatorShown(true);
114 	m_ui.paletteView->setRootIsDecorated(false);
115 	m_ui.paletteView->setColumnHidden(2, true);
116 	m_ui.paletteView->setColumnHidden(3, true);
117 
118 	QObject::connect(m_ui.nameCombo,
119 		SIGNAL(editTextChanged(const QString&)),
120 		SLOT(nameComboChanged(const QString&)));
121 	QObject::connect(m_ui.saveButton,
122 		SIGNAL(clicked()),
123 		SLOT(saveButtonClicked()));
124 	QObject::connect(m_ui.deleteButton,
125 		SIGNAL(clicked()),
126 		SLOT(deleteButtonClicked()));
127 
128 	QObject::connect(m_ui.generateButton,
129 		SIGNAL(changed()),
130 		SLOT(generateButtonChanged()));
131 	QObject::connect(m_ui.resetButton,
132 		SIGNAL(clicked()),
133 		SLOT(resetButtonClicked()));
134 	QObject::connect(m_ui.detailsCheck,
135 		SIGNAL(clicked()),
136 		SLOT(detailsCheckClicked()));
137 	QObject::connect(m_ui.importButton,
138 		SIGNAL(clicked()),
139 		SLOT(importButtonClicked()));
140 	QObject::connect(m_ui.exportButton,
141 		SIGNAL(clicked()),
142 		SLOT(exportButtonClicked()));
143 
144 	QObject::connect(m_paletteModel,
145 		SIGNAL(paletteChanged(const QPalette&)),
146 		SLOT(paletteChanged(const QPalette&)));
147 
148 	QObject::connect(m_ui.dialogButtons,
149 		SIGNAL(accepted()),
150 		SLOT(accept()));
151 	QObject::connect(m_ui.dialogButtons,
152 		SIGNAL(rejected()),
153 		SLOT(reject()));
154 
155 	setPalette(pal, pal);
156 
157 	QDialog::adjustSize();
158 }
159 
160 
~qsynthPaletteForm(void)161 qsynthPaletteForm::~qsynthPaletteForm (void)
162 {
163 	setSettings(nullptr);
164 }
165 
166 
setPalette(const QPalette & pal)167 void qsynthPaletteForm::setPalette ( const QPalette& pal )
168 {
169 	m_palette = pal;
170 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
171 	const uint mask = pal.resolveMask();
172 #else
173 	const uint mask = pal.resolve();
174 #endif
175 	for (int i = 0; g_colorRoles[i].key; ++i) {
176 		if ((mask & (1 << i)) == 0) {
177 			const QPalette::ColorRole cr = QPalette::ColorRole(i);
178 			m_palette.setBrush(QPalette::Active, cr,
179 				m_parentPalette.brush(QPalette::Active, cr));
180 			m_palette.setBrush(QPalette::Inactive, cr,
181 				m_parentPalette.brush(QPalette::Inactive, cr));
182 			m_palette.setBrush(QPalette::Disabled, cr,
183 				m_parentPalette.brush(QPalette::Disabled, cr));
184 		}
185 	}
186 #if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
187 	m_palette.setResolveMask(mask);
188 #else
189 	m_palette.resolve(mask);
190 #endif
191 
192 	updateGenerateButton();
193 
194 	m_paletteUpdated = true;
195 	if (!m_modelUpdated)
196 		m_paletteModel->setPalette(m_palette, m_parentPalette);
197 	m_paletteUpdated = false;
198 }
199 
200 
setPalette(const QPalette & pal,const QPalette & parentPal)201 void qsynthPaletteForm::setPalette ( const QPalette& pal, const QPalette& parentPal )
202 {
203 	m_parentPalette = parentPal;
204 
205 	setPalette(pal);
206 }
207 
208 
palette(void) const209 const QPalette& qsynthPaletteForm::palette (void) const
210 {
211 	return m_palette;
212 }
213 
214 
setSettings(QSettings * settings,bool owner)215 void qsynthPaletteForm::setSettings ( QSettings *settings, bool owner )
216 {
217 	if (m_settings && m_owner)
218 		delete m_settings;
219 
220 	m_settings = settings;
221 	m_owner = owner;
222 
223 	m_ui.detailsCheck->setChecked(isShowDetails());
224 
225 	updateNamedPaletteList();
226 	updateDialogButtons();
227 }
228 
229 
settings(void) const230 QSettings *qsynthPaletteForm::settings (void) const
231 {
232 	return m_settings;
233 }
234 
235 
nameComboChanged(const QString & name)236 void qsynthPaletteForm::nameComboChanged ( const QString& name )
237 {
238 	if (m_dirtyCount > 0 || m_ui.nameCombo->findText(name) < 0) {
239 		updateDialogButtons();
240 	} else {
241 		setPaletteName(name);
242 		++m_dirtyTotal;
243 	}
244 }
245 
246 
saveButtonClicked(void)247 void qsynthPaletteForm::saveButtonClicked (void)
248 {
249 	const QString& name = m_ui.nameCombo->currentText();
250 	if (!name.isEmpty()) {
251 		saveNamedPalette(name, m_palette);
252 		setPalette(m_palette, m_palette);
253 		updateNamedPaletteList();
254 		resetButtonClicked();
255 	}
256 }
257 
258 
deleteButtonClicked(void)259 void qsynthPaletteForm::deleteButtonClicked (void)
260 {
261 	const QString& name = m_ui.nameCombo->currentText();
262 	if (m_ui.nameCombo->findText(name) >= 0) {
263 		deleteNamedPalette(name);
264 		updateNamedPaletteList();
265 		updateDialogButtons();
266 	}
267 }
268 
269 
generateButtonChanged(void)270 void qsynthPaletteForm::generateButtonChanged (void)
271 {
272 	const QColor& color
273 		= m_ui.generateButton->brush().color();
274 	const QPalette& pal = QPalette(color);
275 	setPalette(pal);
276 
277 	++m_dirtyCount;
278 	updateDialogButtons();
279 }
280 
281 
resetButtonClicked(void)282 void qsynthPaletteForm::resetButtonClicked (void)
283 {
284 	const bool blocked = blockSignals(true);
285 
286 	for (int i = 0; g_colorRoles[i].key; ++i) {
287 		const QPalette::ColorRole cr = g_colorRoles[i].value;
288 		const QModelIndex& index = m_paletteModel->index(cr, 0);
289 		m_paletteModel->setData(index, false, Qt::EditRole);
290 	}
291 
292 	m_dirtyCount = 0;
293 	updateDialogButtons();
294 
295 	blockSignals(blocked);
296 }
297 
298 
detailsCheckClicked(void)299 void qsynthPaletteForm::detailsCheckClicked (void)
300 {
301 	const int cw = (m_ui.paletteView->viewport()->width() >> 2);
302 	QHeaderView *header = m_ui.paletteView->header();
303 	header->resizeSection(0, cw);
304 	if (m_ui.detailsCheck->isChecked()) {
305 		m_ui.paletteView->setColumnHidden(2, false);
306 		m_ui.paletteView->setColumnHidden(3, false);
307 		header->resizeSection(1, cw);
308 		header->resizeSection(2, cw);
309 		header->resizeSection(3, cw);
310 		m_paletteModel->setGenerate(false);
311 	} else {
312 		m_ui.paletteView->setColumnHidden(2, true);
313 		m_ui.paletteView->setColumnHidden(3, true);
314 		header->resizeSection(1, cw * 3);
315 		m_paletteModel->setGenerate(true);
316 	}
317 }
318 
319 
importButtonClicked(void)320 void qsynthPaletteForm::importButtonClicked (void)
321 {
322 	const QString& title
323 		= tr("Import File - %1").arg(QDialog::windowTitle());
324 
325 	QStringList filters;
326 	filters.append(tr("Palette files (*.%1)").arg(DefaultSuffix));
327 	filters.append(tr("All files (*.*)"));
328 
329 	const QString& filename
330 		= QFileDialog::getOpenFileName(this,
331 			title, defaultDir(), filters.join(";;"));
332 
333 	if (filename.isEmpty())
334 		return;
335 
336 	int imported = 0;
337 	QSettings settings(filename, QSettings::IniFormat);
338 	settings.beginGroup(ColorThemesGroup);
339 	QStringListIterator name_iter(settings.childGroups());
340 	while (name_iter.hasNext()) {
341 		const QString& name = name_iter.next();
342 		if (!name.isEmpty()) {
343 			QPalette pal;
344 			int result = 0;
345 		#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
346 			uint mask = pal.resolveMask();
347 		#else
348 			uint mask = pal.resolve();
349 		#endif
350 			settings.beginGroup(name + '/');
351 			QStringListIterator iter(settings.childKeys());
352 			while (iter.hasNext()) {
353 				const QString& key = iter.next();
354 				const QPalette::ColorRole cr
355 					= qsynthPaletteForm::colorRole(key);
356 				const QStringList& clist
357 					= settings.value(key).toStringList();
358 				if (clist.count() == 3) {
359 					pal.setColor(QPalette::Active,   cr, QColor(clist.at(0)));
360 					pal.setColor(QPalette::Inactive, cr, QColor(clist.at(1)));
361 					pal.setColor(QPalette::Disabled, cr, QColor(clist.at(2)));
362 					mask &= ~(1 << int(cr));
363 					++result;
364 				}
365 			}
366 		#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
367 			pal.setResolveMask(mask);
368 		#else
369 			pal.resolve(mask);
370 		#endif
371 			settings.endGroup();
372 			if (result > 0) {
373 				saveNamedPalette(name, pal);
374 				setPaletteName(name);
375 				++imported;
376 			}
377 		}
378 	}
379 	settings.endGroup();
380 
381 	if (imported > 0) {
382 		updateNamedPaletteList();
383 		resetButtonClicked();
384 		setDefaultDir(QFileInfo(filename).absolutePath());
385 	} else {
386 		QMessageBox::warning(this,
387 			tr("Warning - %1").arg(QDialog::windowTitle()),
388 			tr("Could not import from file:\n\n"
389 			"%1\n\nSorry.").arg(filename));
390 	}
391 }
392 
393 
exportButtonClicked(void)394 void qsynthPaletteForm::exportButtonClicked (void)
395 {
396 	const QString& title
397 		= tr("Export File - %1").arg(QDialog::windowTitle());
398 
399 	QStringList filters;
400 	filters.append(tr("Palette files (*.%1)").arg(DefaultSuffix));
401 	filters.append(tr("All files (*.*)"));
402 
403 	QString dirname = defaultDir();
404 	if (!dirname.isEmpty())
405 		dirname.append(QDir::separator());
406 	dirname.append(paletteName() + '.' + DefaultSuffix);
407 
408 	const QString& filename
409 		= QFileDialog::getSaveFileName(this,
410 			title, dirname, filters.join(";;"));
411 
412 	if (filename.isEmpty())
413 		return;
414 
415 	const QPalette& pal = m_palette;
416 
417 	QSettings settings(filename, QSettings::IniFormat);
418 	settings.beginGroup(ColorThemesGroup);
419 	settings.beginGroup(QFileInfo(filename).baseName() + '/');
420 	for (int i = 0; g_colorRoles[i].key; ++i) {
421 		const QString& key
422 			= QString::fromLatin1(g_colorRoles[i].key);
423 		const QPalette::ColorRole cr
424 			= g_colorRoles[i].value;
425 		QStringList clist;
426 		clist.append(pal.color(QPalette::Active,   cr).name());
427 		clist.append(pal.color(QPalette::Inactive, cr).name());
428 		clist.append(pal.color(QPalette::Disabled, cr).name());
429 		settings.setValue(key, clist);
430 	}
431 	settings.endGroup();
432 	settings.endGroup();
433 
434 	setDefaultDir(QFileInfo(filename).absolutePath());
435 }
436 
437 
paletteChanged(const QPalette & pal)438 void qsynthPaletteForm::paletteChanged ( const QPalette& pal )
439 {
440 	m_modelUpdated = true;
441 	if (!m_paletteUpdated)
442 		setPalette(pal);
443 	m_modelUpdated = false;
444 
445 	++m_dirtyCount;
446 	updateDialogButtons();
447 }
448 
449 
setPaletteName(const QString & name)450 void qsynthPaletteForm::setPaletteName ( const QString& name )
451 {
452 	const bool blocked = m_ui.nameCombo->blockSignals(true);
453 
454 	m_ui.nameCombo->setEditText(name);
455 
456 	QPalette pal;
457 
458 	if (namedPalette(m_settings, name, pal, true))
459 		setPalette(pal, pal);
460 
461 	m_dirtyCount = 0;
462 	updateDialogButtons();
463 
464 	m_ui.nameCombo->blockSignals(blocked);
465 }
466 
467 
paletteName(void) const468 QString qsynthPaletteForm::paletteName (void) const
469 {
470 	return m_ui.nameCombo->currentText();
471 }
472 
473 
updateNamedPaletteList(void)474 void qsynthPaletteForm::updateNamedPaletteList (void)
475 {
476 	const bool blocked = m_ui.nameCombo->blockSignals(true);
477 	const QString old_name = m_ui.nameCombo->currentText();
478 
479 	m_ui.nameCombo->clear();
480 	m_ui.nameCombo->insertItems(0, namedPaletteList());
481 //	m_ui.nameCombo->model()->sort(0);
482 
483 	const int i = m_ui.nameCombo->findText(old_name);
484 	if (i >= 0)
485 		m_ui.nameCombo->setCurrentIndex(i);
486 	else
487 		m_ui.nameCombo->setEditText(old_name);
488 
489 	m_ui.nameCombo->blockSignals(blocked);
490 }
491 
492 
updateGenerateButton(void)493 void qsynthPaletteForm::updateGenerateButton (void)
494 {
495 	m_ui.generateButton->setBrush(
496 		m_palette.brush(QPalette::Active, QPalette::Button));
497 }
498 
499 
updateDialogButtons(void)500 void qsynthPaletteForm::updateDialogButtons (void)
501 {
502 	const QString& name = m_ui.nameCombo->currentText();
503 	const int i = m_ui.nameCombo->findText(name);
504 	m_ui.saveButton->setEnabled(!name.isEmpty() && (m_dirtyCount > 0 || i < 0));
505 	m_ui.deleteButton->setEnabled(i >= 0);
506 	m_ui.resetButton->setEnabled(m_dirtyCount > 0);
507 	m_ui.exportButton->setEnabled(!name.isEmpty() || i >= 0);
508 	m_ui.dialogButtons->button(QDialogButtonBox::Ok)->setEnabled(i >= 0);
509 	if (name == "Wonton Soup" || name == "KXStudio") {
510 		m_ui.saveButton->setEnabled(false);
511 		m_ui.deleteButton->setEnabled(false);
512 		m_ui.exportButton->setEnabled(false);
513 	}
514 }
515 
516 
namedPalette(const QString & name,QPalette & pal)517 bool qsynthPaletteForm::namedPalette ( const QString& name, QPalette& pal )
518 {
519 	return namedPalette(m_settings, name, pal);
520 }
521 
522 
namedPalette(QSettings * settings,const QString & name,QPalette & pal,bool fixup)523 bool qsynthPaletteForm::namedPalette (
524 	QSettings *settings, const QString& name, QPalette& pal, bool fixup )
525 {
526 	int result = 0;
527 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
528 	uint mask = pal.resolve();
529 #endif
530 
531 	// Custom color themes...
532 	if (name == "Wonton Soup") {
533 		pal.setColor(QPalette::Active,   QPalette::Window, QColor(73, 78, 88));
534 		pal.setColor(QPalette::Inactive, QPalette::Window, QColor(73, 78, 88));
535 		pal.setColor(QPalette::Disabled, QPalette::Window, QColor(64, 68, 77));
536 		pal.setColor(QPalette::Active,   QPalette::WindowText, QColor(182, 193, 208));
537 		pal.setColor(QPalette::Inactive, QPalette::WindowText, QColor(182, 193, 208));
538 		pal.setColor(QPalette::Disabled, QPalette::WindowText, QColor(97, 104, 114));
539 		pal.setColor(QPalette::Active,   QPalette::Base, QColor(60, 64, 72));
540 		pal.setColor(QPalette::Inactive, QPalette::Base, QColor(60, 64, 72));
541 		pal.setColor(QPalette::Disabled, QPalette::Base, QColor(52, 56, 63));
542 		pal.setColor(QPalette::Active,   QPalette::AlternateBase, QColor(67, 71, 80));
543 		pal.setColor(QPalette::Inactive, QPalette::AlternateBase, QColor(67, 71, 80));
544 		pal.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(59, 62, 70));
545 		pal.setColor(QPalette::Active,   QPalette::ToolTipBase, QColor(182, 193, 208));
546 		pal.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(182, 193, 208));
547 		pal.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(182, 193, 208));
548 		pal.setColor(QPalette::Active,   QPalette::ToolTipText, QColor(42, 44, 48));
549 		pal.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(42, 44, 48));
550 		pal.setColor(QPalette::Disabled, QPalette::ToolTipText, QColor(42, 44, 48));
551 		pal.setColor(QPalette::Active,   QPalette::Text, QColor(210, 222, 240));
552 		pal.setColor(QPalette::Inactive, QPalette::Text, QColor(210, 222, 240));
553 		pal.setColor(QPalette::Disabled, QPalette::Text, QColor(99, 105, 115));
554 		pal.setColor(QPalette::Active,   QPalette::Button, QColor(82, 88, 99));
555 		pal.setColor(QPalette::Inactive, QPalette::Button, QColor(82, 88, 99));
556 		pal.setColor(QPalette::Disabled, QPalette::Button, QColor(72, 77, 87));
557 		pal.setColor(QPalette::Active,   QPalette::ButtonText, QColor(210, 222, 240));
558 		pal.setColor(QPalette::Inactive, QPalette::ButtonText, QColor(210, 222, 240));
559 		pal.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(111, 118, 130));
560 		pal.setColor(QPalette::Active,   QPalette::BrightText, QColor(255, 255, 255));
561 		pal.setColor(QPalette::Inactive, QPalette::BrightText, QColor(255, 255, 255));
562 		pal.setColor(QPalette::Disabled, QPalette::BrightText, QColor(255, 255, 255));
563 		pal.setColor(QPalette::Active,   QPalette::Light, QColor(95, 101, 114));
564 		pal.setColor(QPalette::Inactive, QPalette::Light, QColor(95, 101, 114));
565 		pal.setColor(QPalette::Disabled, QPalette::Light, QColor(86, 92, 104));
566 		pal.setColor(QPalette::Active,   QPalette::Midlight, QColor(84, 90, 101));
567 		pal.setColor(QPalette::Inactive, QPalette::Midlight, QColor(84, 90, 101));
568 		pal.setColor(QPalette::Disabled, QPalette::Midlight, QColor(75, 81, 91));
569 		pal.setColor(QPalette::Active,   QPalette::Dark, QColor(40, 43, 49));
570 		pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(40, 43, 49));
571 		pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(35, 38, 43));
572 		pal.setColor(QPalette::Active,   QPalette::Mid, QColor(63, 68, 76));
573 		pal.setColor(QPalette::Inactive, QPalette::Mid, QColor(63, 68, 76));
574 		pal.setColor(QPalette::Disabled, QPalette::Mid, QColor(56, 59, 67));
575 		pal.setColor(QPalette::Active,   QPalette::Shadow, QColor(29, 31, 35));
576 		pal.setColor(QPalette::Inactive, QPalette::Shadow, QColor(29, 31, 35));
577 		pal.setColor(QPalette::Disabled, QPalette::Shadow, QColor(25, 27, 30));
578 		pal.setColor(QPalette::Active,   QPalette::Highlight, QColor(120, 136, 156));
579 		pal.setColor(QPalette::Inactive, QPalette::Highlight, QColor(81, 90, 103));
580 		pal.setColor(QPalette::Disabled, QPalette::Highlight, QColor(64, 68, 77));
581 		pal.setColor(QPalette::Active,   QPalette::HighlightedText, QColor(209, 225, 244));
582 		pal.setColor(QPalette::Inactive, QPalette::HighlightedText, QColor(182, 193, 208));
583 		pal.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(97, 104, 114));
584 		pal.setColor(QPalette::Active,   QPalette::Link, QColor(156, 212, 255));
585 		pal.setColor(QPalette::Inactive, QPalette::Link, QColor(156, 212, 255));
586 		pal.setColor(QPalette::Disabled, QPalette::Link, QColor(82, 102, 119));
587 		pal.setColor(QPalette::Active,   QPalette::LinkVisited, QColor(64, 128, 255));
588 		pal.setColor(QPalette::Inactive, QPalette::LinkVisited, QColor(64, 128, 255));
589 		pal.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(54, 76, 119));
590 	#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
591 		mask = 0;
592 	#endif
593 		++result;
594 	}
595 	else
596 	if (name == "KXStudio") {
597 		pal.setColor(QPalette::Active,   QPalette::Window, QColor(17, 17, 17));
598 		pal.setColor(QPalette::Inactive, QPalette::Window, QColor(17, 17, 17));
599 		pal.setColor(QPalette::Disabled, QPalette::Window, QColor(14, 14, 14));
600 		pal.setColor(QPalette::Active,   QPalette::WindowText, QColor(240, 240, 240));
601 		pal.setColor(QPalette::Inactive, QPalette::WindowText, QColor(240, 240, 240));
602 		pal.setColor(QPalette::Disabled, QPalette::WindowText, QColor(83, 83, 83));
603 		pal.setColor(QPalette::Active,   QPalette::Base, QColor(7, 7, 7));
604 		pal.setColor(QPalette::Inactive, QPalette::Base, QColor(7, 7, 7));
605 		pal.setColor(QPalette::Disabled, QPalette::Base, QColor(6, 6, 6));
606 		pal.setColor(QPalette::Active,   QPalette::AlternateBase, QColor(14, 14, 14));
607 		pal.setColor(QPalette::Inactive, QPalette::AlternateBase, QColor(14, 14, 14));
608 		pal.setColor(QPalette::Disabled, QPalette::AlternateBase, QColor(12, 12, 12));
609 		pal.setColor(QPalette::Active,   QPalette::ToolTipBase, QColor(4, 4, 4));
610 		pal.setColor(QPalette::Inactive, QPalette::ToolTipBase, QColor(4, 4, 4));
611 		pal.setColor(QPalette::Disabled, QPalette::ToolTipBase, QColor(4, 4, 4));
612 		pal.setColor(QPalette::Active,   QPalette::ToolTipText, QColor(230, 230, 230));
613 		pal.setColor(QPalette::Inactive, QPalette::ToolTipText, QColor(230, 230, 230));
614 		pal.setColor(QPalette::Disabled, QPalette::ToolTipText, QColor(230, 230, 230));
615 		pal.setColor(QPalette::Active,   QPalette::Text, QColor(230, 230, 230));
616 		pal.setColor(QPalette::Inactive, QPalette::Text, QColor(230, 230, 230));
617 		pal.setColor(QPalette::Disabled, QPalette::Text, QColor(74, 74, 74));
618 		pal.setColor(QPalette::Active,   QPalette::Button, QColor(28, 28, 28));
619 		pal.setColor(QPalette::Inactive, QPalette::Button, QColor(28, 28, 28));
620 		pal.setColor(QPalette::Disabled, QPalette::Button, QColor(24, 24, 24));
621 		pal.setColor(QPalette::Active,   QPalette::ButtonText, QColor(240, 240, 240));
622 		pal.setColor(QPalette::Inactive, QPalette::ButtonText, QColor(240, 240, 240));
623 		pal.setColor(QPalette::Disabled, QPalette::ButtonText, QColor(90, 90, 90));
624 		pal.setColor(QPalette::Active,   QPalette::BrightText, QColor(255, 255, 255));
625 		pal.setColor(QPalette::Inactive, QPalette::BrightText, QColor(255, 255, 255));
626 		pal.setColor(QPalette::Disabled, QPalette::BrightText, QColor(255, 255, 255));
627 		pal.setColor(QPalette::Active,   QPalette::Light, QColor(191, 191, 191));
628 		pal.setColor(QPalette::Inactive, QPalette::Light, QColor(191, 191, 191));
629 		pal.setColor(QPalette::Disabled, QPalette::Light, QColor(191, 191, 191));
630 		pal.setColor(QPalette::Active,   QPalette::Midlight, QColor(155, 155, 155));
631 		pal.setColor(QPalette::Inactive, QPalette::Midlight, QColor(155, 155, 155));
632 		pal.setColor(QPalette::Disabled, QPalette::Midlight, QColor(155, 155, 155));
633 		pal.setColor(QPalette::Active,   QPalette::Dark, QColor(129, 129, 129));
634 		pal.setColor(QPalette::Inactive, QPalette::Dark, QColor(129, 129, 129));
635 		pal.setColor(QPalette::Disabled, QPalette::Dark, QColor(129, 129, 129));
636 		pal.setColor(QPalette::Active,   QPalette::Mid, QColor(94, 94, 94));
637 		pal.setColor(QPalette::Inactive, QPalette::Mid, QColor(94, 94, 94));
638 		pal.setColor(QPalette::Disabled, QPalette::Mid, QColor(94, 94, 94));
639 		pal.setColor(QPalette::Active,   QPalette::Shadow, QColor(155, 155, 155));
640 		pal.setColor(QPalette::Inactive, QPalette::Shadow, QColor(155, 155, 155));
641 		pal.setColor(QPalette::Disabled, QPalette::Shadow, QColor(155, 155, 155));
642 		pal.setColor(QPalette::Active,   QPalette::Highlight, QColor(60, 60, 60));
643 		pal.setColor(QPalette::Inactive, QPalette::Highlight, QColor(34, 34, 34));
644 		pal.setColor(QPalette::Disabled, QPalette::Highlight, QColor(14, 14, 14));
645 		pal.setColor(QPalette::Active,   QPalette::HighlightedText, QColor(255, 255, 255));
646 		pal.setColor(QPalette::Inactive, QPalette::HighlightedText, QColor(240, 240, 240));
647 		pal.setColor(QPalette::Disabled, QPalette::HighlightedText, QColor(83, 83, 83));
648 		pal.setColor(QPalette::Active,   QPalette::Link, QColor(100, 100, 230));
649 		pal.setColor(QPalette::Inactive, QPalette::Link, QColor(100, 100, 230));
650 		pal.setColor(QPalette::Disabled, QPalette::Link, QColor(34, 34, 74));
651 		pal.setColor(QPalette::Active,   QPalette::LinkVisited, QColor(230, 100, 230));
652 		pal.setColor(QPalette::Inactive, QPalette::LinkVisited, QColor(230, 100, 230));
653 		pal.setColor(QPalette::Disabled, QPalette::LinkVisited, QColor(74, 34, 74));
654 	#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
655 		mask = 0;
656 	#endif
657 		++result;
658 	}
659 	else
660 	if (settings) {
661 		settings->beginGroup(ColorThemesGroup);
662 		settings->beginGroup(name + '/');
663 		QStringListIterator iter(settings->childKeys());
664 		while (iter.hasNext()) {
665 			const QString& key = iter.next();
666 			const QPalette::ColorRole cr
667 				= qsynthPaletteForm::colorRole(key);
668 			const QStringList& clist
669 				= settings->value(key).toStringList();
670 			if (clist.count() == 3) {
671 				pal.setColor(QPalette::Active,   cr, QColor(clist.at(0)));
672 				pal.setColor(QPalette::Inactive, cr, QColor(clist.at(1)));
673 				pal.setColor(QPalette::Disabled, cr, QColor(clist.at(2)));
674 			#if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
675 				mask &= ~(1 << int(cr));
676 			#endif
677 				++result;
678 			}
679 		}
680 		settings->endGroup();
681 		settings->endGroup();
682 	}
683 
684 	// Dark themes grayed/disabled color group fix...
685 	if (!fixup && pal.base().color().value() < 0x7f) {
686 		const QColor& color = pal.window().color();
687 		const int groups = int(QPalette::Active | QPalette::Inactive) + 1;
688 		for (int i = 0; i < groups; ++i) {
689 			const QPalette::ColorGroup cg = QPalette::ColorGroup(i);
690 			pal.setBrush(cg, QPalette::Light,    color.lighter(140));
691 			pal.setBrush(cg, QPalette::Midlight, color.lighter(100));
692 			pal.setBrush(cg, QPalette::Mid,      color.lighter(90));
693 			pal.setBrush(cg, QPalette::Dark,     color.darker(160));
694 			pal.setBrush(cg, QPalette::Shadow,   color.darker(180));
695 		}
696 		pal.setColorGroup(QPalette::Disabled,
697 			pal.windowText().color().darker(),
698 			pal.button(),
699 			pal.light(),
700 			pal.dark(),
701 			pal.mid(),
702 			pal.text().color().darker(),
703 			pal.text().color().lighter(),
704 			pal.base(),
705 			pal.window());
706 	#if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0)
707 		pal.setColor(QPalette::Disabled,
708 			QPalette::Highlight, pal.mid().color());
709 		pal.setColor(QPalette::Disabled,
710 			QPalette::ButtonText, pal.mid().color());
711 	#endif
712 		++result;
713 	}
714 
715 #if QT_VERSION < QT_VERSION_CHECK(5, 15, 0)
716 	pal.resolve(mask);
717 #endif
718 	return (result > 0);
719 }
720 
721 
saveNamedPalette(const QString & name,const QPalette & pal)722 void qsynthPaletteForm::saveNamedPalette (
723 	const QString& name, const QPalette& pal )
724 {
725 	if (m_settings && name != "KXStudio" && name != "Wonton Soup") {
726 		m_settings->beginGroup(ColorThemesGroup);
727 		m_settings->beginGroup(name + '/');
728 		for (int i = 0; g_colorRoles[i].key; ++i) {
729 			const QString& key
730 				= QString::fromLatin1(g_colorRoles[i].key);
731 			const QPalette::ColorRole cr
732 				= g_colorRoles[i].value;
733 			QStringList clist;
734 			clist.append(pal.color(QPalette::Active,   cr).name());
735 			clist.append(pal.color(QPalette::Inactive, cr).name());
736 			clist.append(pal.color(QPalette::Disabled, cr).name());
737 			m_settings->setValue(key, clist);
738 		}
739 		m_settings->endGroup();
740 		m_settings->endGroup();
741 		++m_dirtyTotal;
742 	}
743 }
744 
745 
deleteNamedPalette(const QString & name)746 void qsynthPaletteForm::deleteNamedPalette ( const QString& name )
747 {
748 	if (m_settings) {
749 		m_settings->beginGroup(ColorThemesGroup);
750 		m_settings->remove(name);
751 		m_settings->endGroup();
752 		++m_dirtyTotal;
753 	}
754 }
755 
756 
namedPaletteList(void)757 QStringList qsynthPaletteForm::namedPaletteList (void)
758 {
759 	return namedPaletteList(m_settings);
760 }
761 
762 
namedPaletteList(QSettings * settings)763 QStringList qsynthPaletteForm::namedPaletteList ( QSettings *settings )
764 {
765 	QStringList list;
766 	list.append("Wonton Soup");
767 	list.append("KXStudio");
768 
769 	if (settings) {
770 		settings->beginGroup(ColorThemesGroup);
771 		list.append(settings->childGroups());
772 		settings->endGroup();
773 	}
774 
775 	return list;
776 }
777 
778 
colorRole(const QString & name)779 QPalette::ColorRole qsynthPaletteForm::colorRole ( const QString& name )
780 {
781 	static QHash<QString, QPalette::ColorRole> s_colorRoles;
782 
783 	if (s_colorRoles.isEmpty()) {
784 		for (int i = 0; g_colorRoles[i].key; ++i) {
785 			const QString& key
786 				= QString::fromLatin1(g_colorRoles[i].key);
787 			const QPalette::ColorRole value
788 				= g_colorRoles[i].value;
789 			s_colorRoles.insert(key, value);
790 		}
791 	}
792 
793 	return s_colorRoles.value(name, QPalette::NoRole);
794 }
795 
796 
isDirty(void) const797 bool qsynthPaletteForm::isDirty (void) const
798 {
799 	return (m_dirtyTotal > 0);
800 }
801 
802 
accept(void)803 void qsynthPaletteForm::accept (void)
804 {
805 	setShowDetails(m_ui.detailsCheck->isChecked());
806 
807 	if (m_dirtyCount > 0)
808 		saveButtonClicked();
809 
810 	QDialog::accept();
811 }
812 
813 
reject(void)814 void qsynthPaletteForm::reject (void)
815 {
816 	if (m_dirtyCount > 0) {
817 		const QString& name = paletteName();
818 		if (name.isEmpty()) {
819 			if (QMessageBox::warning(this,
820 				tr("Warning - %1").arg(QDialog::windowTitle()),
821 				tr("Some settings have been changed.\n\n"
822 				"Do you want to discard the changes?"),
823 				QMessageBox::Discard |
824 				QMessageBox::Cancel) == QMessageBox::Cancel)
825 				return;
826 		} else {
827 			switch (QMessageBox::warning(this,
828 				tr("Warning - %1").arg(QDialog::windowTitle()),
829 				tr("Some settings have been changed:\n\n"
830 				"\"%1\".\n\nDo you want to save the changes?")
831 				.arg(name),
832 				QMessageBox::Save |
833 				QMessageBox::Discard |
834 				QMessageBox::Cancel)) {
835 			case QMessageBox::Save:
836 				saveButtonClicked();
837 				// Fall thru...
838 			case QMessageBox::Discard:
839 				break;
840 			default: // Cancel...
841 				return;
842 			}
843 		}
844 	}
845 
846 	QDialog::reject();
847 }
848 
849 
setDefaultDir(const QString & dir)850 void qsynthPaletteForm::setDefaultDir ( const QString& dir )
851 {
852 	if (m_settings) {
853 		m_settings->beginGroup(PaletteEditorGroup);
854 		m_settings->setValue(DefaultDirKey, dir);
855 		m_settings->endGroup();
856 	}
857 }
858 
859 
defaultDir(void) const860 QString qsynthPaletteForm::defaultDir (void) const
861 {
862 	QString dir;
863 
864 	if (m_settings) {
865 		m_settings->beginGroup(PaletteEditorGroup);
866 		dir = m_settings->value(DefaultDirKey).toString();
867 		m_settings->endGroup();
868 	}
869 
870 	return dir;
871 }
872 
873 
setShowDetails(bool on)874 void qsynthPaletteForm::setShowDetails ( bool on )
875 {
876 	if (m_settings) {
877 		m_settings->beginGroup(PaletteEditorGroup);
878 		m_settings->setValue(ShowDetailsKey, on);
879 		m_settings->endGroup();
880 	}
881 }
882 
883 
isShowDetails(void) const884 bool qsynthPaletteForm::isShowDetails (void) const
885 {
886 	bool on = false;
887 
888 	if (m_settings) {
889 		m_settings->beginGroup(PaletteEditorGroup);
890 		on = m_settings->value(ShowDetailsKey).toBool();
891 		m_settings->endGroup();
892 	}
893 
894 	return on;
895 }
896 
897 
showEvent(QShowEvent * event)898 void qsynthPaletteForm::showEvent ( QShowEvent *event )
899 {
900 	QDialog::showEvent(event);
901 
902 	detailsCheckClicked();
903 }
904 
905 
resizeEvent(QResizeEvent * event)906 void qsynthPaletteForm::resizeEvent ( QResizeEvent *event )
907 {
908 	QDialog::resizeEvent(event);
909 
910 	detailsCheckClicked();
911 }
912 
913 
914 //-------------------------------------------------------------------------
915 // qsynthPaletteForm::PaletteModel
916 
PaletteModel(QObject * parent)917 qsynthPaletteForm::PaletteModel::PaletteModel ( QObject *parent )
918 	: QAbstractTableModel(parent)
919 {
920 	for (m_nrows = 0; g_colorRoles[m_nrows].key; ++m_nrows) {
921 		const QPalette::ColorRole value
922 			= g_colorRoles[m_nrows].value;
923 		const QString& key
924 			= QString::fromLatin1(g_colorRoles[m_nrows].key);
925 		m_roleNames.insert(value, key);
926 	}
927 
928 	m_generate = true;
929 }
930 
931 
rowCount(const QModelIndex &) const932 int qsynthPaletteForm::PaletteModel::rowCount ( const QModelIndex& ) const
933 {
934 	return m_nrows;
935 }
936 
937 
columnCount(const QModelIndex &) const938 int qsynthPaletteForm::PaletteModel::columnCount ( const QModelIndex& ) const
939 {
940 	return 4;
941 }
942 
943 
data(const QModelIndex & index,int role) const944 QVariant qsynthPaletteForm::PaletteModel::data ( const QModelIndex& index, int role ) const
945 {
946 	if (!index.isValid())
947 		return QVariant();
948 	if (index.row() < 0 || index.row() >= m_nrows)
949 		return QVariant();
950 	if (index.column() < 0 || index.column() >= 4)
951 		return QVariant();
952 
953 	if (index.column() == 0) {
954 		if (role == Qt::DisplayRole)
955 			return m_roleNames.value(QPalette::ColorRole(index.row()));
956 		if (role == Qt::EditRole) {
957 		#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
958 			const uint mask = m_palette.resolveMask();
959 		#else
960 			const uint mask = m_palette.resolve();
961 		#endif
962 			return bool(mask & (1 << index.row()));
963 		}
964 	}
965 	else
966 	if (role == Qt::BackgroundRole) {
967 		return m_palette.color(
968 			columnToGroup(index.column()),
969 			QPalette::ColorRole(index.row()));
970 	}
971 
972 	return QVariant();
973 }
974 
975 
setData(const QModelIndex & index,const QVariant & value,int role)976 bool qsynthPaletteForm::PaletteModel::setData (
977 	const QModelIndex& index, const QVariant& value, int role )
978 {
979 	if (!index.isValid())
980 		return false;
981 
982 	if (index.column() != 0 && role == Qt::BackgroundRole) {
983 		const QColor& color = value.value<QColor>();
984 		const QPalette::ColorRole cr = QPalette::ColorRole(index.row());
985 		const QPalette::ColorGroup cg = columnToGroup(index.column());
986 		m_palette.setBrush(cg, cr, color);
987 		QModelIndex index_begin = PaletteModel::index(cr, 0);
988 		QModelIndex index_end = PaletteModel::index(cr, 3);
989 		if (m_generate) {
990 			m_palette.setBrush(QPalette::Inactive, cr, color);
991 			switch (cr) {
992 				case QPalette::WindowText:
993 				case QPalette::Text:
994 				case QPalette::ButtonText:
995 				case QPalette::Base:
996 					break;
997 				case QPalette::Dark:
998 					m_palette.setBrush(QPalette::Disabled, QPalette::WindowText, color);
999 					m_palette.setBrush(QPalette::Disabled, QPalette::Dark, color);
1000 					m_palette.setBrush(QPalette::Disabled, QPalette::Text, color);
1001 					m_palette.setBrush(QPalette::Disabled, QPalette::ButtonText, color);
1002 					index_begin = PaletteModel::index(0, 0);
1003 					index_end = PaletteModel::index(m_nrows - 1, 3);
1004 					break;
1005 				case QPalette::Window:
1006 					m_palette.setBrush(QPalette::Disabled, QPalette::Base, color);
1007 					m_palette.setBrush(QPalette::Disabled, QPalette::Window, color);
1008 					index_begin = PaletteModel::index(QPalette::Base, 0);
1009 					break;
1010 				case QPalette::Highlight:
1011 					m_palette.setBrush(QPalette::Disabled, QPalette::Highlight, color.darker(120));
1012 					break;
1013 				default:
1014 					m_palette.setBrush(QPalette::Disabled, cr, color);
1015 					break;
1016 			}
1017 		}
1018 		emit paletteChanged(m_palette);
1019 		emit dataChanged(index_begin, index_end);
1020 		return true;
1021 	}
1022 
1023 	if (index.column() == 0 && role == Qt::EditRole) {
1024 	#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1025 		uint mask = m_palette.resolveMask();
1026 	#else
1027 		uint mask = m_palette.resolve();
1028 	#endif
1029 		const bool masked = value.value<bool>();
1030 		const int i = index.row();
1031 		if (masked) {
1032 			mask |= (1 << i);
1033 		} else {
1034 			const QPalette::ColorRole cr = QPalette::ColorRole(i);
1035 			m_palette.setBrush(QPalette::Active, cr,
1036 				m_parentPalette.brush(QPalette::Active, cr));
1037 			m_palette.setBrush(QPalette::Inactive, cr,
1038 				m_parentPalette.brush(QPalette::Inactive, cr));
1039 			m_palette.setBrush(QPalette::Disabled, cr,
1040 				m_parentPalette.brush(QPalette::Disabled, cr));
1041 			mask &= ~(1 << i);
1042 		}
1043 	#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
1044 		m_palette.setResolveMask(mask);
1045 	#else
1046 		m_palette.resolve(mask);
1047 	#endif
1048 		emit paletteChanged(m_palette);
1049 		const QModelIndex& index_end = PaletteModel::index(i, 3);
1050 		emit dataChanged(index, index_end);
1051 		return true;
1052 	}
1053 
1054 	return false;
1055 }
1056 
1057 
flags(const QModelIndex & index) const1058 Qt::ItemFlags qsynthPaletteForm::PaletteModel::flags ( const QModelIndex& index ) const
1059 {
1060 	if (!index.isValid())
1061 		return Qt::ItemIsEnabled;
1062 	else
1063 		return Qt::ItemIsEditable | Qt::ItemIsEnabled;
1064 }
1065 
1066 
headerData(int section,Qt::Orientation orientation,int role) const1067 QVariant qsynthPaletteForm::PaletteModel::headerData (
1068 	int section, Qt::Orientation orientation, int role ) const
1069 {
1070 	if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
1071 		if (section == 0)
1072 			return tr("Color Role");
1073 		else
1074 		if (section == groupToColumn(QPalette::Active))
1075 			return tr("Active");
1076 		else
1077 		if (section == groupToColumn(QPalette::Inactive))
1078 			return tr("Inactive");
1079 		else
1080 		if (section == groupToColumn(QPalette::Disabled))
1081 			return tr("Disabled");
1082 	}
1083 
1084 	return QVariant();
1085 }
1086 
1087 
palette(void) const1088 const QPalette& qsynthPaletteForm::PaletteModel::palette(void) const
1089 {
1090 	return m_palette;
1091 }
1092 
1093 
setPalette(const QPalette & palette,const QPalette & parentPalette)1094 void qsynthPaletteForm::PaletteModel::setPalette (
1095 	const QPalette& palette, const QPalette& parentPalette )
1096 {
1097 	m_palette = palette;
1098 	m_parentPalette = parentPalette;
1099 
1100 	const QModelIndex& index_begin = index(0, 0);
1101 	const QModelIndex& index_end = index(m_nrows - 1, 3);
1102 	emit dataChanged(index_begin, index_end);
1103 }
1104 
1105 
columnToGroup(int index) const1106 QPalette::ColorGroup qsynthPaletteForm::PaletteModel::columnToGroup ( int index ) const
1107 {
1108 	if (index == 1)
1109 		return QPalette::Active;
1110 	else
1111 	if (index == 2)
1112 		return QPalette::Inactive;
1113 
1114 	return QPalette::Disabled;
1115 }
1116 
1117 
groupToColumn(QPalette::ColorGroup group) const1118 int qsynthPaletteForm::PaletteModel::groupToColumn ( QPalette::ColorGroup group ) const
1119 {
1120 	if (group == QPalette::Active)
1121 		return 1;
1122 	else
1123 	if (group == QPalette::Inactive)
1124 		return 2;
1125 
1126 	return 3;
1127 }
1128 
1129 
1130 //-------------------------------------------------------------------------
1131 // qsynthPaletteForm::ColorDelegate
1132 
createEditor(QWidget * parent,const QStyleOptionViewItem &,const QModelIndex & index) const1133 QWidget *qsynthPaletteForm::ColorDelegate::createEditor ( QWidget *parent,
1134 	const QStyleOptionViewItem&, const QModelIndex& index ) const
1135 {
1136 	QWidget *editor = nullptr;
1137 
1138 	if (index.column() == 0) {
1139 		RoleEditor *ed = new RoleEditor(parent);
1140 		QObject::connect(ed,
1141 			SIGNAL(changed(QWidget *)),
1142 			SIGNAL(commitData(QWidget *)));
1143 	//	ed->setFocusPolicy(Qt::NoFocus);
1144 	//	ed->installEventFilter(const_cast<ColorDelegate *>(this));
1145 		editor = ed;
1146 	} else {
1147 		ColorEditor *ed = new ColorEditor(parent);
1148 		QObject::connect(ed,
1149 			SIGNAL(changed(QWidget *)),
1150 			SIGNAL(commitData(QWidget *)));
1151 		ed->setFocusPolicy(Qt::NoFocus);
1152 		ed->installEventFilter(const_cast<ColorDelegate *>(this));
1153 		editor = ed;
1154 	}
1155 
1156 	return editor;
1157 }
1158 
1159 
setEditorData(QWidget * editor,const QModelIndex & index) const1160 void qsynthPaletteForm::ColorDelegate::setEditorData (
1161 	QWidget *editor, const QModelIndex& index ) const
1162 {
1163 	if (index.column() == 0) {
1164 		const bool masked
1165 			= index.model()->data(index, Qt::EditRole).value<bool>();
1166 		RoleEditor *ed = static_cast<RoleEditor *>(editor);
1167 		ed->setEdited(masked);
1168 		const QString& colorName
1169 			= index.model()->data(index, Qt::DisplayRole).value<QString>();
1170 		ed->setLabel(colorName);
1171 	} else {
1172 		const QColor& color
1173 			= index.model()->data(index, Qt::BackgroundRole).value<QColor>();
1174 		ColorEditor *ed = static_cast<ColorEditor *>(editor);
1175 		ed->setColor(color);
1176 	}
1177 }
1178 
1179 
setModelData(QWidget * editor,QAbstractItemModel * model,const QModelIndex & index) const1180 void qsynthPaletteForm::ColorDelegate::setModelData ( QWidget *editor,
1181 	QAbstractItemModel *model, const QModelIndex& index ) const
1182 {
1183 	if (index.column() == 0) {
1184 		RoleEditor *ed = static_cast<RoleEditor *>(editor);
1185 		const bool masked = ed->edited();
1186 		model->setData(index, masked, Qt::EditRole);
1187 	} else {
1188 		ColorEditor *ed = static_cast<ColorEditor *>(editor);
1189 		if (ed->changed()) {
1190 			const QColor& color = ed->color();
1191 			model->setData(index, color, Qt::BackgroundRole);
1192 		}
1193 	}
1194 }
1195 
1196 
updateEditorGeometry(QWidget * editor,const QStyleOptionViewItem & option,const QModelIndex & index) const1197 void qsynthPaletteForm::ColorDelegate::updateEditorGeometry ( QWidget *editor,
1198 	const QStyleOptionViewItem& option, const QModelIndex& index ) const
1199 {
1200 	QItemDelegate::updateEditorGeometry(editor, option, index);
1201 	editor->setGeometry(editor->geometry().adjusted(0, 0, -1, -1));
1202 }
1203 
1204 
paint(QPainter * painter,const QStyleOptionViewItem & option,const QModelIndex & index) const1205 void qsynthPaletteForm::ColorDelegate::paint ( QPainter *painter,
1206 	const QStyleOptionViewItem& option, const QModelIndex& index ) const
1207 {
1208 	QStyleOptionViewItem opt = option;
1209 
1210 	const bool masked
1211 		= index.model()->data(index, Qt::EditRole).value<bool>();
1212 	if (index.column() == 0 && masked)
1213 		opt.font.setBold(true);
1214 
1215 	QItemDelegate::paint(painter, opt, index);
1216 
1217 //	painter->setPen(opt.palette.midlight().color());
1218 	painter->setPen(Qt::darkGray);
1219 	painter->drawLine(opt.rect.right(), opt.rect.y(),
1220 		opt.rect.right(), opt.rect.bottom());
1221 	painter->drawLine(opt.rect.x(), opt.rect.bottom(),
1222 		opt.rect.right(), opt.rect.bottom());
1223 }
1224 
1225 
sizeHint(const QStyleOptionViewItem & option,const QModelIndex & index) const1226 QSize qsynthPaletteForm::ColorDelegate::sizeHint (
1227 	const QStyleOptionViewItem& option, const QModelIndex &index) const
1228 {
1229 	return QItemDelegate::sizeHint(option, index) + QSize(4, 4);
1230 }
1231 
1232 
1233 //-------------------------------------------------------------------------
1234 // qsynthPaletteForm::ColorButton
1235 
ColorButton(QWidget * parent)1236 qsynthPaletteForm::ColorButton::ColorButton ( QWidget *parent )
1237 	: QPushButton(parent), m_brush(Qt::darkGray)
1238 {
1239 	QPushButton::setMinimumWidth(48);
1240 
1241 	QObject::connect(this,
1242 		SIGNAL(clicked()),
1243 		SLOT(chooseColor()));
1244 }
1245 
1246 
brush(void) const1247 const QBrush& qsynthPaletteForm::ColorButton::brush (void) const
1248 {
1249 	return m_brush;
1250 }
1251 
1252 
setBrush(const QBrush & brush)1253 void qsynthPaletteForm::ColorButton::setBrush ( const QBrush& brush )
1254 {
1255 	m_brush = brush;
1256 	update();
1257 }
1258 
1259 
paintEvent(QPaintEvent * event)1260 void qsynthPaletteForm::ColorButton::paintEvent ( QPaintEvent *event )
1261 {
1262 	QPushButton::paintEvent(event);
1263 
1264 	QStyleOptionButton opt;
1265 	opt.initFrom(this);
1266 
1267 	const QRect& rect
1268 		= style()->subElementRect(QStyle::SE_PushButtonContents, &opt, this);
1269 
1270 	QPainter paint(this);
1271 	paint.setBrush(QBrush(m_brush.color()));
1272 	paint.drawRect(rect.adjusted(+1, +1, -2, -2));
1273 }
1274 
1275 
chooseColor(void)1276 void qsynthPaletteForm::ColorButton::chooseColor (void)
1277 {
1278 	const QColor color
1279 		= QColorDialog::getColor(m_brush.color(), this);
1280 	if (color.isValid()) {
1281 		m_brush.setColor(color);
1282 		emit changed();
1283 	}
1284 }
1285 
1286 
1287 //-------------------------------------------------------------------------
1288 // qsynthPaletteForm::ColorEditor
1289 
ColorEditor(QWidget * parent)1290 qsynthPaletteForm::ColorEditor::ColorEditor ( QWidget *parent )
1291 	: QWidget(parent)
1292 {
1293 	QLayout *layout = new QHBoxLayout(this);
1294 	layout->setContentsMargins(0, 0, 0, 0);
1295 	m_button = new qsynthPaletteForm::ColorButton(this);
1296 	layout->addWidget(m_button);
1297 	QObject::connect(m_button,
1298 		SIGNAL(changed()),
1299 		SLOT(colorChanged()));
1300 	setFocusProxy(m_button);
1301 	m_changed = false;
1302 }
1303 
1304 
setColor(const QColor & color)1305 void qsynthPaletteForm::ColorEditor::setColor ( const QColor& color )
1306 {
1307 	m_button->setBrush(color);
1308 	m_changed = false;
1309 }
1310 
1311 
color(void) const1312 QColor qsynthPaletteForm::ColorEditor::color (void) const
1313 {
1314 	return m_button->brush().color();
1315 }
1316 
1317 
colorChanged(void)1318 void qsynthPaletteForm::ColorEditor::colorChanged (void)
1319 {
1320 	m_changed = true;
1321 	emit changed(this);
1322 }
1323 
1324 
changed(void) const1325 bool qsynthPaletteForm::ColorEditor::changed (void) const
1326 {
1327 	return m_changed;
1328 }
1329 
1330 
1331 //-------------------------------------------------------------------------
1332 // qsynthPaletteForm::RoleEditor
1333 
RoleEditor(QWidget * parent)1334 qsynthPaletteForm::RoleEditor::RoleEditor ( QWidget *parent )
1335 	: QWidget(parent)
1336 {
1337 	m_edited = false;
1338 
1339 	QHBoxLayout *layout = new QHBoxLayout(this);
1340 	layout->setContentsMargins(0, 0, 0, 0);
1341 	layout->setSpacing(0);
1342 
1343 	m_label = new QLabel(this);
1344 	layout->addWidget(m_label);
1345 	m_label->setAutoFillBackground(true);
1346 	m_label->setIndent(3); // HACK: it should have the same value of textMargin in QItemDelegate
1347 	setFocusProxy(m_label);
1348 
1349 	m_button = new QToolButton(this);
1350 	m_button->setToolButtonStyle(Qt::ToolButtonIconOnly);
1351 	m_button->setIcon(QPixmap(":/images/itemReset.png"));
1352 	m_button->setIconSize(QSize(8, 8));
1353 	m_button->setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::MinimumExpanding));
1354 	layout->addWidget(m_button);
1355 
1356 	QObject::connect(m_button,
1357 		SIGNAL(clicked()),
1358 		SLOT(resetProperty()));
1359 }
1360 
1361 
setLabel(const QString & label)1362 void qsynthPaletteForm::RoleEditor::setLabel ( const QString& label )
1363 {
1364 	m_label->setText(label);
1365 }
1366 
1367 
setEdited(bool on)1368 void qsynthPaletteForm::RoleEditor::setEdited ( bool on )
1369 {
1370 	QFont font;
1371 	if (on)
1372 		font.setBold(on);
1373 	m_label->setFont(font);
1374 	m_button->setEnabled(on);
1375 	m_edited = on;
1376 }
1377 
1378 
edited(void) const1379 bool qsynthPaletteForm::RoleEditor::edited (void) const
1380 {
1381 	return m_edited;
1382 }
1383 
1384 
resetProperty(void)1385 void qsynthPaletteForm::RoleEditor::resetProperty (void)
1386 {
1387 	setEdited(false);
1388 	emit changed(this);
1389 }
1390 
1391 
1392 // end of qsynthPaletteForm.cpp
1393