00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include <QtGui>
00033 #include <vidalia.h>
00034 #include <util/html.h>
00035
00036 #include "common/vmessagebox.h"
00037 #include "mainwindow.h"
00038
00039 #define IMG_APP_ICON ":/images/16x16/tor-logo.png"
00040 #define IMG_START ":/images/16x16/tor-on.png"
00041 #define IMG_STOP ":/images/16x16/tor-off.png"
00042 #define IMG_BWGRAPH ":/images/16x16/utilities-system-monitor.png"
00043 #define IMG_MESSAGELOG ":/images/16x16/format-justify-fill.png"
00044 #define IMG_CONFIG ":/images/16x16/preferences-system.png"
00045 #define IMG_IDENTITY ":/images/16x16/system-users.png"
00046 #define IMG_HELP ":/images/16x16/help-browser.png"
00047 #define IMG_ABOUT ":/images/16x16/tor-logo.png"
00048 #define IMG_EXIT ":/images/16x16/emblem-unreadable.png"
00049 #define IMG_NETWORK ":/images/16x16/applications-internet.png"
00050
00051 #if defined(Q_WS_MAC)
00052
00053 #define IMG_TOR_STOPPED "tor-off"
00054 #define IMG_TOR_RUNNING "tor-on"
00055 #define IMG_TOR_STARTING "tor-starting"
00056 #define IMG_TOR_STOPPING "tor-stopping"
00057 #elif defined(Q_WS_X11)
00058
00059 #define IMG_TOR_STOPPED ":/images/22x22/tor-off.png"
00060 #define IMG_TOR_RUNNING ":/images/22x22/tor-on.png"
00061 #define IMG_TOR_STARTING ":/images/22x22/tor-starting.png"
00062 #define IMG_TOR_STOPPING ":/images/22x22/tor-stopping.png"
00063 #else
00064
00065 #include "res/vidalia_win.rc.h"
00066 #define IMG_TOR_STOPPED QString::number(IDI_TOR_OFF)
00067 #define IMG_TOR_RUNNING QString::number(IDI_TOR_ON)
00068 #define IMG_TOR_STARTING QString::number(IDI_TOR_STARTING)
00069 #define IMG_TOR_STOPPING QString::number(IDI_TOR_STOPPING)
00070 #endif
00071
00072
00073
00074
00075 MainWindow::MainWindow()
00076 {
00077 VidaliaSettings settings;
00078
00079
00080 setWindowIcon(QIcon(IMG_APP_ICON));
00081
00082
00083 createActions();
00084
00085 #if defined(Q_WS_MAC)
00086 createMenuBar();
00087 #else
00088
00089 createTrayMenu();
00090 #endif
00091
00092
00093 _torControl = Vidalia::torControl();
00094 connect(_torControl, SIGNAL(started()), this, SLOT(started()));
00095 connect(_torControl, SIGNAL(startFailed(QString)),
00096 this, SLOT(startFailed(QString)));
00097 connect(_torControl, SIGNAL(stopped(int, QProcess::ExitStatus)),
00098 this, SLOT(stopped(int, QProcess::ExitStatus)));
00099 connect(_torControl, SIGNAL(connected()), this, SLOT(connected()));
00100 connect(_torControl, SIGNAL(disconnected()), this, SLOT(disconnected()));
00101 connect(_torControl, SIGNAL(connectFailed(QString)),
00102 this, SLOT(connectFailed(QString)));
00103
00104
00105 _messageLog = new MessageLog();
00106
00107
00108 _bandwidthGraph = new BandwidthGraph(this);
00109
00110
00111 _netViewer = new NetViewer();
00112
00113
00114 _trayIcon = new TrayIcon(IMG_TOR_STOPPED,
00115 tr("Tor is Stopped"), _trayMenu);
00116 _trayIcon->show();
00117
00118 if (_torControl->isRunning()) {
00119
00120 this->started();
00121 } else if (settings.runTorAtStart()) {
00122
00123 start();
00124 }
00125 }
00126
00127
00128 MainWindow::~MainWindow()
00129 {
00130 _trayIcon->hide();
00131 delete _trayIcon;
00132 delete _messageLog;
00133 delete _netViewer;
00134 }
00135
00136
00137
00138
00139 void
00140 MainWindow::close()
00141 {
00142
00143 disconnect(_torControl, 0, 0, 0);
00144
00145
00146 if (_torControl->isConnected()) {
00147 _torControl->disconnect();
00148 }
00149
00150
00151 if (_torControl->isVidaliaRunningTor()) {
00152 _torControl->stop();
00153 }
00154
00155
00156 QCoreApplication::quit();
00157 }
00158
00159
00160
00161 void
00162 MainWindow::createActions()
00163 {
00164 _startAct = new QAction(QIcon(IMG_START), tr("Start"), this);
00165 connect(_startAct, SIGNAL(triggered()), this, SLOT(start()));
00166 _startAct->setEnabled(true);
00167
00168 _stopAct = new QAction(QIcon(IMG_STOP), tr("Stop"), this);
00169 connect(_stopAct, SIGNAL(triggered()), this, SLOT(stop()));
00170 _stopAct->setEnabled(false);
00171
00172 _configAct = new QAction(QIcon(IMG_CONFIG), tr("Settings"), this);
00173 connect(_configAct, SIGNAL(triggered()), this, SLOT(showConfig()));
00174
00175 _aboutAct = new QAction(QIcon(IMG_ABOUT), tr("About"), this);
00176 connect(_aboutAct, SIGNAL(triggered()), this, SLOT(showAbout()));
00177
00178 _exitAct = new QAction(QIcon(IMG_EXIT), tr("Exit"), this);
00179 connect(_exitAct, SIGNAL(triggered()), this, SLOT(close()));
00180
00181 _bandwidthAct = new QAction(QIcon(IMG_BWGRAPH), tr("Bandwidth Graph"), this);
00182 connect(_bandwidthAct, SIGNAL(triggered()), this, SLOT(showBandwidthGraph()));
00183
00184 _messageAct = new QAction(QIcon(IMG_MESSAGELOG), tr("Message Log"), this);
00185 connect(_messageAct, SIGNAL(triggered()), this, SLOT(showMessageLog()));
00186
00187 _helpAct = new QAction(QIcon(IMG_HELP), tr("Help"), this);
00188 connect(_helpAct, SIGNAL(triggered()), this, SLOT(showHelp()));
00189
00190 _networkAct = new QAction(QIcon(IMG_NETWORK), tr("Network Map"), this);
00191 connect(_networkAct, SIGNAL(triggered()), this, SLOT(showNetwork()));
00192
00193 _newIdentityAct = new QAction(QIcon(IMG_IDENTITY), tr("New Identity"), this);
00194 _newIdentityAct->setEnabled(false);
00195 connect(_newIdentityAct, SIGNAL(triggered()), this, SLOT(newIdentity()));
00196 }
00197
00198
00199
00200
00201
00202 void
00203 MainWindow::createTrayMenu()
00204 {
00205
00206 _trayMenu = new QMenu(this);
00207 _trayMenu->addAction(_startAct);
00208 _trayMenu->addAction(_stopAct);
00209 _trayMenu->addSeparator();
00210 _trayMenu->addAction(_bandwidthAct);
00211 _trayMenu->addAction(_messageAct);
00212 _trayMenu->addAction(_networkAct);
00213 _trayMenu->addAction(_newIdentityAct);
00214 _trayMenu->addSeparator();
00215 _trayMenu->addAction(_configAct);
00216 _trayMenu->addAction(_helpAct);
00217 _trayMenu->addAction(_aboutAct);
00218 _trayMenu->addSeparator();
00219 _trayMenu->addAction(_exitAct);
00220 }
00221
00222
00223
00224
00225 void
00226 MainWindow::createMenuBar()
00227 {
00228 #if defined(Q_WS_MAC)
00229
00230
00231
00232 _startAct->setShortcut(tr("Ctrl+S"));
00233 _stopAct->setShortcut(tr("Ctrl+T"));
00234 _bandwidthAct->setShortcut(tr("Ctrl+B"));
00235 _messageAct->setShortcut(tr("Ctrl+L"));
00236 _networkAct->setShortcut(tr("Ctrl+N"));
00237 _helpAct->setShortcut(tr("Ctrl+?"));
00238 _newIdentityAct->setShortcut(tr("Ctrl+I"));
00239
00240
00241
00242 _exitAct->setText("exit");
00243 _configAct->setText("config");
00244 _aboutAct->setText("about");
00245
00246
00247
00248 QMenuBar *menuBar = new QMenuBar();
00249 QMenu *fileMenu = menuBar->addMenu(tr("File"));
00250 fileMenu->addAction(_exitAct);
00251
00252 QMenu *torMenu = menuBar->addMenu(tr("Tor"));
00253 torMenu->addAction(_startAct);
00254 torMenu->addAction(_stopAct);
00255 torMenu->addSeparator();
00256 torMenu->addAction(_newIdentityAct);
00257
00258 QMenu *viewMenu = menuBar->addMenu(tr("View"));
00259 viewMenu->addAction(_bandwidthAct);
00260 viewMenu->addAction(_messageAct);
00261 viewMenu->addAction(_networkAct);
00262 viewMenu->addAction(_configAct);
00263
00264 QMenu *helpMenu = menuBar->addMenu(tr("Help"));
00265 _helpAct->setText(tr("Vidalia Help"));
00266 helpMenu->addAction(_helpAct);
00267 helpMenu->addAction(_aboutAct);
00268 #endif
00269 }
00270
00271
00272
00273 void
00274 MainWindow::start()
00275 {
00276
00277
00278
00279
00280 _isIntentionalExit = true;
00281
00282 _torControl->start();
00283
00284 _startAct->setEnabled(false);
00285 }
00286
00287
00288
00289 void
00290 MainWindow::startFailed(QString errmsg)
00291 {
00292
00293
00294
00295 Q_UNUSED(errmsg);
00296
00297
00298 int response = VMessageBox::warning(this, tr("Error Starting Tor"),
00299 tr("Vidalia was unable to start Tor. Check your settings "
00300 "to ensure the correct name and location of your Tor "
00301 "executable is specified."),
00302 VMessageBox::Ok, VMessageBox::ShowSettings, VMessageBox::Help);
00303
00304 if (response == VMessageBox::ShowSettings) {
00305
00306
00307 ConfigDialog* configDialog = new ConfigDialog(this);
00308 configDialog->show(ConfigDialog::General);
00309 } else if (response == VMessageBox::Help) {
00310
00311 Vidalia::help("troubleshooting.start");
00312 }
00313 _startAct->setEnabled(true);
00314 }
00315
00316
00317
00318 void
00319 MainWindow::started()
00320 {
00321
00322
00323 _isIntentionalExit = false;
00324
00325 _trayIcon->update(IMG_TOR_STARTING, tr("Tor is starting"));
00326
00327 _stopAct->setEnabled(true);
00328 _startAct->setEnabled(false);
00329
00330 _torControl->connect();
00331 }
00332
00333
00334
00335 void
00336 MainWindow::connectFailed(QString errmsg)
00337 {
00338
00339 int response = VMessageBox::warning(this,
00340 tr("Error Connecting to Tor"), p(errmsg),
00341 VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape,
00342 VMessageBox::Retry, VMessageBox::Help);
00343
00344
00345 if (response == VMessageBox::Retry) {
00346
00347 _torControl->connect();
00348 } else {
00349
00350 if (response == VMessageBox::Help) {
00351 Vidalia::help("troubleshooting.connect");
00352 }
00353
00354 _torControl->stop();
00355 }
00356 }
00357
00358
00359
00360
00361
00362 bool
00363 MainWindow::initiateServerShutdown()
00364 {
00365 QString errmsg;
00366 bool rc = false;
00367
00368
00369 int response = VMessageBox::question(this, tr("Server is Enabled"),
00370 tr("You are currently running a Tor server. "
00371 "Terminating your server will interrupt any "
00372 "open connections from clients.\n\n"
00373 "Would you like to shutdown gracefully and "
00374 "give clients time to find a new server?"),
00375 VMessageBox::Yes, VMessageBox::No);
00376
00377 if (response == VMessageBox::Yes) {
00378
00379 if (_torControl->signal(TorSignal::Shutdown, &errmsg)) {
00380 rc = true;
00381 } else {
00382
00383
00384 response = VMessageBox::warning(this, tr("Error Shutting Down"),
00385 p(tr("Vidalia was unable to shutdown Tor gracefully. (")
00386 + errmsg + ")") +
00387 p(tr("Do you want to close Tor anyway?")),
00388 VMessageBox::Yes, VMessageBox::No);
00389
00390 if (response == VMessageBox::No) {
00391
00392 _trayIcon->update(IMG_TOR_RUNNING, tr("Tor is running"));
00393 rc = true;
00394 }
00395 }
00396 }
00397 return rc;
00398 }
00399
00400
00401 void
00402 MainWindow::stop()
00403 {
00404 ServerSettings server(_torControl);
00405 QString errmsg;
00406
00407
00408 _trayIcon->update(IMG_TOR_STOPPING, tr("Tor is stopping"));
00409
00410
00411
00412 if (server.isServerEnabled()) {
00413 if (initiateServerShutdown()) {
00414
00415 return;
00416 }
00417 }
00418
00419
00420 _isIntentionalExit = true;
00421 if (_torControl->stop(&errmsg)) {
00422 _stopAct->setEnabled(false);
00423 } else {
00424 int response = VMessageBox::warning(this, tr("Error Stopping Tor"),
00425 p(tr("Vidalia was unable to stop Tor.")) + p(errmsg),
00426 VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape,
00427 VMessageBox::Help);
00428
00429 if (response == VMessageBox::Help) {
00430
00431 Vidalia::help("troubleshooting.stop");
00432 }
00433
00434
00435 _trayIcon->update(IMG_TOR_RUNNING, tr("Tor is running"));
00436 _isIntentionalExit = false;
00437 }
00438 }
00439
00440
00441
00442 void
00443 MainWindow::stopped(int exitCode, QProcess::ExitStatus exitStatus)
00444 {
00445
00446 _trayIcon->update(IMG_TOR_STOPPED, tr("Tor is stopped"));
00447
00448
00449 _startAct->setEnabled(true);
00450
00451
00452
00453 if (!_isIntentionalExit) {
00454 _stopAct->setEnabled(false);
00455
00456
00457
00458 if (exitStatus == QProcess::CrashExit || exitCode != 0) {
00459 int ret = VMessageBox::warning(this, tr("Tor Exited"),
00460 tr("Vidalia detected that Tor exited unexpectedly.\n\n"
00461 "Please check the message log for indicators "
00462 "about what happened to Tor before it exited."),
00463 VMessageBox::Ok, VMessageBox::ShowLog, VMessageBox::Help);
00464 if (ret == VMessageBox::ShowLog) {
00465 showMessageLog();
00466 } else if (ret == VMessageBox::Help) {
00467 Vidalia::help("troubleshooting.torexited");
00468 }
00469 }
00470 }
00471 }
00472
00473
00474 void
00475 MainWindow::connected()
00476 {
00477 ServerSettings serverSettings(_torControl);
00478 QString errmsg;
00479
00480
00481 _trayIcon->update(IMG_TOR_RUNNING, tr("Tor is running"));
00482 _newIdentityAct->setEnabled(true);
00483
00484
00485
00486 if (serverSettings.changedSinceLastApply()) {
00487 if (!serverSettings.apply(&errmsg)) {
00488 int ret = VMessageBox::warning(this,
00489 tr("Error Applying Server Settings"),
00490 p(tr("Vidalia was unable to apply your server's settings."))
00491 + p(errmsg),
00492 VMessageBox::Ok, VMessageBox::ShowSettings, VMessageBox::ShowLog);
00493
00494 if (ret == VMessageBox::ShowSettings) {
00495
00496 ConfigDialog* configDialog = new ConfigDialog(this);
00497 configDialog->show(ConfigDialog::Server);
00498 } else if (ret == VMessageBox::ShowLog) {
00499
00500 showMessageLog();
00501 }
00502 }
00503 }
00504 }
00505
00506
00507 void
00508 MainWindow::disconnected()
00509 {
00510 _newIdentityAct->setEnabled(false);
00511 }
00512
00513
00514
00515 void
00516 MainWindow::showAbout()
00517 {
00518 static AboutDialog* aboutDialog = new AboutDialog(this);
00519 aboutDialog->show();
00520 }
00521
00522
00523
00524 void
00525 MainWindow::showMessageLog()
00526 {
00527 _messageLog->show();
00528 }
00529
00530
00531
00532 void
00533 MainWindow::showBandwidthGraph()
00534 {
00535 _bandwidthGraph->show();
00536 }
00537
00538
00539
00540 void
00541 MainWindow::showConfig()
00542 {
00543 static ConfigDialog* configDialog = new ConfigDialog(this);
00544 configDialog->show();
00545 }
00546
00547
00548
00549 void
00550 MainWindow::showHelp()
00551 {
00552 Vidalia::help();
00553 }
00554
00555
00556
00557 void
00558 MainWindow::showNetwork()
00559 {
00560 _netViewer->show();
00561 }
00562
00563
00564 void
00565 MainWindow::newIdentity()
00566 {
00567 QString errmsg;
00568 if (_torControl->signal(TorSignal::NewNym, &errmsg)) {
00569 VMessageBox::information(this,
00570 tr("New Identity"),
00571 tr("All subsequent connections will appear to be different "
00572 "than your old connections."),
00573 QMessageBox::Ok);
00574 } else {
00575 VMessageBox::warning(this,
00576 tr("Failed to Create New Identity"), errmsg, VMessageBox::Ok);
00577 }
00578 }
00579