Vidalia 0.2.10
|
00001 /* 00002 ** This file is part of Vidalia, and is subject to the license terms in the 00003 ** LICENSE file, found in the top level directory of this distribution. If you 00004 ** did not receive the LICENSE file with this file, you may obtain it from the 00005 ** Vidalia source package distributed by the Vidalia Project at 00006 ** http://www.vidalia-project.net/. No part of Vidalia, including this file, 00007 ** may be copied, modified, propagated, or distributed except according to the 00008 ** terms described in the LICENSE file. 00009 */ 00010 00011 /* 00012 ** \file ConfigDialog.cpp 00013 ** \version $Id: ConfigDialog.cpp 3735 2009-04-28 20:28:01Z edmanm $ 00014 ** \brief Contains a series of Vidalia and Tor configuration pages 00015 */ 00016 00017 #include "ConfigDialog.h" 00018 #include "GeneralPage.h" 00019 #include "NetworkPage.h" 00020 #include "ServerPage.h" 00021 #include "AdvancedPage.h" 00022 #include "AppearancePage.h" 00023 #include "ServicePage.h" 00024 #include "VMessageBox.h" 00025 #include "ServerSettings.h" 00026 #include "NetworkSettings.h" 00027 #include "Vidalia.h" 00028 00029 #include "html.h" 00030 00031 00032 /* Images for toolbar icons */ 00033 #define IMAGE_GENERAL ":/images/32x32/preferences-system.png" 00034 #define IMAGE_NETWORK ":/images/32x32/preferences-system-network.png" 00035 #define IMAGE_SERVER ":/images/32x32/preferences-system-network-sharing.png" 00036 #define IMAGE_APPEARANCE ":/images/32x32/preferences-desktop-locale.png" 00037 #define IMAGE_ADVANCED ":/images/32x32/applications-system.png" 00038 #define IMAGE_HELP ":/images/32x32/system-help.png" 00039 #define IMAGE_SERVICE ":/images/32x32/services.png" 00040 00041 00042 /** Constructor */ 00043 ConfigDialog::ConfigDialog(QWidget* parent) 00044 : VidaliaWindow("ConfigDialog", parent) 00045 { 00046 /* Invoke the Qt Designer generated QObject setup routine */ 00047 ui.setupUi(this); 00048 00049 /* Override the QDialogButtonBox button text so we can use our own 00050 * translations. */ 00051 QPushButton *button = ui.buttonBox->button(QDialogButtonBox::Ok); 00052 if (button) { 00053 Vidalia::createShortcut(QKeySequence(Qt::Key_Return), 00054 this, button, SLOT(click())); 00055 } 00056 button = ui.buttonBox->button(QDialogButtonBox::Cancel); 00057 if (button) { 00058 Vidalia::createShortcut("Esc", this, button, SLOT(click())); 00059 Vidalia::createShortcut("Ctrl+W", this, button, SLOT(click())); 00060 } 00061 00062 /* Connect the button box signals to the appropriate slots */ 00063 connect(ui.buttonBox, SIGNAL(accepted()), this, SLOT(saveChanges())); 00064 connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(close())); 00065 connect(ui.buttonBox, SIGNAL(helpRequested()), this, SLOT(help())); 00066 connect(Vidalia::torControl(), SIGNAL(authenticated()), 00067 this, SLOT(applyChanges())); 00068 00069 /* Create the config pages and actions */ 00070 QActionGroup *grp = new QActionGroup(this); 00071 GeneralPage *generalPage = new GeneralPage(ui.stackPages); 00072 ui.stackPages->add(generalPage, 00073 createPageAction(QIcon(IMAGE_GENERAL), 00074 tr("General"), "General", grp)); 00075 connect(generalPage, SIGNAL(checkForUpdates()), 00076 this, SLOT(onCheckForUpdates())); 00077 00078 ui.stackPages->add(new NetworkPage(ui.stackPages), 00079 createPageAction(QIcon(IMAGE_NETWORK), 00080 tr("Network"), "Network", grp)); 00081 00082 ui.stackPages->add(new ServerPage(ui.stackPages), 00083 createPageAction(QIcon(IMAGE_SERVER), 00084 tr("Sharing"), "Sharing", grp)); 00085 00086 ui.stackPages->add(new ServicePage(ui.stackPages), 00087 createPageAction(QIcon(IMAGE_SERVICE), 00088 tr("Services"), "Services", grp)); 00089 00090 ui.stackPages->add(new AppearancePage(ui.stackPages), 00091 createPageAction(QIcon(IMAGE_APPEARANCE), 00092 tr("Appearance"), "Appearance", grp)); 00093 00094 ui.stackPages->add(new AdvancedPage(ui.stackPages), 00095 createPageAction(QIcon(IMAGE_ADVANCED), 00096 tr("Advanced"), "Advanced", grp)); 00097 00098 foreach (ConfigPage *page, ui.stackPages->pages()) { 00099 connect(page, SIGNAL(helpRequested(QString)), 00100 this, SLOT(help(QString))); 00101 } 00102 00103 /* Create the toolbar */ 00104 ui.toolBar->addActions(grp->actions()); 00105 ui.toolBar->addSeparator(); 00106 connect(grp, SIGNAL(triggered(QAction *)), 00107 ui.stackPages, SLOT(showPage(QAction *))); 00108 00109 /* Create and bind the Help button */ 00110 QAction *helpAct = new QAction(QIcon(IMAGE_HELP), tr("Help"), ui.toolBar); 00111 helpAct->setData("Help"); 00112 addAction(helpAct, SLOT(help())); 00113 00114 /* Select the first action */ 00115 grp->actions()[0]->setChecked(true); 00116 00117 #if defined(Q_WS_WIN) 00118 helpAct->setShortcut(QString("F1")); 00119 #else 00120 helpAct->setShortcut(QString("Ctrl+?")); 00121 #endif 00122 } 00123 00124 /** Creates a new action associated with a config page. */ 00125 QAction* 00126 ConfigDialog::createPageAction(const QIcon &img, const QString &text, 00127 const QString &data, QActionGroup *group) 00128 { 00129 QAction *action = new QAction(img, text, group); 00130 action->setData(data); 00131 action->setCheckable(true); 00132 return action; 00133 } 00134 00135 /** Adds the given action to the toolbar and hooks its triggered() signal to 00136 * the specified slot (if given). */ 00137 void 00138 ConfigDialog::addAction(QAction *action, const char *slot) 00139 { 00140 ui.toolBar->addAction(action); 00141 connect(action, SIGNAL(triggered()), this, slot); 00142 } 00143 00144 /** Shows the config dialog with focus set to the given page. */ 00145 void 00146 ConfigDialog::showWindow(Page page) 00147 { 00148 /* Load saved settings */ 00149 loadSettings(); 00150 /* Show the dialog. */ 00151 VidaliaWindow::showWindow(); 00152 /* Set the focus to the specified page. */ 00153 ui.stackPages->setCurrentIndex((int)page); 00154 } 00155 00156 /** Called when the user changes the UI translation. */ 00157 void 00158 ConfigDialog::retranslateUi() 00159 { 00160 ui.retranslateUi(this); 00161 foreach (ConfigPage *page, ui.stackPages->pages()) { 00162 page->retranslateUi(); 00163 } 00164 foreach (QAction *action, ui.toolBar->actions()) { 00165 action->setText(tr(qPrintable(action->data().toString()), "ConfigDialog")); 00166 } 00167 ui.buttonBox->setStandardButtons(ui.buttonBox->standardButtons()); 00168 } 00169 00170 /** Loads the saved ConfigDialog settings. */ 00171 void 00172 ConfigDialog::loadSettings() 00173 { 00174 /* Call each config page's load() method to load its data */ 00175 foreach (ConfigPage *page, ui.stackPages->pages()) { 00176 page->load(); 00177 } 00178 } 00179 00180 /** Saves changes made to settings. If Tor is running and Vidalia is 00181 * connected, we will also attempt to apply the changes to Tor. */ 00182 void 00183 ConfigDialog::saveChanges() 00184 { 00185 QString errmsg; 00186 00187 /* Call each config page's save() method to save its data */ 00188 foreach (ConfigPage *page, ui.stackPages->pages()) { 00189 if (!page->save(errmsg)) { 00190 /* Display the offending page */ 00191 ui.stackPages->setCurrentPage(page); 00192 00193 /* Show the user what went wrong */ 00194 VMessageBox::warning(this, 00195 tr("Error Saving Settings"), 00196 p(tr("Vidalia was unable to save your %1 settings.") 00197 .arg(tr(qPrintable(page->title()), "ConfigDialog"))) + p(errmsg), 00198 VMessageBox::Ok); 00199 00200 /* Don't process the rest of the pages */ 00201 return; 00202 } 00203 } 00204 if (Vidalia::torControl()->isConnected()) 00205 applyChanges(); 00206 else 00207 close(); 00208 } 00209 00210 /** Called after Vidalia has authenticated to Tor and applies any changes 00211 * made since the last time they were applied. */ 00212 void 00213 ConfigDialog::applyChanges() 00214 { 00215 QString errmsg; 00216 bool appliedChanges = false; 00217 00218 foreach (ConfigPage *page, ui.stackPages->pages()) { 00219 if (!page->changedSinceLastApply()) 00220 continue; 00221 if (!page->apply(errmsg)) { 00222 /* Failed to apply the changes to Tor */ 00223 int ret = VMessageBox::warning(this, 00224 tr("Error Applying Settings"), 00225 p(tr("Vidalia was unable to apply your %1 settings " 00226 "to Tor.").arg(page->title())) 00227 + p(errmsg), 00228 VMessageBox::ShowSettings|VMessageBox::Default, 00229 VMessageBox::Cancel|VMessageBox::Escape); 00230 if (ret == VMessageBox::ShowSettings) { 00231 /* Show the user the page with the bad settings */ 00232 showWindow(); 00233 ui.stackPages->setCurrentPage(page); 00234 } else { 00235 /* The user clicked 'Cancel', so revert the failed settings */ 00236 page->revert(); 00237 close(); 00238 } 00239 return; 00240 } 00241 appliedChanges = true; 00242 } 00243 if (appliedChanges) 00244 saveConf(); 00245 close(); 00246 } 00247 00248 /** Sends Tor a SAVECONF to write its configuration to disk. If the SAVECONF 00249 * is successful, then all settings are considered to be applied. */ 00250 void 00251 ConfigDialog::saveConf() 00252 { 00253 TorControl *tc = Vidalia::torControl(); 00254 if (tc->saveConf()) { 00255 ServerSettings(tc).setChanged(false); 00256 NetworkSettings(tc).setChanged(false); 00257 TorSettings(tc).setChanged(false); 00258 } 00259 } 00260 00261 /** Shows help information for whichever settings page the user is currently 00262 * viewing. */ 00263 void 00264 ConfigDialog::help() 00265 { 00266 Page currentPage = static_cast<Page>(ui.stackPages->currentIndex()); 00267 00268 switch (currentPage) { 00269 case Network: 00270 help("config.network"); break; 00271 case Server: 00272 help("server"); break; 00273 case Appearance: 00274 help("config.appearance"); break; 00275 case Advanced: 00276 help("config.advanced"); break; 00277 case Service: 00278 help("config.services"); break; 00279 default: 00280 help("config.general"); break; 00281 } 00282 } 00283 00284 /** Stub method that relays the checkForUpdates() signal from the General 00285 * settings page to the owner of the config dialog (MainWindow). */ 00286 void 00287 ConfigDialog::onCheckForUpdates() 00288 { 00289 emit checkForUpdates(); 00290 } 00291 00292 00293 /** Called when a ConfigPage in the dialog requests help on a specific 00294 * <b>topic</b>. */ 00295 void 00296 ConfigDialog::help(const QString &topic) 00297 { 00298 emit helpRequested(topic); 00299 } 00300