Vidalia 0.3.1
ConfigDialog.cpp
Go to the documentation of this file.
1/*
2** This file is part of Vidalia, and is subject to the license terms in the
3** LICENSE file, found in the top level directory of this distribution. If you
4** did not receive the LICENSE file with this file, you may obtain it from the
5** Vidalia source package distributed by the Vidalia Project at
6** http://www.torproject.org/projects/vidalia.html. No part of Vidalia,
7** including this file, may be copied, modified, propagated, or distributed
8** except according to the terms described in the LICENSE file.
9*/
10
11/*
12** \file ConfigDialog.cpp
13** \brief Contains a series of Vidalia and Tor configuration pages
14*/
15
16#include "ConfigDialog.h"
17#include "GeneralPage.h"
18#include "NetworkPage.h"
19#include "ServerPage.h"
20#include "AdvancedPage.h"
21#include "AppearancePage.h"
22#include "ServicePage.h"
23#include "VMessageBox.h"
24#include "ServerSettings.h"
25#include "NetworkSettings.h"
26#include "Vidalia.h"
27
28#include "html.h"
29
30
31/* Images for toolbar icons */
32#define IMAGE_GENERAL ":/images/32x32/preferences-system.png"
33#define IMAGE_NETWORK ":/images/32x32/preferences-system-network.png"
34#define IMAGE_SERVER ":/images/32x32/preferences-system-network-sharing.png"
35#define IMAGE_APPEARANCE ":/images/32x32/preferences-desktop-locale.png"
36#define IMAGE_ADVANCED ":/images/32x32/applications-system.png"
37#define IMAGE_HELP ":/images/32x32/system-help.png"
38#define IMAGE_SERVICE ":/images/32x32/services.png"
39
40
41/** Constructor */
43: VidaliaWindow("ConfigDialog", parent)
44{
45 /* Invoke the Qt Designer generated QObject setup routine */
46 ui.setupUi(this);
47
48 /* Override the QDialogButtonBox button text so we can use our own
49 * translations. */
50 QPushButton *button = ui.buttonBox->button(QDialogButtonBox::Ok);
51 if (button) {
52 Vidalia::createShortcut(QKeySequence(Qt::Key_Return),
53 this, button, SLOT(click()));
54 }
55 button = ui.buttonBox->button(QDialogButtonBox::Cancel);
56 if (button) {
57 Vidalia::createShortcut("Esc", this, button, SLOT(click()));
58 Vidalia::createShortcut("Ctrl+W", this, button, SLOT(click()));
59 }
60
61 /* Connect the button box signals to the appropriate slots */
62 connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(saveChanges()));
63 connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close()));
64 connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help()));
65 connect(Vidalia::torControl(), SIGNAL(authenticated()),
66 this, SLOT(applyChanges()));
67
68 /* Used to connect restartTor signals */
69 AdvancedPage *advancedPage;
70 /* Create the config pages and actions */
71 QActionGroup *grp = new QActionGroup(this);
72 GeneralPage *generalPage = new GeneralPage(ui.stackPages);
73 ui.stackPages->add(generalPage,
75 tr("General"), "General", grp));
76 connect(generalPage, SIGNAL(checkForUpdates()),
77 this, SLOT(onCheckForUpdates()));
78
79 ui.stackPages->add(new NetworkPage(ui.stackPages),
81 tr("Network"), "Network", grp));
82
83 ui.stackPages->add(new ServerPage(ui.stackPages),
85 tr("Sharing"), "Sharing", grp));
86
87 ui.stackPages->add(new ServicePage(ui.stackPages),
89 tr("Services"), "Services", grp));
90
91 ui.stackPages->add(new AppearancePage(ui.stackPages),
93 tr("Appearance"), "Appearance", grp));
94
95 ui.stackPages->add(advancedPage = new AdvancedPage(ui.stackPages),
97 tr("Advanced"), "Advanced", grp));
98
99 connect(advancedPage, SIGNAL(restartTor()), this, SIGNAL(restartTor()));
100
101 foreach (ConfigPage *page, ui.stackPages->pages()) {
102 connect(page, SIGNAL(helpRequested(QString)),
103 this, SLOT(help(QString)));
104 }
105
106 /* Create the toolbar */
107 ui.toolBar->addActions(grp->actions());
108 ui.toolBar->addSeparator();
109 connect(grp, SIGNAL(triggered(QAction *)),
110 ui.stackPages, SLOT(showPage(QAction *)));
111
112 /* Create and bind the Help button */
113 QAction *helpAct = new QAction(QIcon(IMAGE_HELP), tr("Help"), ui.toolBar);
114 helpAct->setData("Help");
115 addAction(helpAct, SLOT(help()));
116
117 /* Select the first action */
118 grp->actions()[0]->setChecked(true);
119
120#if defined(Q_WS_WIN)
121 helpAct->setShortcut(QString("F1"));
122#else
123 helpAct->setShortcut(QString("Ctrl+?"));
124#endif
125}
126
127/** Creates a new action associated with a config page. */
128QAction*
129ConfigDialog::createPageAction(const QIcon &img, const QString &text,
130 const QString &data, QActionGroup *group)
131{
132 QAction *action = new QAction(img, text, group);
133 action->setData(data);
134 action->setCheckable(true);
135 return action;
136}
137
138/** Adds the given action to the toolbar and hooks its triggered() signal to
139 * the specified slot (if given). */
140void
141ConfigDialog::addAction(QAction *action, const char *slot)
142{
143 ui.toolBar->addAction(action);
144 connect(action, SIGNAL(triggered()), this, slot);
145}
146
147/** Shows the config dialog with focus set to the given page. */
148void
150{
151 /* Load saved settings */
152 loadSettings();
153 /* Show the dialog. */
155 /* Set the focus to the specified page. */
156 ui.stackPages->setCurrentIndex((int)page);
157}
158
159/** Called when the user changes the UI translation. */
160void
162{
163 ui.retranslateUi(this);
164 foreach (ConfigPage *page, ui.stackPages->pages()) {
165 page->retranslateUi();
166 }
167 foreach (QAction *action, ui.toolBar->actions()) {
168 action->setText(tr(qPrintable(action->data().toString()), "ConfigDialog"));
169 }
170 ui.buttonBox->setStandardButtons(ui.buttonBox->standardButtons());
171}
172
173/** Loads the saved ConfigDialog settings. */
174void
176{
177 /* Call each config page's load() method to load its data */
178 foreach (ConfigPage *page, ui.stackPages->pages()) {
179 page->load();
180 }
181}
182
183/** Saves changes made to settings. If Tor is running and Vidalia is
184 * connected, we will also attempt to apply the changes to Tor. */
185void
187{
188 QString errmsg;
189
190 /* Call each config page's save() method to save its data */
191 foreach (ConfigPage *page, ui.stackPages->pages()) {
192 if (!page->save(errmsg)) {
193 /* Display the offending page */
194 ui.stackPages->setCurrentPage(page);
195
196 /* Show the user what went wrong */
198 tr("Error Saving Settings"),
199 p(tr("Vidalia was unable to save your %1 settings.")
200 .arg(tr(qPrintable(page->title()), "ConfigDialog"))) + p(errmsg),
202
203 /* Don't process the rest of the pages */
204 return;
205 }
206 }
208 applyChanges();
209 else
210 close();
211}
212
213/** Called after Vidalia has authenticated to Tor and applies any changes
214 * made since the last time they were applied. */
215void
217{
218 QString errmsg;
219 bool appliedChanges = false;
220
221 foreach (ConfigPage *page, ui.stackPages->pages()) {
222 if (!page->changedSinceLastApply())
223 continue;
224 if (!page->apply(errmsg)) {
225 /* Failed to apply the changes to Tor */
226 int ret = VMessageBox::warning(this,
227 tr("Error Applying Settings"),
228 p(tr("Vidalia was unable to apply your %1 settings "
229 "to Tor.").arg(page->title()))
230 + p(errmsg),
231 VMessageBox::ShowSettings|VMessageBox::Default,
232 VMessageBox::Cancel|VMessageBox::Escape);
233 if (ret == VMessageBox::ShowSettings) {
234 /* Show the user the page with the bad settings */
235 showWindow();
236 ui.stackPages->setCurrentPage(page);
237 } else {
238 /* The user clicked 'Cancel', so revert the failed settings */
239 page->revert();
240 close();
241 }
242 return;
243 }
244 appliedChanges = true;
245 }
246 if (appliedChanges)
247 saveConf();
248 close();
249}
250
251/** Sends Tor a SAVECONF to write its configuration to disk. If the SAVECONF
252 * is successful, then all settings are considered to be applied. */
253void
255{
257 if (tc->saveConf()) {
260 TorSettings(tc).setChanged(false);
261 }
262}
263
264/** Shows help information for whichever settings page the user is currently
265 * viewing. */
266void
268{
269 Page currentPage = static_cast<Page>(ui.stackPages->currentIndex());
270
271 switch (currentPage) {
272 case Network:
273 help("config.network"); break;
274 case Server:
275 help("server"); break;
276 case Appearance:
277 help("config.appearance"); break;
278 case Advanced:
279 help("config.advanced"); break;
280 case Service:
281 help("config.services"); break;
282 default:
283 help("config.general"); break;
284 }
285}
286
287/** Stub method that relays the checkForUpdates() signal from the General
288 * settings page to the owner of the config dialog (MainWindow). */
289void
291{
292 emit checkForUpdates();
293}
294
295
296/** Called when a ConfigPage in the dialog requests help on a specific
297 * <b>topic</b>. */
298void
299ConfigDialog::help(const QString &topic)
300{
301 emit helpRequested(topic);
302}
303
#define IMAGE_NETWORK
#define IMAGE_SERVER
#define IMAGE_GENERAL
#define IMAGE_APPEARANCE
#define IMAGE_SERVICE
#define IMAGE_HELP
#define IMAGE_ADVANCED
stop errmsg connect(const QHostAddress &address, quint16 port)
stop errmsg isConnected()
void setChanged(bool changed)
void checkForUpdates()
void applyChanges()
void addAction(QAction *action, const char *slot=0)
QAction * createPageAction(const QIcon &img, const QString &text, const QString &data, QActionGroup *group)
void loadSettings()
void restartTor()
void onCheckForUpdates()
void saveChanges()
Ui::ConfigDialog ui
Definition: ConfigDialog.h:90
ConfigDialog(QWidget *parent=0)
virtual void retranslateUi()
QString title() const
Definition: ConfigPage.h:32
virtual void retranslateUi()
Definition: ConfigPage.h:58
virtual void revert()
Definition: ConfigPage.h:56
virtual bool changedSinceLastApply()
Definition: ConfigPage.h:43
virtual bool save(QString &errmsg)=0
virtual bool apply(QString &errmsg)
Definition: ConfigPage.h:50
virtual void load()=0
static int warning(QWidget *parent, QString caption, QString text, int button0, int button1=NoButton, int button2=NoButton)
static void createShortcut(const QKeySequence &key, QWidget *sender, QObject *receiver, const char *slot)
Definition: Vidalia.cpp:402
static TorControl * torControl()
Definition: Vidalia.h:76
virtual void showWindow()
Definition: VidaliaWindow.h:64
void helpRequested(const QString &topic)
QString p(QString str)
Definition: html.cpp:22
Definition: tcglobal.cpp:19