1 /*******************************************************************************************************
2 DkPreferenceWidgets.cpp
3 Created on:	14.12.2015
4 
5 nomacs is a fast and small image viewer with the capability of synchronizing multiple instances
6 
7 Copyright (C) 2011-2014 Markus Diem <markus@nomacs.org>
8 Copyright (C) 2011-2014 Stefan Fiel <stefan@nomacs.org>
9 Copyright (C) 2011-2014 Florian Kleber <florian@nomacs.org>
10 
11 This file is part of nomacs.
12 
13 nomacs is free software: you can redistribute it and/or modify
14 it under the terms of the GNU General Public License as published by
15 the Free Software Foundation, either version 3 of the License, or
16 (at your option) any later version.
17 
18 nomacs is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21 GNU General Public License for more details.
22 
23 You should have received a copy of the GNU General Public License
24 along with this program.  If not, see <http://www.gnu.org/licenses/>.
25 
26 *******************************************************************************************************/
27 
28 #include "DkPreferenceWidgets.h"
29 
30 #include "DkImageStorage.h"
31 #include "DkWidgets.h"
32 #include "DkSettings.h"
33 #include "DkUtils.h"
34 #include "DkBasicWidgets.h"
35 #include "DkSettingsWidget.h"
36 #include "DkActionManager.h"
37 #include "DkNoMacs.h"
38 #include "DkDialog.h"
39 
40 #pragma warning(push, 0)	// no warnings from includes
41 #include <QVBoxLayout>
42 #include <QStackedLayout>
43 #include <QStyleOption>
44 #include <QPainter>
45 #include <QAction>
46 #include <QFileInfo>
47 #include <QCheckBox>
48 #include <QComboBox>
49 #include <QMessageBox>
50 #include <QSpinBox>
51 #include <QStandardItemModel>
52 #include <QTableView>
53 #include <QHeaderView>
54 #include <QStandardPaths>
55 #include <QProcess>
56 #include <QFileDialog>
57 #include <QStandardPaths>
58 
59 #include <QButtonGroup>
60 #include <QRadioButton>
61 
62 #include <QDebug>
63 #pragma warning(pop)
64 
65 namespace nmc {
66 
DkPreferenceWidget(QWidget * parent)67 DkPreferenceWidget::DkPreferenceWidget(QWidget* parent) : DkFadeWidget(parent) {
68 
69 	createLayout();
70 
71 	QAction* nextAction = new QAction(tr("next"), this);
72 	nextAction->setShortcut(Qt::Key_PageDown);
73 	connect(nextAction, SIGNAL(triggered()), this, SLOT(nextTab()));
74 	addAction(nextAction);
75 
76 	QAction* previousAction = new QAction(tr("previous"), this);
77 	previousAction->setShortcut(Qt::Key_PageUp);
78 	previousAction->setShortcutContext(Qt::WidgetWithChildrenShortcut);
79 	connect(previousAction, SIGNAL(triggered()), this, SLOT(previousTab()));
80 	addAction(previousAction);
81 }
82 
createLayout()83 void DkPreferenceWidget::createLayout() {
84 
85 	// create tab entries
86 	QWidget* tabs = new QWidget(this);
87 	tabs->setObjectName("DkPreferenceTabs");
88 
89 	QSize s(32, 32);
90 	QPixmap pm = DkImage::loadIcon(":/nomacs/img/power.svg", QColor(255, 255, 255), s);
91 	QPushButton* restartButton = new QPushButton(pm, "", this);
92 	restartButton->setObjectName("DkPlayerButton");
93 	restartButton->setFlat(true);
94 	restartButton->setIconSize(pm.size());
95 	restartButton->setObjectName("DkRestartButton");
96 	restartButton->setStatusTip(tr("Restart nomacs"));
97 	connect(restartButton, SIGNAL(clicked()), this, SIGNAL(restartSignal()));
98 
99 	mTabLayout = new QVBoxLayout(tabs);
100 	mTabLayout->setContentsMargins(0, 60, 0, 0);
101 	mTabLayout->setSpacing(0);
102 	mTabLayout->setAlignment(Qt::AlignTop);
103 	mTabLayout->addStretch();
104 	mTabLayout->addWidget(restartButton);
105 
106 	// create central widget
107 	QWidget* centralWidget = new QWidget(this);
108 	mCentralLayout = new QStackedLayout(centralWidget);
109 	mCentralLayout->setContentsMargins(0, 0, 0, 0);
110 
111 	// add a scroll area
112 	DkResizableScrollArea* scrollAreaTabs = new DkResizableScrollArea(this);
113 	scrollAreaTabs->setObjectName("DkPreferenceTabsScroller");
114 	scrollAreaTabs->setWidgetResizable(true);
115 	scrollAreaTabs->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
116 	scrollAreaTabs->setWidget(tabs);
117 
118 	QHBoxLayout* sL = new QHBoxLayout(this);
119 	sL->setContentsMargins(0, 0, 0, 0);	// use 1 to get the border
120 	sL->setSpacing(0);
121 	sL->setAlignment(Qt::AlignLeft);
122 	sL->addWidget(scrollAreaTabs);
123 	sL->addWidget(centralWidget);
124 }
125 
addTabWidget(DkPreferenceTabWidget * tabWidget)126 void DkPreferenceWidget::addTabWidget(DkPreferenceTabWidget* tabWidget) {
127 
128 	mWidgets.append(tabWidget);
129 	mCentralLayout->addWidget(tabWidget);
130 
131 	DkTabEntryWidget* tabEntry = new DkTabEntryWidget(tabWidget->icon(), tabWidget->name(), this);
132 	mTabLayout->insertWidget(mTabLayout->count()-2, tabEntry);	// -2 -> insert before stretch
133 	connect(tabEntry, SIGNAL(clicked()), this, SLOT(changeTab()));
134 	connect(tabWidget, SIGNAL(restartSignal()), this, SIGNAL(restartSignal()));
135 	mTabEntries.append(tabEntry);
136 
137 	// tick the first
138 	if (mTabEntries.size() == 1)
139 		tabEntry->click();
140 }
141 
previousTab()142 void DkPreferenceWidget::previousTab() {
143 
144 	// modulo is sign aware in cpp...
145 	int idx = (mCurrentIndex == 0) ? mWidgets.size()-1 : mCurrentIndex-1;
146 	setCurrentIndex(idx);
147 }
148 
nextTab()149 void DkPreferenceWidget::nextTab() {
150 	setCurrentIndex((mCurrentIndex+1) % mWidgets.size());
151 }
152 
changeTab()153 void DkPreferenceWidget::changeTab() {
154 
155 	DkTabEntryWidget* te = qobject_cast<DkTabEntryWidget*>(sender());
156 
157 	for (int idx = 0; idx < mTabEntries.size(); idx++) {
158 
159 		if (te == mTabEntries[idx]) {
160 			setCurrentIndex(idx);
161 		}
162 	}
163 }
164 
setCurrentIndex(int index)165 void DkPreferenceWidget::setCurrentIndex(int index) {
166 
167 	// something todo here?
168 	if (index == mCurrentIndex)
169 		return;
170 
171 	mCurrentIndex = index;
172 	mCentralLayout->setCurrentIndex(index);
173 
174 	// now check the correct one
175 	for (int idx = 0; idx < mTabEntries.size(); idx++)
176 		mTabEntries[idx]->setChecked(idx == index);
177 
178 }
179 
180 // DkPreferenceTabWidget --------------------------------------------------------------------
DkPreferenceTabWidget(const QIcon & icon,const QString & name,QWidget * parent)181 DkPreferenceTabWidget::DkPreferenceTabWidget(const QIcon& icon, const QString& name, QWidget* parent) : DkNamedWidget(name, parent) {
182 
183 	setObjectName("DkPreferenceTab");
184 	mIcon = icon;
185 
186 	createLayout();
187 	QMetaObject::connectSlotsByName(this);
188 }
189 
createLayout()190 void DkPreferenceTabWidget::createLayout() {
191 
192 	QLabel* titleLabel = new QLabel(name(), this);
193 	titleLabel->setObjectName("DkPreferenceTitle");
194 
195 	// add a scroll area
196 	mCentralScroller = new DkResizableScrollArea(this);
197 	mCentralScroller->setObjectName("DkPreferenceScroller");
198 	mCentralScroller->setWidgetResizable(true);
199 
200 	mInfoButton = new QPushButton(tr(""), this);
201 	mInfoButton->setObjectName("infoButton");
202 	mInfoButton->setFlat(true);
203 	mInfoButton->setVisible(false);
204 	connect(mInfoButton, SIGNAL(clicked()), this, SIGNAL(restartSignal()));
205 
206 	QGridLayout* l = new QGridLayout(this);
207 	l->setContentsMargins(0, 0, 0, 0);
208 	l->setAlignment(Qt::AlignTop);
209 	l->addWidget(titleLabel, 0, 0);
210 	l->addWidget(mCentralScroller, 1, 0);
211 	l->addWidget(mInfoButton, 2, 0, Qt::AlignBottom);
212 }
213 
setWidget(QWidget * w)214 void DkPreferenceTabWidget::setWidget(QWidget* w) {
215 
216 	mCentralScroller->setWidget(w);
217 	w->setObjectName("DkPreferenceWidget");
218 
219 	connect(w, SIGNAL(infoSignal(const QString&)), this, SLOT(setInfoMessage(const QString&)));
220 }
221 
setInfoMessage(const QString & msg)222 void DkPreferenceTabWidget::setInfoMessage(const QString& msg) {
223 
224 	mInfoButton->setText(msg);
225 	mInfoButton->setVisible(!msg.isEmpty());
226 }
227 
widget() const228 QWidget* DkPreferenceTabWidget::widget() const {
229 	return mCentralScroller->widget();
230 }
231 
icon() const232 QIcon DkPreferenceTabWidget::icon() const {
233 	return mIcon;
234 }
235 
236 // DkGroupWidget --------------------------------------------------------------------
DkGroupWidget(const QString & title,QWidget * parent)237 DkGroupWidget::DkGroupWidget(const QString& title, QWidget* parent) : DkWidget(parent) {
238 
239 	setObjectName("DkGroupWidget");
240 	mTitle = title;
241 
242 	createLayout();
243 }
244 
createLayout()245 void DkGroupWidget::createLayout() {
246 
247 	QLabel* titleLabel = new QLabel(mTitle, this);
248 	titleLabel->setObjectName("subTitle");
249 
250 	// we create a content widget to have control over the margins
251 	QWidget* contentWidget = new QWidget(this);
252 	mContentLayout = new QVBoxLayout(contentWidget);
253 
254 	QVBoxLayout* layout = new QVBoxLayout(this);
255 	layout->setContentsMargins(0, 0, 0, 0);
256 	layout->addWidget(titleLabel);
257 	layout->addWidget(contentWidget);
258 }
259 
addWidget(QWidget * widget)260 void DkGroupWidget::addWidget(QWidget* widget) {
261 
262 	mContentLayout->addWidget(widget);
263 }
264 
addSpace()265 void DkGroupWidget::addSpace() {
266 
267 	mContentLayout->addSpacing(10);
268 }
269 
paintEvent(QPaintEvent * event)270 void DkGroupWidget::paintEvent(QPaintEvent *event) {
271 
272 	// fixes stylesheets which are not applied to custom widgets
273 	QStyleOption opt;
274 	opt.init(this);
275 	QPainter p(this);
276 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
277 
278 	QWidget::paintEvent(event);
279 }
280 
281 // DkGeneralPreference --------------------------------------------------------------------
DkGeneralPreference(QWidget * parent)282 DkGeneralPreference::DkGeneralPreference(QWidget* parent) : DkWidget(parent) {
283 
284 	createLayout();
285 	QMetaObject::connectSlotsByName(this);
286 }
287 
createLayout()288 void DkGeneralPreference::createLayout() {
289 
290 	// Theme
291 	DkThemeManager tm;
292 	QStringList themes = tm.cleanThemeNames(tm.getAvailableThemes());
293 
294 	QComboBox* themeBox = new QComboBox(this);
295 	themeBox->setView(new QListView());
296 	themeBox->setObjectName("themeBox");
297 	themeBox->addItems(themes);
298 	themeBox->setCurrentText(tm.cleanThemeName(tm.getCurrentThemeName()));
299 	connect(themeBox, SIGNAL(currentIndexChanged(int)), this, SLOT(showRestartLabel()));
300 
301 	DkColorChooser* iconColorChooser = new DkColorChooser(QColor(51, 51, 51, 255), tr("Icon Color"), this);
302 	iconColorChooser->setObjectName("iconColor");
303 	iconColorChooser->setColor(&DkSettingsManager::param().display().iconColor);
304 	connect(iconColorChooser, SIGNAL(accepted()), this, SLOT(showRestartLabel()));
305 
306 	DkColorChooser* bgColorChooser = new DkColorChooser(QColor(100, 100, 100, 255), tr("Background Color"), this);
307 	bgColorChooser->setObjectName("backgroundColor");
308 	bgColorChooser->setColor(&DkSettingsManager::param().display().bgColor);
309 	connect(bgColorChooser, SIGNAL(accepted()), this, SLOT(showRestartLabel()));
310 
311 	DkColorChooser* fullscreenColorChooser = new DkColorChooser(QColor(51, 51, 51), tr("Fullscreen Color"), this);
312 	fullscreenColorChooser->setObjectName("fullscreenColor");
313 	fullscreenColorChooser->setColor(&DkSettingsManager::param().slideShow().backgroundColor);
314 	connect(fullscreenColorChooser, SIGNAL(accepted()), this, SLOT(showRestartLabel()));
315 
316 	DkGroupWidget* colorGroup = new DkGroupWidget(tr("Color Settings"), this);
317 	colorGroup->addWidget(themeBox);
318 	colorGroup->addWidget(iconColorChooser);
319 	colorGroup->addWidget(bgColorChooser);
320 	colorGroup->addWidget(fullscreenColorChooser);
321 
322 	// default pushbutton
323 	QPushButton* defaultSettings = new QPushButton(tr("Reset All Settings"));
324 	defaultSettings->setObjectName("defaultSettings");
325 	defaultSettings->setMaximumWidth(300);
326 
327 	QPushButton* importSettings = new QPushButton(tr("&Import Settings"));
328 	importSettings->setObjectName("importSettings");
329 	importSettings->setMaximumWidth(300);
330 
331 	QPushButton* exportSettings = new QPushButton(tr("&Export Settings"));
332 	exportSettings->setObjectName("exportSettings");
333 	exportSettings->setMaximumWidth(300);
334 
335 	DkGroupWidget* defaultGroup = new DkGroupWidget(tr("Default Settings"), this);
336 	defaultGroup->addWidget(defaultSettings);
337 	defaultGroup->addWidget(importSettings);
338 	defaultGroup->addWidget(exportSettings);
339 
340 	// the left column (holding all color settings)
341 	QWidget* leftColumn = new QWidget(this);
342 	leftColumn->setMinimumWidth(400);
343 
344 	QVBoxLayout* leftColumnLayout = new QVBoxLayout(leftColumn);
345 	leftColumnLayout->setAlignment(Qt::AlignTop);
346 	leftColumnLayout->addWidget(colorGroup);
347 	leftColumnLayout->addWidget(defaultGroup);
348 
349 	// checkboxes
350 	QCheckBox* cbRecentFiles = new QCheckBox(tr("Show Recent Files on Start-Up"), this);
351 	cbRecentFiles->setObjectName("showRecentFiles");
352 	cbRecentFiles->setToolTip(tr("Show the History Panel on Start-Up"));
353 	cbRecentFiles->setChecked(DkSettingsManager::param().app().showRecentFiles);
354 
355 	QCheckBox* cbLogRecentFiles = new QCheckBox(tr("Remember Recent Files History"), this);
356 	cbLogRecentFiles->setObjectName("logRecentFiles");
357 	cbLogRecentFiles->setToolTip(tr("If checked, recent files will be saved."));
358 	cbLogRecentFiles->setChecked(DkSettingsManager::param().global().logRecentFiles);
359 
360 	QCheckBox* cbCheckOpenDuplicates = new QCheckBox(tr("Check for Duplicates on Open"), this);
361 	cbCheckOpenDuplicates->setObjectName("checkOpenDuplicates");
362 	cbCheckOpenDuplicates->setToolTip(tr("If any files are opened which are already open in a tab, don't open them again."));
363 	cbCheckOpenDuplicates->setChecked(DkSettingsManager::param().global().checkOpenDuplicates);
364 
365 	QCheckBox* cbExtendedTabs = new QCheckBox(tr("Show extra options related to tabs"), this);
366 	cbExtendedTabs->setObjectName("extendedTabs");
367 	cbExtendedTabs->setToolTip(tr("Enables the \"Go to Tab\", \"First Tab\", and \"Last Tab\" options in the View menu, and the \"Open Tabs\" and \"Save Tabs\" options in the File menu."));
368 	cbExtendedTabs->setChecked(DkSettingsManager::param().global().extendedTabs);
369 
370 	QCheckBox* cbLoopImages = new QCheckBox(tr("Loop Images"), this);
371 	cbLoopImages->setObjectName("loopImages");
372 	cbLoopImages->setToolTip(tr("Start with the first image in a folder after showing the last."));
373 	cbLoopImages->setChecked(DkSettingsManager::param().global().loop);
374 
375 	QCheckBox* cbZoomOnWheel = new QCheckBox(tr("Mouse Wheel Zooms"), this);
376 	cbZoomOnWheel->setObjectName("zoomOnWheel");
377 	cbZoomOnWheel->setToolTip(tr("If checked, the mouse wheel zooms - otherwise it is used to switch between images."));
378 	cbZoomOnWheel->setChecked(DkSettingsManager::param().global().zoomOnWheel);
379 
380 	QCheckBox* cbHorZoomSkips = new QCheckBox(tr("Next Image on Horizontal Zoom"), this);
381 	cbHorZoomSkips->setObjectName("horZoomSkips");
382 	cbHorZoomSkips->setToolTip(tr("If checked, horizontal wheel events load the next/previous images."));
383 	cbHorZoomSkips->setChecked(DkSettingsManager::param().global().horZoomSkips);
384 
385 	QCheckBox* cbDoubleClickForFullscreen = new QCheckBox(tr("Double Click Opens Fullscreen"), this);
386 	cbDoubleClickForFullscreen->setObjectName("doubleClickForFullscreen");
387 	cbDoubleClickForFullscreen->setToolTip(tr("If checked, a double click on the canvas opens the fullscreen mode."));
388 	cbDoubleClickForFullscreen->setChecked(DkSettingsManager::param().global().doubleClickForFullscreen);
389 
390 	QCheckBox* cbShowBgImage = new QCheckBox(tr("Show Background Image"), this);
391 	cbShowBgImage->setObjectName("showBgImage");
392 	cbShowBgImage->setToolTip(tr("If checked, the nomacs logo is shown in the bottom right corner."));
393 	cbShowBgImage->setChecked(DkSettingsManager::param().global().showBgImage);
394 
395 	QCheckBox* cbSwitchModifier = new QCheckBox(tr("Switch CTRL with ALT"), this);
396 	cbSwitchModifier->setObjectName("switchModifier");
397 	cbSwitchModifier->setToolTip(tr("If checked, CTRL + Mouse is switched with ALT + Mouse."));
398 	cbSwitchModifier->setChecked(DkSettingsManager::param().sync().switchModifier);
399 
400 	QCheckBox* cbCloseOnEsc = new QCheckBox(tr("Close on ESC"), this);
401 	cbCloseOnEsc->setObjectName("closeOnEsc");
402 	cbCloseOnEsc->setToolTip(tr("Close nomacs if ESC is pressed."));
403 	cbCloseOnEsc->setChecked(DkSettingsManager::param().app().closeOnEsc);
404 
405 	QCheckBox* cbCheckForUpdates = new QCheckBox(tr("Check For Updates"), this);
406 	cbCheckForUpdates->setObjectName("checkForUpdates");
407 	cbCheckForUpdates->setToolTip(tr("Check for updates on start-up."));
408 	cbCheckForUpdates->setChecked(DkSettingsManager::param().sync().checkForUpdates);
409 	cbCheckForUpdates->setDisabled(DkSettingsManager::param().sync().disableUpdateInteraction);
410 
411 	DkGroupWidget* generalGroup = new DkGroupWidget(tr("General"), this);
412 	generalGroup->addWidget(cbRecentFiles);
413 	generalGroup->addWidget(cbLogRecentFiles);
414 	generalGroup->addWidget(cbCheckOpenDuplicates);
415 	generalGroup->addWidget(cbExtendedTabs);
416 	generalGroup->addWidget(cbLoopImages);
417 	generalGroup->addWidget(cbZoomOnWheel);
418 	generalGroup->addWidget(cbHorZoomSkips);
419 	generalGroup->addWidget(cbDoubleClickForFullscreen);
420 	generalGroup->addWidget(cbSwitchModifier);
421 	generalGroup->addWidget(cbCloseOnEsc);
422 	generalGroup->addWidget(cbCheckForUpdates);
423 	generalGroup->addWidget(cbShowBgImage);
424 
425 	// language
426 	QComboBox* languageCombo = new QComboBox(this);
427 	languageCombo->setView(new QListView());	// fix style
428 	languageCombo->setObjectName("languageCombo");
429 	languageCombo->setToolTip(tr("Choose your preferred language."));
430 	DkUtils::addLanguages(languageCombo, mLanguages);
431 	languageCombo->setCurrentIndex(mLanguages.indexOf(DkSettingsManager::param().global().language));
432 
433 	QLabel* translateLabel = new QLabel("<a href=\"https://nomacs.org/how-to-translate-nomacs/\">How-to translate nomacs</a>", this);
434 	translateLabel->setToolTip(tr("Info on how to translate nomacs."));
435 	translateLabel->setOpenExternalLinks(true);
436 
437 	DkGroupWidget* languageGroup = new DkGroupWidget(tr("Language"), this);
438 	languageGroup->addWidget(languageCombo);
439 	languageGroup->addWidget(translateLabel);
440 
441 	// the right column (holding all checkboxes)
442 	QWidget* cbWidget = new QWidget(this);
443 	QVBoxLayout* cbLayout = new QVBoxLayout(cbWidget);
444 	cbLayout->setAlignment(Qt::AlignTop);
445 	cbLayout->addWidget(generalGroup);
446 
447 	// add language
448 	cbLayout->addWidget(languageGroup);
449 
450 	QHBoxLayout* contentLayout = new QHBoxLayout(this);
451 	contentLayout->setAlignment(Qt::AlignLeft);
452 	contentLayout->addWidget(leftColumn);
453 	contentLayout->addWidget(cbWidget);
454 }
455 
showRestartLabel() const456 void DkGeneralPreference::showRestartLabel() const {
457 	emit infoSignal(tr("Please Restart nomacs to apply changes"));
458 }
459 
on_backgroundColor_accepted() const460 void DkGeneralPreference::on_backgroundColor_accepted() const {
461 	DkSettingsManager::param().display().defaultBackgroundColor = false;
462 }
463 
on_backgroundColor_resetClicked() const464 void DkGeneralPreference::on_backgroundColor_resetClicked() const {
465 	DkSettingsManager::param().display().defaultBackgroundColor = true;
466 }
467 
on_iconColor_accepted() const468 void DkGeneralPreference::on_iconColor_accepted() const {
469 	DkSettingsManager::param().display().defaultIconColor = false;
470 }
471 
on_iconColor_resetClicked() const472 void DkGeneralPreference::on_iconColor_resetClicked() const {
473 	DkSettingsManager::param().display().defaultIconColor = true;
474 }
475 
on_themeBox_currentIndexChanged(const QString & text) const476 void DkGeneralPreference::on_themeBox_currentIndexChanged(const QString& text) const {
477 
478 	QString tn = text + ".css";
479 	tn = tn.replace(" ", "-");
480 
481 	if (DkSettingsManager::param().display().themeName != tn) {
482 		DkSettingsManager::param().display().themeName = tn;
483 		DkThemeManager tm;
484 		tm.loadTheme(tn);
485 	}
486 }
487 
on_showRecentFiles_toggled(bool checked) const488 void DkGeneralPreference::on_showRecentFiles_toggled(bool checked) const {
489 
490 	if (DkSettingsManager::param().app().showRecentFiles != checked)
491 		DkSettingsManager::param().app().showRecentFiles = checked;
492 }
493 
on_logRecentFiles_toggled(bool checked) const494 void DkGeneralPreference::on_logRecentFiles_toggled(bool checked) const {
495 
496 	if (DkSettingsManager::param().global().logRecentFiles != checked)
497 		DkSettingsManager::param().global().logRecentFiles = checked;
498 }
499 
on_checkOpenDuplicates_toggled(bool checked) const500 void DkGeneralPreference::on_checkOpenDuplicates_toggled(bool checked) const {
501 
502 	if (DkSettingsManager::param().global().checkOpenDuplicates != checked)
503 		DkSettingsManager::param().global().checkOpenDuplicates = checked;
504 }
505 
on_extendedTabs_toggled(bool checked) const506 void DkGeneralPreference::on_extendedTabs_toggled(bool checked) const {
507 
508 	if (DkSettingsManager::param().global().extendedTabs != checked) {
509 		DkSettingsManager::param().global().extendedTabs = checked;
510 		showRestartLabel();
511 	}
512 }
513 
on_closeOnEsc_toggled(bool checked) const514 void DkGeneralPreference::on_closeOnEsc_toggled(bool checked) const {
515 
516 	if (DkSettingsManager::param().app().closeOnEsc != checked)
517 		DkSettingsManager::param().app().closeOnEsc = checked;
518 }
519 
on_zoomOnWheel_toggled(bool checked) const520 void DkGeneralPreference::on_zoomOnWheel_toggled(bool checked) const {
521 
522 	if (DkSettingsManager::param().global().zoomOnWheel != checked) {
523 		DkSettingsManager::param().global().zoomOnWheel = checked;
524 	}
525 }
526 
on_horZoomSkips_toggled(bool checked) const527 void DkGeneralPreference::on_horZoomSkips_toggled(bool checked) const {
528 
529 	if (DkSettingsManager::param().global().horZoomSkips != checked) {
530 		DkSettingsManager::param().global().horZoomSkips = checked;
531 	}
532 }
533 
on_doubleClickForFullscreen_toggled(bool checked) const534 void DkGeneralPreference::on_doubleClickForFullscreen_toggled(bool checked) const {
535 
536 	if (DkSettingsManager::param().global().doubleClickForFullscreen != checked)
537 		DkSettingsManager::param().global().doubleClickForFullscreen = checked;
538 
539 }
540 
on_showBgImage_toggled(bool checked) const541 void DkGeneralPreference::on_showBgImage_toggled(bool checked) const {
542 
543 	if (DkSettingsManager::param().global().showBgImage != checked) {
544 		DkSettingsManager::param().global().showBgImage = checked;
545 		showRestartLabel();
546 	}
547 
548 }
549 
on_checkForUpdates_toggled(bool checked) const550 void DkGeneralPreference::on_checkForUpdates_toggled(bool checked) const {
551 
552 	if (DkSettingsManager::param().sync().checkForUpdates != checked)
553 		DkSettingsManager::param().sync().checkForUpdates = checked;
554 }
555 
on_switchModifier_toggled(bool checked) const556 void DkGeneralPreference::on_switchModifier_toggled(bool checked) const {
557 
558 	if (DkSettingsManager::param().sync().switchModifier != checked) {
559 
560 		DkSettingsManager::param().sync().switchModifier = checked;
561 
562 		if (DkSettingsManager::param().sync().switchModifier) {
563 			DkSettingsManager::param().global().altMod = Qt::ControlModifier;
564 			DkSettingsManager::param().global().ctrlMod = Qt::AltModifier;
565 		}
566 		else {
567 			DkSettingsManager::param().global().altMod = Qt::AltModifier;
568 			DkSettingsManager::param().global().ctrlMod = Qt::ControlModifier;
569 		}
570 	}
571 }
572 
on_loopImages_toggled(bool checked) const573 void DkGeneralPreference::on_loopImages_toggled(bool checked) const {
574 
575 	if (DkSettingsManager::param().global().loop != checked)
576 		DkSettingsManager::param().global().loop = checked;
577 }
578 
on_defaultSettings_clicked()579 void DkGeneralPreference::on_defaultSettings_clicked() {
580 
581 	int answer = QMessageBox::warning(this, tr("Reset All Settings"), tr("This will reset all personal settings!"), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel);
582 
583 	if (answer == QMessageBox::Yes) {
584 		DkSettingsManager::param().setToDefaultSettings();
585 		showRestartLabel();
586 		qDebug() << "answer is: " << answer << "flushing all settings...";
587 	}
588 
589 }
590 
on_importSettings_clicked()591 void DkGeneralPreference::on_importSettings_clicked() {
592 
593 	QString filePath = QFileDialog::getOpenFileName(
594 		DkUtils::getMainWindow(),
595 		tr("Import Settings"),
596 		QDir::homePath(),
597 		"Nomacs Settings (*.ini)",
598 		nullptr,
599 		DkDialog::fileDialogOptions()
600 	);
601 
602 	// user canceled?
603 	if (filePath.isEmpty())
604 		return;
605 
606 	DkSettingsManager::importSettings(filePath);
607 
608 	showRestartLabel();
609 }
610 
on_exportSettings_clicked()611 void DkGeneralPreference::on_exportSettings_clicked() {
612 
613 	QString filePath = QFileDialog::getSaveFileName(
614 		DkUtils::getMainWindow(),
615 		tr("Export Settings"),
616 		QDir::homePath(),
617 		"Nomacs Settings (*.ini)",
618 		nullptr,
619 		DkDialog::fileDialogOptions()
620 	);
621 
622 	// user canceled?
623 	if (filePath.isEmpty())
624 		return;
625 
626 	// try copying setting
627 	// NOTE: unfortunately this won't copy ini files on unix
628 	bool copied = false;
629 	QFile f(DkSettingsManager::instance().param().settingsPath());
630 	if (f.exists())
631 		copied = f.copy(filePath);
632 
633 	// save settings (here we lose settings such as [CustomShortcuts])
634 	if (!copied) {
635 		QSettings settings(filePath, QSettings::IniFormat);
636 		DkSettingsManager::instance().settings().save(settings, true);
637 	}
638 
639 	emit infoSignal(tr("Settings exported"));
640 }
641 
on_languageCombo_currentIndexChanged(int index) const642 void DkGeneralPreference::on_languageCombo_currentIndexChanged(int index) const {
643 
644 	if (index >= 0 && index < mLanguages.size()) {
645 		QString language = mLanguages[index];
646 
647 		if (DkSettingsManager::param().global().language != language) {
648 			DkSettingsManager::param().global().language = language;
649 			showRestartLabel();
650 		}
651 	}
652 }
653 
paintEvent(QPaintEvent * event)654 void DkGeneralPreference::paintEvent(QPaintEvent *event) {
655 
656 	// fixes stylesheets which are not applied to custom widgets
657 	QStyleOption opt;
658 	opt.init(this);
659 	QPainter p(this);
660 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
661 
662 	QWidget::paintEvent(event);
663 }
664 
665 // DkDisplaySettings --------------------------------------------------------------------
DkDisplayPreference(QWidget * parent)666 DkDisplayPreference::DkDisplayPreference(QWidget* parent) : DkWidget(parent) {
667 
668 	createLayout();
669 	QMetaObject::connectSlotsByName(this);
670 }
671 
createLayout()672 void DkDisplayPreference::createLayout() {
673 
674 	// zoom settings
675 	QCheckBox* invertZoom = new QCheckBox(tr("Invert mouse wheel behaviour for zooming"), this);
676 	invertZoom->setObjectName("invertZoom");
677 	invertZoom->setToolTip(tr("If checked, the mouse wheel behaviour is inverted while zooming."));
678 	invertZoom->setChecked(DkSettingsManager::param().display().invertZoom);
679 
680 	// zoom settings
681 	QCheckBox* hQAntiAliasing = new QCheckBox(tr("Display Images with High Quality Anti Aliasing"), this);
682 	hQAntiAliasing->setObjectName("hQAntiAliasing");
683 	hQAntiAliasing->setToolTip(tr("NOTE: if checked, nomacs might be slow while zooming."));
684 	hQAntiAliasing->setChecked(DkSettingsManager::param().display().highQualityAntiAliasing);
685 
686 	// show scollbars
687 	QCheckBox* showScrollBars = new QCheckBox(tr("Show Scrollbars when zooming into images"), this);
688 	showScrollBars->setObjectName("showScrollBars");
689 	showScrollBars->setToolTip(tr("If checked, scrollbars will appear that allow panning with the mouse."));
690 	showScrollBars->setChecked(DkSettingsManager::param().display().showScrollBars);
691 
692 	QLabel* interpolationLabel = new QLabel(tr("Show pixels if zoom level is above"), this);
693 
694 	QSpinBox* sbInterpolation = new QSpinBox(this);
695 	sbInterpolation->setObjectName("interpolationBox");
696 	sbInterpolation->setToolTip(tr("nomacs will not interpolate images if the zoom level is larger."));
697 	sbInterpolation->setSuffix("%");
698 	sbInterpolation->setMinimum(0);
699 	sbInterpolation->setMaximum(10000);
700 	sbInterpolation->setValue(DkSettingsManager::param().display().interpolateZoomLevel);
701 
702 	// zoom levels
703 	DkZoomConfig& zc = DkZoomConfig::instance();
704 	QCheckBox* useZoomLevels = new QCheckBox(tr("Use Fixed Zoom Levels"), this);
705 	useZoomLevels->setObjectName("useZoomLevels");
706 	useZoomLevels->setToolTip(tr("If checked, predefined zoom levels are used when zooming."));
707 	useZoomLevels->setChecked(zc.useLevels());
708 
709 	mZoomLevelsEdit = new QLineEdit(this);
710 	mZoomLevelsEdit->setObjectName("zoomLevels");
711 	mZoomLevelsEdit->setText(zc.levelsToString());
712 
713 	QPushButton* zoomLevelsDefaults = new QPushButton(tr("Load Defaults"), this);
714 	zoomLevelsDefaults->setObjectName("zoomLevelsDefault");
715 
716 	mZoomLevels = new QWidget(this);
717 
718 	QHBoxLayout* zll = new QHBoxLayout(mZoomLevels);
719 	zll->addWidget(mZoomLevelsEdit);
720 	zll->addWidget(zoomLevelsDefaults);
721 
722 	mZoomLevels->setEnabled(zc.useLevels());
723 
724 	DkGroupWidget* zoomGroup = new DkGroupWidget(tr("Zoom"), this);
725 	zoomGroup->addWidget(invertZoom);
726 	zoomGroup->addWidget(hQAntiAliasing);
727 	zoomGroup->addWidget(showScrollBars);
728 	zoomGroup->addWidget(interpolationLabel);
729 	zoomGroup->addWidget(sbInterpolation);
730 	zoomGroup->addWidget(useZoomLevels);
731 	zoomGroup->addWidget(mZoomLevels);
732 
733 	// keep zoom radio buttons
734 	QVector<QRadioButton*> keepZoomButtons;
735 	keepZoomButtons.resize(DkSettings::zoom_end);
736 	keepZoomButtons[DkSettings::zoom_always_keep] = new QRadioButton(tr("Always keep zoom"), this);
737 	keepZoomButtons[DkSettings::zoom_keep_same_size] = new QRadioButton(tr("Keep zoom if the size is the same"), this);
738 	keepZoomButtons[DkSettings::zoom_keep_same_size]->setToolTip(tr("If checked, the zoom level is only kept, if the image loaded has the same level as the previous."));
739 	keepZoomButtons[DkSettings::zoom_never_keep] = new QRadioButton(tr("Never keep zoom"), this);
740 
741 	QCheckBox* cbZoomToFit = new QCheckBox(tr("Always zoom to fit"), this);
742 	cbZoomToFit->setObjectName("zoomToFit");
743 	cbZoomToFit->setChecked(DkSettingsManager::param().display().zoomToFit);
744 
745 	// check wrt the current settings
746 	keepZoomButtons[DkSettingsManager::param().display().keepZoom]->setChecked(true);
747 
748 	QButtonGroup* keepZoomButtonGroup = new QButtonGroup(this);
749 	keepZoomButtonGroup->setObjectName("keepZoom");
750 	keepZoomButtonGroup->addButton(keepZoomButtons[DkSettings::zoom_always_keep], DkSettings::zoom_always_keep);
751 	keepZoomButtonGroup->addButton(keepZoomButtons[DkSettings::zoom_keep_same_size], DkSettings::zoom_keep_same_size);
752 	keepZoomButtonGroup->addButton(keepZoomButtons[DkSettings::zoom_never_keep], DkSettings::zoom_never_keep);
753 
754 	DkGroupWidget* keepZoomGroup = new DkGroupWidget(tr("When Displaying New Images"), this);
755 	keepZoomGroup->addWidget(keepZoomButtons[DkSettings::zoom_always_keep]);
756 	keepZoomGroup->addWidget(keepZoomButtons[DkSettings::zoom_keep_same_size]);
757 	keepZoomGroup->addWidget(keepZoomButtons[DkSettings::zoom_never_keep]);
758 	keepZoomGroup->addWidget(cbZoomToFit);
759 
760 	// icon size
761 	QSpinBox* sbIconSize = new QSpinBox(this);
762 	sbIconSize->setObjectName("iconSizeBox");
763 	sbIconSize->setToolTip(tr("Define the icon size in pixel."));
764 	sbIconSize->setSuffix(" px");
765 	sbIconSize->setMinimum(16);
766 	sbIconSize->setMaximum(1024);
767 	sbIconSize->setValue(DkSettingsManager::param().effectiveIconSize(sbIconSize));
768 
769 	DkGroupWidget* iconGroup = new DkGroupWidget(tr("Icon Size"), this);
770 	iconGroup->addWidget(sbIconSize);
771 
772 	// show navigation
773 	QCheckBox* cbShowNavigation = new QCheckBox(tr("Show Navigation Arrows"), this);
774 	cbShowNavigation->setObjectName("showNavigation");
775 	cbShowNavigation->setToolTip(tr("If checked, navigation arrows will be displayed on top of the image"));
776 	cbShowNavigation->setChecked(DkSettingsManager::param().display().showNavigation);
777 
778 	DkGroupWidget* navigationGroup = new DkGroupWidget(tr("Navigation"), this);
779 	navigationGroup->addWidget(cbShowNavigation);
780 
781 
782 	// slideshow
783 	QLabel* fadeImageLabel = new QLabel(tr("Image Transition"), this);
784 
785 	QComboBox* cbTransition = new QComboBox(this);
786 	cbTransition->setView(new QListView());	// fix style
787 	cbTransition->setObjectName("transition");
788 	cbTransition->setToolTip(tr("Choose a transition when loading a new image"));
789 
790 	for (int idx = 0; idx < DkSettings::trans_end; idx++) {
791 
792 		QString str = tr("Unknown Transition");
793 
794 		switch (idx) {
795 		case DkSettings::trans_appear:	str = tr("Appear"); break;
796 		case DkSettings::trans_swipe:	str = tr("Swipe");	break;
797 		case DkSettings::trans_fade:	str = tr("Fade");	break;
798 		}
799 
800 		cbTransition->addItem(str);
801 	}
802 	cbTransition->setCurrentIndex(DkSettingsManager::param().display().transition);
803 
804 	QDoubleSpinBox* fadeImageBox = new QDoubleSpinBox(this);
805 	fadeImageBox->setObjectName("fadeImageBox");
806 	fadeImageBox->setToolTip(tr("Define the image transition speed."));
807 	fadeImageBox->setSuffix(" sec");
808 	fadeImageBox->setMinimum(0.0);
809 	fadeImageBox->setMaximum(3);
810 	fadeImageBox->setSingleStep(.2);
811 	fadeImageBox->setValue(DkSettingsManager::param().display().animationDuration);
812 
813 	QCheckBox* cbAlwaysAnimate = new QCheckBox(tr("Always Animate Image Loading"), this);
814 	cbAlwaysAnimate->setObjectName("alwaysAnimate");
815 	cbAlwaysAnimate->setToolTip(tr("If unchecked, loading is only animated if nomacs is fullscreen"));
816 	cbAlwaysAnimate->setChecked(DkSettingsManager::param().display().alwaysAnimate);
817 
818 	QLabel* displayTimeLabel = new QLabel(tr("Display Time"), this);
819 
820 	QDoubleSpinBox* displayTimeBox = new QDoubleSpinBox(this);
821 	displayTimeBox->setObjectName("displayTimeBox");
822 	displayTimeBox->setToolTip(tr("Define the time an image is displayed."));
823 	displayTimeBox->setSuffix(" sec");
824 	displayTimeBox->setMinimum(0.0);
825 	displayTimeBox->setMaximum(30);
826 	displayTimeBox->setSingleStep(.2);
827 	displayTimeBox->setValue(DkSettingsManager::param().slideShow().time);
828 
829 	QCheckBox* showPlayer = new QCheckBox(tr("Show Player"), this);
830 	showPlayer->setObjectName("showPlayer");
831 	showPlayer->setChecked(DkSettingsManager::param().slideShow().showPlayer);
832 
833 	DkGroupWidget* slideshowGroup = new DkGroupWidget(tr("Slideshow"), this);
834 	slideshowGroup->addWidget(fadeImageLabel);
835 	slideshowGroup->addWidget(cbTransition);
836 	slideshowGroup->addWidget(fadeImageBox);
837 	slideshowGroup->addWidget(cbAlwaysAnimate);
838 	slideshowGroup->addWidget(displayTimeLabel);
839 	slideshowGroup->addWidget(displayTimeBox);
840 	slideshowGroup->addWidget(showPlayer);
841 
842 	// show crop from metadata
843 	QCheckBox* showCrop = new QCheckBox(tr("Show crop rectangle"), this);
844 	showCrop->setObjectName("showCrop");
845 	showCrop->setChecked(DkSettingsManager::param().display().showCrop);
846 
847 	DkGroupWidget* showCropGroup = new DkGroupWidget(tr("Show Metadata Cropping"), this);
848 	showCropGroup->addWidget(showCrop);
849 
850 	// left column
851 	QVBoxLayout* l = new QVBoxLayout(this);
852 	l->setAlignment(Qt::AlignTop);
853 	l->addWidget(zoomGroup);
854 	l->addWidget(keepZoomGroup);
855 	l->addWidget(iconGroup);
856 	l->addWidget(navigationGroup);
857 	l->addWidget(slideshowGroup);
858 	l->addWidget(showCropGroup);
859 }
860 
on_interpolationBox_valueChanged(int value) const861 void DkDisplayPreference::on_interpolationBox_valueChanged(int value) const {
862 
863 	if (DkSettingsManager::param().display().interpolateZoomLevel != value)
864 		DkSettingsManager::param().display().interpolateZoomLevel = value;
865 
866 }
867 
on_fadeImageBox_valueChanged(double value) const868 void DkDisplayPreference::on_fadeImageBox_valueChanged(double value) const {
869 
870 	if (DkSettingsManager::param().display().animationDuration != value)
871 		DkSettingsManager::param().display().animationDuration = (float)value;
872 
873 }
874 
on_displayTimeBox_valueChanged(double value) const875 void DkDisplayPreference::on_displayTimeBox_valueChanged(double value) const {
876 
877 	if (DkSettingsManager::param().slideShow().time != value)
878 		DkSettingsManager::param().slideShow().time = (float)value;
879 
880 }
881 
on_showPlayer_toggled(bool checked) const882 void DkDisplayPreference::on_showPlayer_toggled(bool checked) const {
883 
884 	if (DkSettingsManager::param().slideShow().showPlayer != checked)
885 		DkSettingsManager::param().slideShow().showPlayer = checked;
886 
887 }
888 
on_iconSizeBox_valueChanged(int value) const889 void DkDisplayPreference::on_iconSizeBox_valueChanged(int value) const {
890 
891 	if (DkSettingsManager::param().display().iconSize != value) {
892 		DkSettingsManager::param().display().iconSize = value;
893 		emit infoSignal(tr("Please Restart nomacs to apply changes"));
894 	}
895 
896 }
897 
on_keepZoom_buttonClicked(int buttonId) const898 void DkDisplayPreference::on_keepZoom_buttonClicked(int buttonId) const {
899 
900 	if (DkSettingsManager::param().display().keepZoom != buttonId)
901 		DkSettingsManager::param().display().keepZoom = buttonId;
902 }
903 
on_invertZoom_toggled(bool checked) const904 void DkDisplayPreference::on_invertZoom_toggled(bool checked) const {
905 
906 	if (DkSettingsManager::param().display().invertZoom != checked)
907 		DkSettingsManager::param().display().invertZoom = checked;
908 }
909 
on_hQAntiAliasing_toggled(bool checked) const910 void DkDisplayPreference::on_hQAntiAliasing_toggled(bool checked) const {
911 
912 	if (DkSettingsManager::param().display().highQualityAntiAliasing != checked)
913 		DkSettingsManager::param().display().highQualityAntiAliasing = checked;
914 }
915 
on_zoomToFit_toggled(bool checked) const916 void DkDisplayPreference::on_zoomToFit_toggled(bool checked) const {
917 
918 	if (DkSettingsManager::param().display().zoomToFit != checked)
919 		DkSettingsManager::param().display().zoomToFit = checked;
920 
921 }
922 
on_transition_currentIndexChanged(int index) const923 void DkDisplayPreference::on_transition_currentIndexChanged(int index) const {
924 
925 	if (DkSettingsManager::param().display().transition != index)
926 		DkSettingsManager::param().display().transition = (DkSettings::TransitionMode)index;
927 
928 }
929 
on_alwaysAnimate_toggled(bool checked) const930 void DkDisplayPreference::on_alwaysAnimate_toggled(bool checked) const {
931 
932 	if (DkSettingsManager::param().display().alwaysAnimate != checked)
933 		DkSettingsManager::param().display().alwaysAnimate = checked;
934 
935 }
936 
on_showCrop_toggled(bool checked) const937 void DkDisplayPreference::on_showCrop_toggled(bool checked) const {
938 
939 	if (DkSettingsManager::param().display().showCrop != checked)
940 		DkSettingsManager::param().display().showCrop = checked;
941 
942 }
943 
on_showScrollBars_toggled(bool checked) const944 void DkDisplayPreference::on_showScrollBars_toggled(bool checked) const {
945 
946 	if (DkSettingsManager::param().display().showScrollBars != checked)
947 		DkSettingsManager::param().display().showScrollBars = checked;
948 }
949 
on_useZoomLevels_toggled(bool checked) const950 void DkDisplayPreference::on_useZoomLevels_toggled(bool checked) const {
951 
952 	DkZoomConfig::instance().setUseLevels(checked);
953 	mZoomLevels->setEnabled(checked);
954 
955 }
956 
on_showNavigation_toggled(bool checked) const957 void DkDisplayPreference::on_showNavigation_toggled(bool checked) const {
958 
959 	if (DkSettingsManager::param().display().showNavigation != checked)
960 		DkSettingsManager::param().display().showNavigation = checked;
961 
962 }
963 
on_zoomLevels_editingFinished() const964 void DkDisplayPreference::on_zoomLevels_editingFinished() const {
965 
966 	DkZoomConfig& zc = DkZoomConfig::instance();
967 	if (!zc.setLevels(mZoomLevelsEdit->text()))
968 		mZoomLevelsEdit->setText(zc.levelsToString());
969 
970 }
971 
on_zoomLevelsDefault_clicked() const972 void DkDisplayPreference::on_zoomLevelsDefault_clicked() const {
973 
974 	DkZoomConfig::instance().setLevelsToDefault();
975 	mZoomLevelsEdit->setText(DkZoomConfig::instance().levelsToString());
976 }
977 
paintEvent(QPaintEvent * event)978 void DkDisplayPreference::paintEvent(QPaintEvent *event) {
979 
980 	// fixes stylesheets which are not applied to custom widgets
981 	QStyleOption opt;
982 	opt.init(this);
983 	QPainter p(this);
984 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
985 
986 	QWidget::paintEvent(event);
987 }
988 
989 // DkDummySettings --------------------------------------------------------------------
DkFilePreference(QWidget * parent)990 DkFilePreference::DkFilePreference(QWidget* parent) : DkWidget(parent) {
991 
992 	createLayout();
993 	QMetaObject::connectSlotsByName(this);
994 }
995 
createLayout()996 void DkFilePreference::createLayout() {
997 
998 	// temp folder
999 	DkDirectoryChooser* dirChooser = new DkDirectoryChooser(DkSettingsManager::param().global().tmpPath, this);
1000 	dirChooser->setObjectName("dirChooser");
1001 
1002 	QLabel* tLabel = new QLabel(tr("Screenshots are automatically saved to this folder"), this);
1003 
1004 	DkGroupWidget* tempFolderGroup = new DkGroupWidget(tr("Use Temporary Folder"), this);
1005 	tempFolderGroup->addWidget(dirChooser);
1006 	tempFolderGroup->addWidget(tLabel);
1007 
1008 	// cache size
1009 	int maxRam = qMax(qRound(DkMemory::getTotalMemory()), 1024);
1010 	qInfo() << "Available RAM: " << maxRam << "MB";
1011 	QSpinBox* cacheBox = new QSpinBox(this);
1012 	cacheBox->setObjectName("cacheBox");
1013 	cacheBox->setMinimum(0);
1014 	cacheBox->setMaximum(maxRam);
1015 	cacheBox->setSuffix(" MB");
1016 	cacheBox->setMaximumWidth(200);
1017 	cacheBox->setValue(qRound(DkSettingsManager::param().resources().cacheMemory));
1018 
1019 	QLabel* cLabel = new QLabel(tr("We recommend to set a moderate cache value around 100 MB. [%1-%2 MB]")
1020 		.arg(cacheBox->minimum()).arg(cacheBox->maximum()), this);
1021 
1022 	DkGroupWidget* cacheGroup = new DkGroupWidget(tr("Maximal Cache Size"), this);
1023 	cacheGroup->addWidget(cacheBox);
1024 	cacheGroup->addWidget(cLabel);
1025 
1026 	// history size
1027 	// cache size
1028 	QSpinBox* historyBox = new QSpinBox(this);
1029 	historyBox->setObjectName("historyBox");
1030 	historyBox->setMinimum(0);
1031 	historyBox->setMaximum(1024);
1032 	historyBox->setSuffix(" MB");
1033 	historyBox->setMaximumWidth(200);
1034 	historyBox->setValue(qRound(DkSettingsManager::param().resources().historyMemory));
1035 
1036 	QLabel* hLabel = new QLabel(tr("We recommend to set a moderate edit history value around 100 MB. [%1-%2 MB]")
1037 		.arg(historyBox->minimum()).arg(historyBox->maximum()), this);
1038 
1039 	DkGroupWidget* historyGroup = new DkGroupWidget(tr("History Size"), this);
1040 	historyGroup->addWidget(historyBox);
1041 	historyGroup->addWidget(hLabel);
1042 
1043 	// loading policy
1044 	QVector<QRadioButton*> loadButtons;
1045 	loadButtons.append(new QRadioButton(tr("Skip Images"), this));
1046 	loadButtons[0]->setToolTip(tr("Images are skipped until the Next key is released"));
1047 	loadButtons.append(new QRadioButton(tr("Wait for Images to be Loaded"), this));
1048 	loadButtons[1]->setToolTip(tr("The next image is loaded after the current image is shown."));
1049 
1050 	// check wrt the current settings
1051 	loadButtons[0]->setChecked(!DkSettingsManager::param().resources().waitForLastImg);
1052 	loadButtons[1]->setChecked(DkSettingsManager::param().resources().waitForLastImg);
1053 
1054 	QButtonGroup* loadButtonGroup = new QButtonGroup(this);
1055 	loadButtonGroup->setObjectName("loadGroup");
1056 	loadButtonGroup->addButton(loadButtons[0], 0);
1057 	loadButtonGroup->addButton(loadButtons[1], 1);
1058 
1059 	DkGroupWidget* loadGroup = new DkGroupWidget(tr("Image Loading Policy"), this);
1060 	loadGroup->addWidget(loadButtons[0]);
1061 	loadGroup->addWidget(loadButtons[1]);
1062 
1063 	// save policy
1064 	QVector<QRadioButton*> saveButtons;
1065 	saveButtons.append(new QRadioButton(tr("Load Saved Images"), this));
1066 	saveButtons[0]->setToolTip(tr("After saving, the saved image will be loaded in place"));
1067 	saveButtons.append(new QRadioButton(tr("Load to Tab"), this));
1068 	saveButtons[1]->setToolTip(tr("After saving, the saved image will be loaded to a tab."));
1069 	saveButtons.append(new QRadioButton(tr("Do Nothing"), this));
1070 	saveButtons[2]->setToolTip(tr("The saved image will not be loaded."));
1071 
1072 	// check wrt the current settings
1073 	saveButtons[DkSettingsManager::param().resources().loadSavedImage]->setChecked(true);
1074 
1075 	QButtonGroup* saveButtonGroup = new QButtonGroup(this);
1076 	saveButtonGroup->setObjectName("saveGroup");
1077 
1078 	DkGroupWidget* saveGroup = new DkGroupWidget(tr("Image Saving Policy"), this);
1079 
1080 	for (int idx = 0; idx < saveButtons.size(); idx++) {
1081 		saveButtonGroup->addButton(saveButtons[idx], idx);
1082 		saveGroup->addWidget(saveButtons[idx]);
1083 	}
1084 
1085 	// skip images
1086 	QSpinBox* skipBox = new QSpinBox(this);
1087 	skipBox->setObjectName("skipBox");
1088 	skipBox->setMinimum(2);
1089 	skipBox->setMaximum(1000);
1090 	skipBox->setValue(DkSettingsManager::param().global().skipImgs);
1091 	skipBox->setMaximumWidth(200);
1092 
1093 	DkGroupWidget* skipGroup = new DkGroupWidget(tr("Number of Skipped Images on PgUp/PgDown"), this);
1094 	skipGroup->addWidget(skipBox);
1095 
1096 	// left column
1097 	QVBoxLayout* l = new QVBoxLayout(this);
1098 	l->setAlignment(Qt::AlignTop);
1099 	l->addWidget(tempFolderGroup);
1100 	l->addWidget(cacheGroup);
1101 	l->addWidget(historyGroup);
1102 	l->addWidget(loadGroup);
1103 	l->addWidget(saveGroup);
1104 	l->addWidget(skipGroup);
1105 }
1106 
on_dirChooser_directoryChanged(const QString & dirPath) const1107 void DkFilePreference::on_dirChooser_directoryChanged(const QString& dirPath) const {
1108 
1109 	bool dirExists = QDir(dirPath).exists();
1110 
1111 	if (DkSettingsManager::param().global().tmpPath != dirPath && dirExists)
1112 		DkSettingsManager::param().global().tmpPath = dirPath;
1113 	else if (!dirExists)
1114 		DkSettingsManager::param().global().tmpPath = "";
1115 
1116 }
1117 
on_loadGroup_buttonClicked(int buttonId) const1118 void DkFilePreference::on_loadGroup_buttonClicked(int buttonId) const {
1119 
1120 	if (DkSettingsManager::param().resources().waitForLastImg != (buttonId == 1))
1121 		DkSettingsManager::param().resources().waitForLastImg = (buttonId == 1);
1122 
1123 }
1124 
on_saveGroup_buttonClicked(int buttonId) const1125 void DkFilePreference::on_saveGroup_buttonClicked(int buttonId) const {
1126 
1127 	if (DkSettingsManager::param().resources().loadSavedImage != buttonId)
1128 		DkSettingsManager::param().resources().loadSavedImage = buttonId;
1129 
1130 }
1131 
on_skipBox_valueChanged(int value) const1132 void DkFilePreference::on_skipBox_valueChanged(int value) const {
1133 
1134 	if (DkSettingsManager::param().global().skipImgs != value) {
1135 		DkSettingsManager::param().global().skipImgs = value;
1136 	}
1137 
1138 }
1139 
on_cacheBox_valueChanged(int value) const1140 void DkFilePreference::on_cacheBox_valueChanged(int value) const {
1141 
1142 	if (DkSettingsManager::param().resources().cacheMemory != value) {
1143 		DkSettingsManager::param().resources().cacheMemory = (float)value;
1144 	}
1145 
1146 }
1147 
on_historyBox_valueChanged(int value) const1148 void DkFilePreference::on_historyBox_valueChanged(int value) const {
1149 
1150 	if (DkSettingsManager::param().resources().historyMemory != value) {
1151 		DkSettingsManager::param().resources().historyMemory = (float)value;
1152 	}
1153 }
1154 
paintEvent(QPaintEvent * event)1155 void DkFilePreference::paintEvent(QPaintEvent *event) {
1156 
1157 	// fixes stylesheets which are not applied to custom widgets
1158 	QStyleOption opt;
1159 	opt.init(this);
1160 	QPainter p(this);
1161 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
1162 
1163 	QWidget::paintEvent(event);
1164 }
1165 
1166 // DkFileAssocationsSettings --------------------------------------------------------------------
DkFileAssociationsPreference(QWidget * parent)1167 DkFileAssociationsPreference::DkFileAssociationsPreference(QWidget* parent) : DkWidget(parent) {
1168 
1169 	createLayout();
1170 	QMetaObject::connectSlotsByName(this);
1171 }
1172 
~DkFileAssociationsPreference()1173 DkFileAssociationsPreference::~DkFileAssociationsPreference() {
1174 
1175 	// save settings
1176 	if (mSaveSettings) {
1177 		writeSettings();
1178 		mSaveSettings = false;
1179 		DkSettingsManager::param().save();
1180 	}
1181 }
1182 
createLayout()1183 void DkFileAssociationsPreference::createLayout() {
1184 
1185 	QStringList fileFilters = DkSettingsManager::param().app().openFilters;
1186 
1187 	mModel = new QStandardItemModel(this);
1188 	mModel->setObjectName("fileModel");
1189 	for (int rIdx = 1; rIdx < fileFilters.size(); rIdx++)
1190 		mModel->appendRow(getItems(fileFilters.at(rIdx), checkFilter(fileFilters.at(rIdx), DkSettingsManager::param().app().browseFilters), checkFilter(fileFilters.at(rIdx), DkSettingsManager::param().app().registerFilters)));
1191 
1192 	mModel->setHeaderData(0, Qt::Horizontal, tr("Filter"));
1193 	mModel->setHeaderData(1, Qt::Horizontal, tr("Browse"));
1194 	mModel->setHeaderData(2, Qt::Horizontal, tr("Register"));
1195 
1196 	QTableView* filterTableView = new QTableView(this);
1197 	filterTableView->setModel(mModel);
1198 	filterTableView->setSelectionBehavior(QAbstractItemView::SelectRows);
1199 	filterTableView->verticalHeader()->hide();
1200 	filterTableView->setShowGrid(false);
1201 	filterTableView->resizeColumnsToContents();
1202 	filterTableView->resizeRowsToContents();
1203 	filterTableView->setWordWrap(false);
1204 
1205 	// now the final widgets
1206 	QVBoxLayout* layout = new QVBoxLayout(this);
1207 	layout->setAlignment(Qt::AlignTop);
1208 	layout->addWidget(filterTableView);
1209 
1210 #ifdef Q_OS_WIN
1211 
1212 	QPushButton* assocFiles = new QPushButton(tr("Set File Associations"), this);
1213 	assocFiles->setObjectName("associateFiles");
1214 
1215 	QPushButton* openDefault = new QPushButton(tr("Set as Default Viewer"), this);
1216 	openDefault->setObjectName("openDefault");
1217 
1218 	QWidget* bw = new QWidget(this);
1219 	QHBoxLayout* l = new QHBoxLayout(bw);
1220 	l->setAlignment(Qt::AlignLeft);
1221 	l->setContentsMargins(0, 0, 0, 0);
1222 	l->addWidget(openDefault);
1223 	l->addWidget(assocFiles);
1224 
1225 	layout->addWidget(bw);
1226 #endif
1227 
1228 }
1229 
on_fileModel_itemChanged(QStandardItem *)1230 void DkFileAssociationsPreference::on_fileModel_itemChanged(QStandardItem*) {
1231 
1232 	mSaveSettings = true;
1233 	emit infoSignal(tr("Please Restart nomacs to apply changes"));
1234 }
1235 
on_openDefault_clicked() const1236 void DkFileAssociationsPreference::on_openDefault_clicked() const {
1237 
1238 	DkFileFilterHandling fh;
1239 	fh.showDefaultSoftware();
1240 }
1241 
on_associateFiles_clicked()1242 void DkFileAssociationsPreference::on_associateFiles_clicked() {
1243 
1244 	mSaveSettings = true;
1245 	emit infoSignal(tr("Please Restart nomacs to apply changes"));
1246 }
1247 
checkFilter(const QString & cFilter,const QStringList & filters) const1248 bool DkFileAssociationsPreference::checkFilter(const QString& cFilter, const QStringList& filters) const {
1249 
1250 	if (filters.empty() && (DkSettingsManager::param().app().containerFilters.contains(cFilter) || cFilter.contains("ico")))
1251 		return false;
1252 
1253 	if (filters.empty())
1254 		return true;
1255 
1256 	for (int idx = 0; idx < filters.size(); idx++)
1257 		if (cFilter.contains(filters[idx]))
1258 			return true;
1259 
1260 	return filters.indexOf(cFilter) != -1;
1261 }
1262 
getItems(const QString & filter,bool browse,bool reg)1263 QList<QStandardItem*> DkFileAssociationsPreference::getItems(const QString& filter, bool browse, bool reg) {
1264 
1265 	QList<QStandardItem* > items;
1266 	QStandardItem* item = new QStandardItem(filter);
1267 	item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
1268 	items.append(item);
1269 	item = new QStandardItem("");
1270 	//item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
1271 	item->setCheckable(true);
1272 	item->setCheckState(browse ? Qt::Checked : Qt::Unchecked);
1273 	items.append(item);
1274 	item = new QStandardItem("");
1275 	//item->setFlags(Qt::Qt::ItemIsSelectable | Qt::ItemIsUserCheckable);
1276 	item->setCheckable(true);
1277 	item->setCheckState(reg ? Qt::Checked : Qt::Unchecked);
1278 #ifndef Q_OS_WIN	// registering is windows only
1279 	item->setEnabled(false);
1280 #endif
1281 	items.append(item);
1282 
1283 	return items;
1284 
1285 }
1286 
writeSettings() const1287 void DkFileAssociationsPreference::writeSettings() const {
1288 
1289 	DkFileFilterHandling fh;
1290 	DkSettingsManager::param().app().browseFilters.clear();
1291 	DkSettingsManager::param().app().registerFilters.clear();
1292 
1293 	for (int idx = 0; idx < mModel->rowCount(); idx++) {
1294 
1295 		QStandardItem* item = mModel->item(idx, 0);
1296 
1297 		if (!item)
1298 			continue;
1299 
1300 		QStandardItem* browseItem = mModel->item(idx, 1);
1301 		QStandardItem* regItem = mModel->item(idx, 2);
1302 
1303 		if (browseItem && browseItem->checkState() == Qt::Checked) {
1304 
1305 			QString cFilter = item->text();
1306 			cFilter = cFilter.section(QRegExp("(\\(|\\))"), 1);
1307 			cFilter = cFilter.replace(")", "");
1308 
1309 			DkSettingsManager::param().app().browseFilters += cFilter.split(" ");
1310 		}
1311 
1312 		fh.registerFileType(item->text(), tr("Image"), regItem->checkState() == Qt::Checked);
1313 
1314 		if (regItem->checkState() == Qt::Checked) {
1315 			DkSettingsManager::param().app().registerFilters.append(item->text());
1316 			qDebug() << item->text() << " registered";
1317 		}
1318 		else
1319 			qDebug() << item->text() << " unregistered";
1320 	}
1321 
1322 	fh.registerNomacs();	// register nomacs again - to be save
1323 }
1324 
paintEvent(QPaintEvent * event)1325 void DkFileAssociationsPreference::paintEvent(QPaintEvent *event) {
1326 
1327 	// fixes stylesheets which are not applied to custom widgets
1328 	QStyleOption opt;
1329 	opt.init(this);
1330 	QPainter p(this);
1331 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
1332 
1333 	QWidget::paintEvent(event);
1334 }
1335 
1336 // DkAdvancedSettings --------------------------------------------------------------------
DkAdvancedPreference(QWidget * parent)1337 DkAdvancedPreference::DkAdvancedPreference(QWidget* parent) : DkWidget(parent) {
1338 
1339 	createLayout();
1340 	QMetaObject::connectSlotsByName(this);
1341 }
1342 
createLayout()1343 void DkAdvancedPreference::createLayout() {
1344 
1345 	// load RAW radio buttons
1346 	QVector<QRadioButton*> loadRawButtons;
1347 	loadRawButtons.resize(DkSettings::raw_thumb_end);
1348 	loadRawButtons[DkSettings::raw_thumb_always] = new QRadioButton(tr("Always Load JPG if Embedded"), this);
1349 	loadRawButtons[DkSettings::raw_thumb_if_large] = new QRadioButton(tr("Load JPG if it Fits the Screen Resolution"), this);
1350 	loadRawButtons[DkSettings::raw_thumb_never] = new QRadioButton(tr("Always Load RAW Data"), this);
1351 
1352 	// check wrt the current settings
1353 	loadRawButtons[DkSettingsManager::param().resources().loadRawThumb]->setChecked(true);
1354 
1355 	QButtonGroup* loadRawButtonGroup = new QButtonGroup(this);
1356 	loadRawButtonGroup->setObjectName("loadRaw");
1357 	loadRawButtonGroup->addButton(loadRawButtons[DkSettings::raw_thumb_always], DkSettings::raw_thumb_always);
1358 	loadRawButtonGroup->addButton(loadRawButtons[DkSettings::raw_thumb_if_large], DkSettings::raw_thumb_if_large);
1359 	loadRawButtonGroup->addButton(loadRawButtons[DkSettings::raw_thumb_never], DkSettings::raw_thumb_never);
1360 
1361 	QCheckBox* cbFilterRaw = new QCheckBox(tr("Apply Noise Filtering to RAW Images"), this);
1362 	cbFilterRaw->setObjectName("filterRaw");
1363 	cbFilterRaw->setToolTip(tr("If checked, a noise filter is applied which reduced color noise"));
1364 	cbFilterRaw->setChecked(DkSettingsManager::param().resources().filterRawImages);
1365 
1366 	DkGroupWidget* loadRawGroup = new DkGroupWidget(tr("RAW Loader Settings"), this);
1367 	loadRawGroup->addWidget(loadRawButtons[DkSettings::raw_thumb_always]);
1368 	loadRawGroup->addWidget(loadRawButtons[DkSettings::raw_thumb_if_large]);
1369 	loadRawGroup->addWidget(loadRawButtons[DkSettings::raw_thumb_never]);
1370 	loadRawGroup->addSpace();
1371 	loadRawGroup->addWidget(cbFilterRaw);
1372 
1373 	// file loading
1374 	QCheckBox* cbSaveDeleted = new QCheckBox(tr("Ask to Save Deleted Files"), this);
1375 	cbSaveDeleted->setObjectName("saveDeleted");
1376 	cbSaveDeleted->setToolTip(tr("If checked, nomacs asks to save files which were deleted by other applications"));
1377 	cbSaveDeleted->setChecked(DkSettingsManager::param().global().askToSaveDeletedFiles);
1378 
1379 	QCheckBox* cbIgnoreExif = new QCheckBox(tr("Ignore Exif Orientation when Loading"), this);
1380 	cbIgnoreExif->setObjectName("ignoreExif");
1381 	cbIgnoreExif->setToolTip(tr("If checked, images are NOT rotated with respect to their Exif orientation"));
1382 	cbIgnoreExif->setChecked(DkSettingsManager::param().metaData().ignoreExifOrientation);
1383 
1384 	QCheckBox* cbSaveExif = new QCheckBox(tr("Save Exif Orientation"), this);
1385 	cbSaveExif->setObjectName("saveExif");
1386 	cbSaveExif->setToolTip(tr("If checked, orientation is written to the Exif rather than rotating the image Matrix\n") +
1387 		tr("NOTE: this allows for rotating JPGs without losing information."));
1388 	cbSaveExif->setChecked(DkSettingsManager::param().metaData().saveExifOrientation);
1389 
1390 	DkGroupWidget* loadFileGroup = new DkGroupWidget(tr("File Loading/Saving"), this);
1391 	loadFileGroup->addWidget(cbSaveDeleted);
1392 	loadFileGroup->addWidget(cbIgnoreExif);
1393 	loadFileGroup->addWidget(cbSaveExif);
1394 
1395 	// batch processing
1396 	QSpinBox* sbNumThreads = new QSpinBox(this);
1397 	sbNumThreads->setObjectName("numThreads");
1398 	sbNumThreads->setToolTip(tr("Choose the number of Threads in the thread pool"));
1399 	sbNumThreads->setMinimum(1);
1400 	sbNumThreads->setMaximum(100);
1401 	sbNumThreads->setValue(DkSettingsManager::param().global().numThreads);
1402 
1403 	DkGroupWidget* threadsGroup = new DkGroupWidget(tr("Number of Threads"), this);
1404 	threadsGroup->addWidget(sbNumThreads);
1405 
1406 	// native dialogs
1407 	QCheckBox* cbNative = new QCheckBox(tr("Enable Native File Dialogs"), this);
1408 	cbNative->setObjectName("useNative");
1409 	cbNative->setToolTip(tr("If checked, native system dialogs are used for opening/saving files."));
1410 	cbNative->setChecked(DkSettingsManager::param().resources().nativeDialog);
1411 
1412 	DkGroupWidget* nativeGroup = new DkGroupWidget(tr("Native Dialogs"), this);
1413 	nativeGroup->addWidget(cbNative);
1414 
1415 	// log
1416 	QCheckBox* cbUseLog = new QCheckBox(tr("Use Log File"), this);
1417 	cbUseLog->setObjectName("useLog");
1418 	cbUseLog->setToolTip(tr("If checked, a log file will be created."));
1419 	cbUseLog->setChecked(DkSettingsManager::param().app().useLogFile);
1420 
1421 	QPushButton* pbLog = new QPushButton(tr("Open Log"), this);
1422 	pbLog->setObjectName("logFolder");
1423 #ifdef Q_OS_WIN
1424 	pbLog->setVisible(DkSettingsManager::param().app().useLogFile);
1425 #else
1426 	pbLog->setVisible(false);
1427 #endif
1428 
1429 	DkGroupWidget* useLogGroup = new DkGroupWidget(tr("Logging"), this);
1430 	useLogGroup->addWidget(cbUseLog);
1431 	useLogGroup->addWidget(pbLog);
1432 
1433 	QVBoxLayout* layout = new QVBoxLayout(this);
1434 	layout->setAlignment(Qt::AlignTop);
1435 	layout->addWidget(loadRawGroup);
1436 	layout->addWidget(loadFileGroup);
1437 	layout->addWidget(threadsGroup);
1438 	layout->addWidget(nativeGroup);
1439 	layout->addWidget(useLogGroup);
1440 
1441 }
1442 
on_loadRaw_buttonClicked(int buttonId) const1443 void DkAdvancedPreference::on_loadRaw_buttonClicked(int buttonId) const {
1444 
1445 	if (DkSettingsManager::param().resources().loadRawThumb != buttonId)
1446 		DkSettingsManager::param().resources().loadRawThumb = buttonId;
1447 }
1448 
on_filterRaw_toggled(bool checked) const1449 void DkAdvancedPreference::on_filterRaw_toggled(bool checked) const {
1450 
1451 	if (DkSettingsManager::param().resources().filterRawImages != checked)
1452 		DkSettingsManager::param().resources().filterRawImages = checked;
1453 }
1454 
on_saveDeleted_toggled(bool checked) const1455 void DkAdvancedPreference::on_saveDeleted_toggled(bool checked) const {
1456 
1457 	if (DkSettingsManager::param().global().askToSaveDeletedFiles != checked)
1458 		DkSettingsManager::param().global().askToSaveDeletedFiles = checked;
1459 }
1460 
on_ignoreExif_toggled(bool checked) const1461 void DkAdvancedPreference::on_ignoreExif_toggled(bool checked) const {
1462 
1463 	if (DkSettingsManager::param().metaData().ignoreExifOrientation != checked)
1464 		DkSettingsManager::param().metaData().ignoreExifOrientation = checked;
1465 }
1466 
on_saveExif_toggled(bool checked) const1467 void DkAdvancedPreference::on_saveExif_toggled(bool checked) const {
1468 
1469 	if (DkSettingsManager::param().metaData().saveExifOrientation != checked)
1470 		DkSettingsManager::param().metaData().saveExifOrientation = checked;
1471 }
1472 
on_useLog_toggled(bool checked) const1473 void DkAdvancedPreference::on_useLog_toggled(bool checked) const {
1474 
1475 	if (DkSettingsManager::param().app().useLogFile != checked) {
1476 		DkSettingsManager::param().app().useLogFile = checked;
1477 		emit infoSignal(tr("Please Restart nomacs to apply changes"));
1478 	}
1479 }
1480 
on_useNative_toggled(bool checked) const1481 void DkAdvancedPreference::on_useNative_toggled(bool checked) const {
1482 
1483 	if (DkSettingsManager::param().resources().nativeDialog != checked) {
1484 		DkSettingsManager::param().resources().nativeDialog = checked;
1485 	}
1486 }
1487 
on_logFolder_clicked() const1488 void DkAdvancedPreference::on_logFolder_clicked() const {
1489 
1490 	// TODO: add linux/mac os
1491 	QString logPath = QDir::toNativeSeparators(DkUtils::getLogFilePath());
1492 	QProcess::startDetached(QString("explorer /select, \"%1\"").arg(logPath));
1493 }
1494 
on_numThreads_valueChanged(int val) const1495 void DkAdvancedPreference::on_numThreads_valueChanged(int val) const {
1496 
1497 	if (DkSettingsManager::param().global().numThreads != val)
1498 		DkSettingsManager::param().setNumThreads(val);
1499 
1500 }
1501 
paintEvent(QPaintEvent * event)1502 void DkAdvancedPreference::paintEvent(QPaintEvent *event) {
1503 
1504 	// fixes stylesheets which are not applied to custom widgets
1505 	QStyleOption opt;
1506 	opt.init(this);
1507 	QPainter p(this);
1508 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
1509 
1510 	QWidget::paintEvent(event);
1511 }
1512 
1513 // DkEditorPreference --------------------------------------------------------------------
DkEditorPreference(QWidget * parent)1514 DkEditorPreference::DkEditorPreference(QWidget* parent) : DkWidget(parent) {
1515 
1516 	createLayout();
1517 	QMetaObject::connectSlotsByName(this);
1518 }
1519 
createLayout()1520 void DkEditorPreference::createLayout() {
1521 
1522 	mSettingsWidget = new DkSettingsWidget(this);
1523 	mSettingsWidget->setSettingsPath(DkSettingsManager::param().settingsPath());
1524 
1525 	QVBoxLayout* layout = new QVBoxLayout(this);
1526 	layout->setAlignment(Qt::AlignLeft);
1527 
1528 	layout->addWidget(mSettingsWidget);
1529 
1530 	connect(mSettingsWidget, SIGNAL(changeSettingSignal(const QString&, const QVariant&, const QStringList&)),
1531 			this, SLOT(changeSetting(const QString&, const QVariant&, const QStringList&)));
1532 	connect(mSettingsWidget, SIGNAL(removeSettingSignal(const QString&, const QStringList&)),
1533 		this, SLOT(removeSetting(const QString&, const QStringList&)));
1534 
1535 }
paintEvent(QPaintEvent * event)1536 void DkEditorPreference::paintEvent(QPaintEvent *event) {
1537 
1538 	// fixes stylesheets which are not applied to custom widgets
1539 	QStyleOption opt;
1540 	opt.init(this);
1541 	QPainter p(this);
1542 	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
1543 
1544 	QWidget::paintEvent(event);
1545 }
1546 
changeSetting(const QString & key,const QVariant & value,const QStringList & groups) const1547 void DkEditorPreference::changeSetting(const QString& key, const QVariant& value, const QStringList& groups) const {
1548 
1549 	DefaultSettings settings;
1550 	DkSettingsWidget::changeSetting(settings, key, value, groups);
1551 
1552 	// update values
1553 	nmc::DkSettingsManager::instance().param().load();
1554 }
1555 
removeSetting(const QString & key,const QStringList & groups) const1556 void DkEditorPreference::removeSetting(const QString& key, const QStringList& groups) const {
1557 
1558 	DefaultSettings settings;
1559 	DkSettingsWidget::removeSetting(settings, key, groups);
1560 }
1561 
1562 //// DkDummySettings --------------------------------------------------------------------
1563 //DkDummyPreference::DkDummyPreference(QWidget* parent) : QWidget(parent) {
1564 //
1565 //	createLayout();
1566 //	QMetaObject::connectSlotsByName(this);
1567 //}
1568 //
1569 //void DkDummyPreference::createLayout() {
1570 
1571 	//QHBoxLayout* layout = new QHBoxLayout(this);
1572 	//layout->setAlignment(Qt::AlignLeft);
1573 
1574 	//layout->addWidget(leftWidget);
1575 
1576 //}
1577 //void DkDummyPreference::paintEvent(QPaintEvent *event) {
1578 //
1579 //	// fixes stylesheets which are not applied to custom widgets
1580 //	QStyleOption opt;
1581 //	opt.init(this);
1582 //	QPainter p(this);
1583 //	style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
1584 //
1585 //	QWidget::paintEvent(event);
1586 //}
1587 
1588 }
1589