1 /***************************************************************************
2                           rksettings  -  description
3                              -------------------
4     begin                : Wed Jul 28 2004
5     copyright            : (C) 2004-2018 by Thomas Friedrichsmeier
6     email                : thomas.friedrichsmeier@kdemail.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 #include "rksettings.h"
18 
19 #include <QPushButton>
20 
21 #include <KLocalizedString>
22 #include <KSharedConfig>
23 
24 #include "../windows/rkworkplace.h"
25 
26 // modules
27 #include "rksettingsmoduleplugins.h"
28 #include "rksettingsmoduler.h"
29 #include "rksettingsmodulegeneral.h"
30 #include "rksettingsmoduleoutput.h"
31 #include "rksettingsmodulegraphics.h"
32 #include "rksettingsmodulewatch.h"
33 #include "rksettingsmoduleobjectbrowser.h"
34 #include "rksettingsmoduleconsole.h"
35 #include "rksettingsmodulecommandeditor.h"
36 #include "rksettingsmoduledebug.h"
37 
38 #include "../debug.h"
39 
40 //static
41 RKSettings *RKSettings::settings_dialog = 0;
42 RKSettingsTracker *RKSettings::settings_tracker = 0;
43 
44 //static
configureSettings(SettingsPage page,QWidget * parent,RCommandChain * chain)45 void RKSettings::configureSettings (SettingsPage page, QWidget *parent, RCommandChain *chain) {
46 	RK_TRACE (SETTINGS);
47 
48 	RKSettingsModule::chain = chain;
49 
50 	if (!settings_dialog) {
51 		settings_dialog = new RKSettings (parent);
52 	}
53 
54 	settings_dialog->raisePage (page);
55 	settings_dialog->show ();
56 	settings_dialog->raise ();
57 }
58 
59 //static
dialogClosed()60 void RKSettings::dialogClosed () {
61 	RK_TRACE (SETTINGS);
62 	settings_dialog = 0;
63 }
64 
RKSettings(QWidget * parent)65 RKSettings::RKSettings (QWidget *parent) : KPageDialog (parent) {
66 	RK_TRACE (SETTINGS);
67 
68 	setFaceType (KPageDialog::Tree);
69 	setWindowTitle (i18n ("Settings"));
70 	buttonBox ()->setStandardButtons (QDialogButtonBox::Ok | QDialogButtonBox::Apply | QDialogButtonBox::Cancel | QDialogButtonBox::Help);
71 	// KF5 TODO: connect buttons
72 	button (QDialogButtonBox::Apply)->setEnabled (false);
73 	connect (button(QDialogButtonBox::Apply), &QPushButton::clicked, this, &RKSettings::applyAll);
74 	connect (button(QDialogButtonBox::Help), &QPushButton::clicked, this, &RKSettings::helpClicked);
75 
76 	setAttribute (Qt::WA_DeleteOnClose, true);
77 
78 	initModules ();
79 
80 	connect (this, &KPageDialog::currentPageChanged, this, &RKSettings::pageChange);
81 	pageChange (currentPage (), currentPage ());	// init
82 }
83 
~RKSettings()84 RKSettings::~RKSettings() {
85 	RK_TRACE (SETTINGS);
86 
87 	ModuleMap::const_iterator it;
88 	for (it = modules.constBegin (); it != modules.constEnd (); ++it) {
89 		delete *it;
90 	}
91 	modules.clear ();
92 
93 	dialogClosed ();
94 }
95 
initModules()96 void RKSettings::initModules () {
97 	RK_TRACE (SETTINGS);
98 
99 	modules.insert (PagePlugins, new RKSettingsModulePlugins (this, 0));
100 	modules.insert (PageR, new RKSettingsModuleR (this, 0));
101 	modules.insert (PageRPackages, new RKSettingsModuleRPackages (this, 0));
102 	modules.insert (PageGeneral, new RKSettingsModuleGeneral (this, 0));
103 	modules.insert (PageOutput, new RKSettingsModuleOutput (this, 0));
104 	modules.insert (PageX11, new RKSettingsModuleGraphics (this, 0));
105 	modules.insert (PageWatch, new RKSettingsModuleWatch (this, 0));
106 	modules.insert (PageConsole, new RKSettingsModuleConsole (this, 0));
107 	modules.insert (PageCommandEditor, new RKSettingsModuleCommandEditor (this, 0));
108 	modules.insert (PageObjectBrowser, new RKSettingsModuleObjectBrowser (this, 0));
109 	modules.insert (PageDebug, new RKSettingsModuleDebug (this, 0));
110 
111 	ModuleMap::const_iterator it;
112 	for (it = modules.constBegin (); it != modules.constEnd (); ++it) {
113 		pages[it.key ()-1] = addPage (it.value (), it.value ()->caption ());
114 	}
115 }
116 
raisePage(SettingsPage page)117 void RKSettings::raisePage (SettingsPage page) {
118 	RK_TRACE (SETTINGS);
119 
120 	if (page != NoPage) {
121 		setCurrentPage (pages[(int) page - 1]);
122 	}
123 }
124 
pageChange(KPageWidgetItem * current,KPageWidgetItem *)125 void RKSettings::pageChange (KPageWidgetItem *current, KPageWidgetItem *) {
126 	RK_TRACE (SETTINGS);
127 	RKSettingsModule *new_module = dynamic_cast<RKSettingsModule*> (current->widget ());
128 
129 	bool has_help;
130 	if (!new_module) {
131 		RK_ASSERT (false);
132 		has_help = false;
133 	} else {
134 		has_help = !(new_module->helpURL ().isEmpty ());
135 	}
136 	button (QDialogButtonBox::Help)->setEnabled (has_help);
137 }
138 
done(int result)139 void RKSettings::done (int result) {
140 	RK_TRACE (SETTINGS);
141 
142 	if (result == Accepted) applyAll ();
143 	QDialog::done (result);
144 }
145 
helpClicked()146 void RKSettings::helpClicked () {
147 	RK_TRACE (SETTINGS);
148 
149 	RKSettingsModule *current_module = dynamic_cast<RKSettingsModule*> (currentPage ()->widget ());
150 	if (!current_module) {
151 		RK_ASSERT (false);
152 		return;
153 	}
154 
155 	RKWorkplace::mainWorkplace ()->openHelpWindow (current_module->helpURL ());
156 }
157 
applyAll()158 void RKSettings::applyAll () {
159 	RK_TRACE (SETTINGS);
160 
161 	ModuleMap::const_iterator it;
162 	for (it = modules.constBegin (); it != modules.constEnd (); ++it) {
163 		if (it.value ()->hasChanges ()) {
164 			it.value ()->applyChanges ();
165 			it.value ()->changed = false;
166 			it.value ()->save (KSharedConfig::openConfig ().data ());
167 			tracker ()->signalSettingsChange (it.key ());
168 		}
169 	}
170 	button (QDialogButtonBox::Apply)->setEnabled (false);
171 }
172 
enableApply()173 void RKSettings::enableApply () {
174 	RK_TRACE (SETTINGS);
175 	button (QDialogButtonBox::Apply)->setEnabled (true);
176 }
177 
178 #define FOREACH_SETTINGS_MODULE(X)           \
179 	RKSettingsModuleGeneral::X;  /* always handle this first (esp., when loading settings), as it contains the base path for rkward files */ \
180 	RKSettingsModulePlugins::X;          \
181 	RKSettingsModuleR::X;                \
182 	RKSettingsModuleRPackages::X;        \
183 	RKSettingsModuleOutput::X;           \
184 	RKSettingsModuleGraphics::X;         \
185 	RKSettingsModuleWatch::X;            \
186 	RKSettingsModuleConsole::X;          \
187 	RKSettingsModuleCommandEditor::X;    \
188 	RKSettingsModuleObjectBrowser::X;
189 
loadSettings(KConfig * config)190 void RKSettings::loadSettings (KConfig *config) {
191 	RK_TRACE (SETTINGS);
192 
193 	FOREACH_SETTINGS_MODULE(loadSettings(config));
194 }
195 
saveSettings(KConfig * config)196 void RKSettings::saveSettings (KConfig *config) {
197 	RK_TRACE (SETTINGS);
198 
199 	FOREACH_SETTINGS_MODULE(saveSettings(config));
200 }
201 
202 #include <KAssistantDialog>
validateSettingsInteractive()203 void RKSettings::validateSettingsInteractive () {
204 	RK_TRACE (SETTINGS);
205 
206 	QList<RKSettingsWizardPage*> interaction_pages;
207 	FOREACH_SETTINGS_MODULE(validateSettingsInteractive(&interaction_pages));
208 	if (!interaction_pages.isEmpty ()) {
209 		KAssistantDialog dialog ((QWidget*) 0);
210 		for (int i = 0; i < interaction_pages.size (); ++i) {
211 			dialog.addPage (interaction_pages[i], interaction_pages[i]->windowTitle ());
212 		}
213 		QPushButton *help_button = dialog.button (QDialogButtonBox::Help);
214 		if (help_button) help_button->hide ();
215 		if (dialog.exec () == QDialog::Accepted) {
216 			for (int i = 0; i < interaction_pages.size (); ++i) {
217 				interaction_pages[i]->apply ();
218 			}
219 		}
220 	}
221 }
222 
223 //############ END RKSettings ##################
224 //############ BEGIN RKSettingsTracker ############
225 
RKSettingsTracker(QObject * parent)226 RKSettingsTracker::RKSettingsTracker (QObject *parent) : QObject (parent) {
227 	RK_TRACE (SETTINGS);
228 }
229 
~RKSettingsTracker()230 RKSettingsTracker::~RKSettingsTracker () {
231 	RK_TRACE (SETTINGS);
232 }
233 
signalSettingsChange(RKSettings::SettingsPage page)234 void RKSettingsTracker::signalSettingsChange (RKSettings::SettingsPage page) {
235 	RK_TRACE (SETTINGS);
236 	emit (settingsChanged (page));
237 }
238 
239