commit 010b2486efca9566b2e685a6872a9dd7a6133826 Author: Tomas Touceda chiiph@gentoo.org Date: Fri Apr 8 11:31:38 2011 -0300
Adds the new GUI for plug in handling
- HelperProcess is still here, and still needs to be added the part where Vidalia calls the other processes (this had been taken out since it's meant to disappear from the "core" code once the plugin system is working).
- Remove include dep for HelpBrowser in ServicePage's header
- Fix bwgraph closing with Esc or Ctrl+w and a segfault with updateTop
- Add a default for delTab, with no parameters it dels the current tab
- Fix translation handling in the new GUI --- src/torcontrol/TorControl.cpp | 4 - src/vidalia/CMakeLists.txt | 197 ++-- src/vidalia/MainWindow.cpp | 2135 ++++++++++++++----------------- src/vidalia/MainWindow.h | 121 +- src/vidalia/MainWindow.ui | 634 +--------- src/vidalia/StatusTab.cpp | 93 ++ src/vidalia/StatusTab.h | 65 + src/vidalia/StatusTab.ui | 154 +++ src/vidalia/VClickLabel.cpp | 95 -- src/vidalia/VClickLabel.h | 59 - src/vidalia/VTabWidget.cpp | 52 + src/vidalia/VTabWidget.h | 43 + src/vidalia/VidaliaTab.cpp | 66 + src/vidalia/VidaliaTab.h | 70 + src/vidalia/bwgraph/BandwidthGraph.cpp | 27 +- src/vidalia/bwgraph/BandwidthGraph.h | 12 +- src/vidalia/bwgraph/BandwidthGraph.ui | 903 +++++++------- src/vidalia/config/BridgeUsageDialog.ui | 63 +- src/vidalia/config/ConfigDialog.h | 4 +- src/vidalia/config/ServicePage.h | 1 - src/vidalia/config/ServicePage.ui | 117 +- src/vidalia/config/TorrcDialog.cpp | 18 + src/vidalia/config/TorrcDialog.h | 1 + src/vidalia/config/TorrcDialog.ui | 259 ++--- src/vidalia/log/MessageLog.cpp | 79 +- src/vidalia/log/MessageLog.h | 8 +- src/vidalia/log/MessageLog.ui | 814 +++++------- src/vidalia/network/NetViewer.cpp | 20 +- src/vidalia/network/NetViewer.h | 4 +- src/vidalia/network/NetViewer.ui | 464 +++---- 30 files changed, 2962 insertions(+), 3620 deletions(-)
diff --git a/src/torcontrol/TorControl.cpp b/src/torcontrol/TorControl.cpp index ea09724..e7156c7 100644 --- a/src/torcontrol/TorControl.cpp +++ b/src/torcontrol/TorControl.cpp @@ -97,10 +97,6 @@ TorControl::TorControl(ControlMethod::Method method) /** Default destructor */ TorControl::~TorControl() { - /* Disconnect the control socket */ - if (isConnected()) { - disconnect(); - } /* If we started our own Tor, stop it now */ if (isVidaliaRunningTor()) { stop(); diff --git a/src/vidalia/CMakeLists.txt b/src/vidalia/CMakeLists.txt index 15eac34..c9803e9 100644 --- a/src/vidalia/CMakeLists.txt +++ b/src/vidalia/CMakeLists.txt @@ -151,35 +151,63 @@ if (USE_MINIUPNPC) ) endif(USE_MINIUPNPC)
-## Help browser sources +## Main Vidalia sources set(vidalia_SRCS ${vidalia_SRCS} - help/browser/HelpBrowser.cpp - help/browser/HelpTextBrowser.cpp + main.cpp + Vidalia.cpp + LanguageSupport.cpp + VTabWidget.cpp + MainWindow.cpp + VidaliaWindow.cpp + VMessageBox.cpp + ControlPasswordInputDialog.cpp + VidaliaTab.cpp + StatusTab.cpp ) qt4_wrap_cpp(vidalia_SRCS - help/browser/HelpBrowser.h - help/browser/HelpTextBrowser.h + Vidalia.h + VTabWidget.h + MainWindow.h + VidaliaWindow.h + VMessageBox.h + ControlPasswordInputDialog.h + VidaliaTab.h + StatusTab.h )
-## Message log sources -set(vidalia_SRCS ${vidalia_SRCS} - log/LogFile.cpp - log/LogHeaderView.cpp - log/LogMessageColumnDelegate.cpp - log/LogTreeItem.cpp - log/LogTreeWidget.cpp - log/MessageLog.cpp - log/StatusEventItem.cpp - log/StatusEventItemDelegate.cpp - log/StatusEventWidget.cpp +if (USE_MINIUPNPC) + qt4_wrap_ui(vidalia_SRCS config/UPNPTestDialog.ui) +endif(USE_MINIUPNPC) + +## Specify all the Qt Designer .ui files +qt4_wrap_ui(vidalia_SRCS + ControlPasswordInputDialog.ui + StatusTab.ui + MainWindow.ui + about/AboutDialog.ui + about/LicenseDialog.ui + bwgraph/BandwidthGraph.ui + config/AdvancedPage.ui + config/AppearancePage.ui + config/BridgeDownloaderProgressDialog.ui + config/BridgeUsageDialog.ui + config/ConfigDialog.ui + config/GeneralPage.ui + config/NetworkPage.ui + config/ServerPage.ui + config/ServicePage.ui + config/TorrcDialog.ui + log/MessageLog.ui + help/browser/HelpBrowser.ui + network/NetViewer.ui + network/RouterInfoDialog.ui ) -qt4_wrap_cpp(vidalia_SRCS - log/LogFile.h - log/LogHeaderView.h - log/LogTreeWidget.h - log/MessageLog.h - log/StatusEventItemDelegate.h - log/StatusEventWidget.h + +## Add the resource files (icons, etc.) +qt4_add_resources(vidalia_SRCS + res/vidalia.qrc + help/content/content.qrc + ${CMAKE_CURRENT_BINARY_DIR}/i18n/vidalia_i18n.qrc )
## Network map sources @@ -235,112 +263,35 @@ if (USE_GEOIP) ) endif(USE_GEOIP)
-## Main Vidalia sources +## Help browser sources set(vidalia_SRCS ${vidalia_SRCS} - main.cpp - Vidalia.cpp - LanguageSupport.cpp - MainWindow.cpp - VClickLabel.cpp - VidaliaWindow.cpp - VMessageBox.cpp - HelperProcess.cpp - ControlPasswordInputDialog.cpp + help/browser/HelpBrowser.cpp + help/browser/HelpTextBrowser.cpp ) qt4_wrap_cpp(vidalia_SRCS - Vidalia.h - MainWindow.h - VClickLabel.h - VidaliaWindow.h - VMessageBox.h - HelperProcess.h - ControlPasswordInputDialog.h -) -if (USE_BREAKPAD) - set(vidalia_SRCS ${vidalia_SRCS} - CrashReporter.cpp - ) -endif(USE_BREAKPAD) - -## Specify all the Qt Designer .ui files -qt4_wrap_ui(vidalia_SRCS - ControlPasswordInputDialog.ui - MainWindow.ui - about/AboutDialog.ui - about/LicenseDialog.ui - bwgraph/BandwidthGraph.ui - config/AdvancedPage.ui - config/AppearancePage.ui - config/BridgeDownloaderProgressDialog.ui - config/BridgeUsageDialog.ui - config/ConfigDialog.ui - config/GeneralPage.ui - config/NetworkPage.ui - config/ServerPage.ui - config/ServicePage.ui - config/TorrcDialog.ui - help/browser/HelpBrowser.ui - log/MessageLog.ui - network/NetViewer.ui - network/RouterInfoDialog.ui + help/browser/HelpBrowser.h + help/browser/HelpTextBrowser.h )
-if (USE_MINIUPNPC) - qt4_wrap_ui(vidalia_SRCS config/UPNPTestDialog.ui) -endif(USE_MINIUPNPC) - -if (USE_AUTOUPDATE) - set(vidalia_SRCS ${vidalia_SRCS} - PackageInfo.cpp - UpdateProcess.cpp - UpdateProgressDialog.cpp - UpdatesAvailableDialog.cpp - ) - qt4_wrap_cpp(vidalia_SRCS - UpdateProcess.h - UpdateProgressDialog.h - UpdatesAvailableDialog.h - ) - qt4_wrap_ui(vidalia_SRCS - UpdateProgressDialog.ui - UpdatesAvailableDialog.ui - ) -endif(USE_AUTOUPDATE) - -## Add the resource files (icons, etc.) -qt4_add_resources(vidalia_SRCS - res/vidalia.qrc - help/content/content.qrc - ${CMAKE_CURRENT_BINARY_DIR}/i18n/vidalia_i18n.qrc +## Message log sources +set(vidalia_SRCS ${vidalia_SRCS} + log/LogFile.cpp + log/LogHeaderView.cpp + log/LogMessageColumnDelegate.cpp + log/LogTreeItem.cpp + log/LogTreeWidget.cpp + log/MessageLog.cpp + log/StatusEventItem.cpp + log/StatusEventItemDelegate.cpp + log/StatusEventWidget.cpp ) - -## Specify the map data Marble will need -set(marble_DATA - landcolors.leg - seacolors.leg - maps/earth/bluemarble/bluemarble.dgml - maps/earth/citylights/citylights.dgml - maps/earth/srtm/srtm.dgml - maps/earth/srtm/srtm.jpg - mwdbii/DATELINE.PNT - mwdbii/PAUST.PNT - mwdbii/PBORDER.PNT - mwdbii/PCANPROV.PNT - mwdbii/PCOAST.PNT - mwdbii/PDIFFBORDER.PNT - mwdbii/PGLACIER.PNT - mwdbii/PISLAND.PNT - mwdbii/PLAKE.PNT - mwdbii/PLAKEISLAND.PNT - mwdbii/PMEXICO.PNT - mwdbii/PUSA48.DIFF.PNT - mwdbii/PUSA48.PNT - mwdbii/RIVER.PNT - placemarks/baseplacemarks.cache - placemarks/boundaryplacemarks.cache - placemarks/elevplacemarks.cache - stars/stars.dat - svg/worldmap.svg +qt4_wrap_cpp(vidalia_SRCS + log/LogFile.h + log/LogHeaderView.h + log/LogTreeWidget.h + log/MessageLog.h + log/StatusEventItemDelegate.h + log/StatusEventWidget.h )
## Set the appropriate executable target for the current platform diff --git a/src/vidalia/MainWindow.cpp b/src/vidalia/MainWindow.cpp index 3c5c789..ac048e5 100644 --- a/src/vidalia/MainWindow.cpp +++ b/src/vidalia/MainWindow.cpp @@ -19,10 +19,13 @@
#include "MainWindow.h" #include "Vidalia.h" -#include "VMessageBox.h" #include "ControlPasswordInputDialog.h" +#include "VMessageBox.h" #include "TorSettings.h" #include "ServerSettings.h" +#include "BandwidthGraph.h" +#include "AboutDialog.h" +#include "HelpBrowser.h" #ifdef USE_AUTOUPDATE #include "UpdatesAvailableDialog.h" #endif @@ -35,9 +38,7 @@ #include "stringutil.h" #include "procutil.h"
-#include <QMenuBar> -#include <QTimer> -#include <QTextStream> +#include <QtGui>
#define IMG_BWGRAPH ":/images/16x16/utilities-system-monitor.png" #define IMG_CONTROL_PANEL ":/images/16x16/system-run.png" @@ -97,41 +98,234 @@ void qt_mac_set_dock_menu(QMenu *menu); MainWindow::MainWindow() : VidaliaWindow("MainWindow") { - VidaliaSettings settings; + /* Create a new TorControl object, used to communicate with Tor */ + _torControl = Vidalia::torControl();
- ui.setupUi(this); + createGUI(); + createConnections(); +}
- /* Pressing 'Esc' or 'Ctrl+W' will close the window */ - Vidalia::createShortcut("Ctrl+W", this, ui.btnHide, SLOT(click())); - Vidalia::createShortcut("Esc", this, ui.btnHide, SLOT(click())); - - /* Create all the dialogs of which we only want one instance */ - _messageLog = new MessageLog(); - _bandwidthGraph = new BandwidthGraph(); - _netViewer = new NetViewer(); - _configDialog = new ConfigDialog(); - _menuBar = 0; - connect(_messageLog, SIGNAL(helpRequested(QString)), - this, SLOT(showHelpDialog(QString))); - connect(_netViewer, SIGNAL(helpRequested(QString)), - this, SLOT(showHelpDialog(QString))); - connect(_configDialog, SIGNAL(helpRequested(QString)), - this, SLOT(showHelpDialog(QString))); - connect(_configDialog, SIGNAL(restartTor()), - this, SLOT(restart())); +/** Destructor */ +MainWindow::~MainWindow() {}
- /* Create the actions that will go in the tray menu */ +/** Calls the different methods that will handle the GUI "creation". + * It's called once at the MainWindow creation. */ +void +MainWindow::createGUI() +{ + ui.setupUi(this); createActions(); - /* Creates a tray icon with a context menu and adds it to the system's - * notification area. */ + createMenuBar(); + createToolBar(); createTrayIcon(); - /* Start with Tor initially stopped */ - _status = Unset; - _isVidaliaRunningTor = false; - updateTorStatus(Stopped);
- /* Create a new TorControl object, used to communicate with Tor */ - _torControl = Vidalia::torControl(); + // We need to create this tab at the beggining + // and we must specify the statusBar + _messageLog = new MessageLog(this->statusBar()); + + addTab(&_statusTab); + ui.tabWidget->pinTab(0); +} + +/** Creates the actions used in toolbars and menu */ +void +MainWindow::createActions() +{ + _actionShowControlPanel = new QAction(QIcon(IMG_CONTROL_PANEL), tr("Control Panel"), this); + _actionStartTor = new QAction(QIcon(IMG_START_TOR_16), tr("Start"), this); + _actionStopTor = new QAction(QIcon(IMG_STOP_TOR_16), tr("Stop"), this); + _actionRestartTor = new QAction(tr("Restart"), this); + _actionNewIdentity = new QAction(QIcon(IMG_IDENTITY), tr("New Identity"), this); + _actionStatus = new QAction(QIcon(IMG_CONTROL_PANEL), tr("Status"), this); + _actionNetworkMap = new QAction(QIcon(IMG_NETWORK), tr("Network Map"), this); + _actionMessageLog= new QAction(QIcon(IMG_MESSAGELOG), tr("Message Log"), this); + _actionBandwidthGraph = new QAction(QIcon(IMG_BWGRAPH), tr("Bandwidth Graph"), this); + _actionConfigure = new QAction(QIcon(IMG_CONFIG), tr("Settings"), this); + _actionVidaliaHelp = new QAction(QIcon(IMG_HELP), tr("Help"), this); + _actionAbout = new QAction(QIcon(IMG_ABOUT), tr("About"), this); + _actionStartStopTor = new QAction(QIcon(IMG_START_TOR_16), tr("Start Tor"), this); + _actionExit = new QAction(QIcon(IMG_EXIT), tr("Exit"), this); +} + +/** Creates the menu bar */ +void +MainWindow::createMenuBar() +{ + QMenuBar *menu = menuBar(); + menu->clear(); + + QMenu *torMenu = menu->addMenu(tr("Tor")); + torMenu->addAction(_actionStartTor); + torMenu->addAction(_actionStopTor); + torMenu->addAction(_actionRestartTor); + + QMenu *actionsMenu = menu->addMenu(tr("Actions")); + actionsMenu->addAction(_actionNewIdentity); + + QMenu *viewMenu = menu->addMenu(tr("View")); + viewMenu->addAction(_actionStatus); + viewMenu->addAction(_actionNetworkMap); + viewMenu->addAction(_actionMessageLog); + viewMenu->addAction(_actionBandwidthGraph); + viewMenu->addSeparator(); + viewMenu->addAction(_actionConfigure); + +// QMenu *pluginsMenu = menu->addMenu(tr("Plugins")); + + QMenu *helpMenu = menu->addMenu(tr("Help")); + helpMenu->addAction(_actionVidaliaHelp); + helpMenu->addSeparator(); + helpMenu->addAction(_actionAbout); +} + +/** Creates the main toolbar */ +void +MainWindow::createToolBar() +{ + QToolBar *tool = ui.toolBar; + + tool->addAction(_actionStartStopTor); + tool->addAction(_actionNewIdentity); + tool->addAction(_actionConfigure); + + tool->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); +} + +/** Creates a QMenu object that contains QActions which compose the system + * tray menu. */ +QMenu* +MainWindow::createTrayMenu() +{ + QMenu *menu = new QMenu(this); + menu->addAction(_actionStartStopTor); + menu->addSeparator(); + menu->addAction(_actionBandwidthGraph); + menu->addAction(_actionMessageLog); + menu->addAction(_actionNetworkMap); + menu->addAction(_actionNewIdentity); + menu->addSeparator(); + menu->addAction(_actionShowControlPanel); + +#if !defined(Q_WS_MAC) + /* These aren't added to the dock menu on Mac, since they are in the + * standard Mac locations in the menu bar. */ + menu->addAction(_actionConfigure); + menu->addAction(_actionVidaliaHelp); + menu->addAction(_actionAbout); + menu->addSeparator(); + menu->addAction(_actionExit); +#endif + return menu; +} + +/** Creates a tray icon with a context menu and adds it to the system + * notification area. On Mac, we also set up an application menubar. */ +void +MainWindow::createTrayIcon() +{ + QMenu *menu = createTrayMenu(); + + /* Add the menu it to the tray icon */ + _trayIcon.setContextMenu(menu); + + connect(&_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), + this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + +#if defined(Q_WS_MAC) + qt_mac_set_dock_menu(menu); +#endif + + VidaliaSettings settings; + + _statusTab.checkShowOnStartup(settings.showMainWindowAtStart()); + if (_statusTab.isCheckedShowOnStartup()) + show(); + _trayIcon.show(); +} + +void +MainWindow::setVisible(bool visible) +{ + if (visible) { + /* In Gnome, will hide buttons if Vidalia is run on startup. */ + if (!QSystemTrayIcon::isSystemTrayAvailable()) { + /* Don't let people hide the main window, since that's all they have. */ + _statusTab.hideCheckShowOnStartup(); + /* Causes window to not appear in Enlightenment. */ + //setMinimumHeight(height()-ui.btnHide->height()); + //setMaximumHeight(height()-ui.btnHide->height()); + } + } + VidaliaWindow::setVisible(visible); +} + +/** Respond to a double-click on the tray icon by opening the Control Panel + * window. */ +void +MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) +{ + if (reason == QSystemTrayIcon::DoubleClick) + setVisible(true); +} + +void +MainWindow::retranslateUi() +{ + updateTorStatus(_status); + + _actionShowControlPanel->setText(tr("Control Panel")); + _actionStartTor->setText(tr("Start")); + _actionStopTor->setText(tr("Stop")); + _actionRestartTor->setText(tr("Restart")); + _actionConfigure->setText(tr("Settings")); + + if (_status == Stopped) { + _actionStartStopTor->setText(tr("Start Tor")); + } else if (_status == Starting) { + _actionStartStopTor->setText(tr("Starting Tor")); + } else { + _actionStartStopTor->setText(tr("Stop Tor")); + } + + _actionBandwidthGraph->setText(tr("Bandwidth Graph")); + _actionMessageLog->setText(tr("Message Log")); + _actionNetworkMap->setText(tr("Network Map")); + _actionStatus->setText(tr("Status")); + _actionVidaliaHelp->setText(tr("Help")); + _actionNewIdentity->setText(tr("New Identity")); + +#if !defined(Q_WS_MAC) + _actionAbout->setText(tr("About")); + _actionConfigure->setText(tr("Settings")); + _actionExit->setText(tr("Exit")); +#endif + + createMenuBar(); + ui.retranslateUi(this); +} + +void +MainWindow::createConnections() +{ + connect(_actionExit, SIGNAL(triggered()), this, SLOT(close())); + connect(_actionStartTor, SIGNAL(triggered()), this, SLOT(start())); + connect(_actionRestartTor, SIGNAL(triggered()), this, SLOT(restart())); + connect(_actionStopTor, SIGNAL(triggered()), this, SLOT(stop())); + connect(_actionShowControlPanel, SIGNAL(triggered()), this, SLOT(show())); + connect(_actionNewIdentity, SIGNAL(triggered()), this, SLOT(newIdentity())); + + connect(_actionMessageLog, SIGNAL(triggered()), this, SLOT(showMessageLogTab())); + connect(_actionConfigure, SIGNAL(triggered()), this, SLOT(showConfigDialog())); + connect(_actionBandwidthGraph, SIGNAL(triggered()), this, SLOT(showBandwithTab())); + connect(_actionAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog())); + connect(_actionVidaliaHelp, SIGNAL(triggered()), this, SLOT(showHelpDialog())); + connect(_actionStatus, SIGNAL(triggered()), this, SLOT(showStatusTab())); + connect(_actionNetworkMap, SIGNAL(triggered()), this, SLOT(showNetViewerTab())); + + /* Catch signals when the application is running or shutting down */ + connect(vApp, SIGNAL(running()), this, SLOT(running())); + connect(vApp, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); + connect(_torControl, SIGNAL(started()), this, SLOT(started())); connect(_torControl, SIGNAL(startFailed(QString)), this, SLOT(startFailed(QString))); @@ -159,28 +353,8 @@ MainWindow::MainWindow() connect(_torControl, SIGNAL(dangerousPort(quint16, bool)), this, SLOT(warnDangerousPort(quint16, bool)));
- /* Create a new HelperProcess object, used to start the web browser */ - _browserProcess = new HelperProcess(this); - connect(_browserProcess, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(onSubprocessFinished(int, QProcess::ExitStatus))); - connect(_browserProcess, SIGNAL(startFailed(QString)), - this, SLOT(onBrowserFailed(QString))); - - /* Create a new HelperProcess object, used to start the IM client */ - _imProcess = new HelperProcess(this); - connect(_imProcess, SIGNAL(finished(int, QProcess::ExitStatus)), - this, SLOT(onSubprocessFinished(int, QProcess::ExitStatus))); - connect(_imProcess, SIGNAL(startFailed(QString)), - this, SLOT(onIMFailed(QString))); - - /* Create a new HelperProcess object, used to start the proxy server */ - _proxyProcess = new HelperProcess(this); - connect(_proxyProcess, SIGNAL(startFailed(QString)), - this, SLOT(onProxyFailed(QString))); - - /* Catch signals when the application is running or shutting down */ - connect(vApp, SIGNAL(running()), this, SLOT(running())); - connect(vApp, SIGNAL(aboutToQuit()), this, SLOT(aboutToQuit())); + connect(ui.tabWidget, SIGNAL(tabCloseRequested(int)), + this, SLOT(handleCloseTab(int)));
#if defined(USE_AUTOUPDATE) /* Create a timer used to remind us to check for software updates */ @@ -207,74 +381,29 @@ MainWindow::MainWindow() #if defined(USE_MINIUPNPC) /* Catch UPnP-related signals */ connect(UPNPControl::instance(), SIGNAL(error(UPNPControl::UPNPError)), - this, SLOT(upnpError(UPNPControl::UPNPError))); + this, SLOT(upnpError(UPNPControl::UPNPError))); #endif - - ui.chkShowOnStartup->setChecked(settings.showMainWindowAtStart()); - if (ui.chkShowOnStartup->isChecked()) - show(); - /* Optimistically hope that the tray icon gets added. */ - _trayIcon.show(); -} - -/** Destructor. */ -MainWindow::~MainWindow() -{ - _trayIcon.hide(); - delete _messageLog; - delete _bandwidthGraph; - delete _netViewer; - delete _configDialog; }
+/** Called when the application is closing, by selecting "Exit" from the tray + * menu. If we're running a Tor server, then ask if we want to kill Tor now, + * or do a delayed shutdown. */ void -MainWindow::setVisible(bool visible) +MainWindow::close() { - if (visible) { - /* In Gnome, will hide buttons if Vidalia is run on startup. */ - if (!QSystemTrayIcon::isSystemTrayAvailable()) { - /* Don't let people hide the main window, since that's all they have. */ - ui.chkShowOnStartup->hide(); - ui.btnHide->hide(); - /* Causes window to not appear in Enlightenment. */ - //setMinimumHeight(height()-ui.btnHide->height()); - //setMaximumHeight(height()-ui.btnHide->height()); + if (_torControl->isVidaliaRunningTor()) { + /* If we're running a server currently, ask if we want to do a delayed + * shutdown. If we do, then close Vidalia only when Tor stops. Otherwise, + * kill Tor and bail now. */ + ServerSettings settings(_torControl); + if (_torControl->isConnected() && settings.isServerEnabled()) { + connect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit())); + if (!stop()) + QObject::disconnect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit())); + return; } } - VidaliaWindow::setVisible(visible); -} - -void -MainWindow::retranslateUi() -{ - ui.retranslateUi(this); - - updateTorStatus(_status); - if (_status == Stopped) { - _actionStartStopTor->setText(tr("Start Tor")); - ui.lblStartStopTor->setText(tr("Start Tor")); - } else if (_status == Starting) { - _actionStartStopTor->setText(tr("Starting Tor")); - ui.lblStartStopTor->setText(tr("Starting Tor")); - } else { - _actionStartStopTor->setText(tr("Stop Tor")); - ui.lblStartStopTor->setText(tr("Stop Tor")); - } - - _actionShowBandwidth->setText(tr("Bandwidth Graph")); - _actionShowMessageLog->setText(tr("Message Log")); - _actionShowNetworkMap->setText(tr("Network Map")); - _actionShowControlPanel->setText(tr("Control Panel")); - _actionShowHelp->setText(tr("Help")); - _actionNewIdentity->setText(tr("New Identity")); - -#if !defined(Q_WS_MAC) - _actionShowAbout->setText(tr("About")); - _actionShowConfig->setText(tr("Settings")); - _actionExit->setText(tr("Exit")); -#else - createMenuBar(); -#endif + vApp->quit(); }
/** Called when the application has started and the main event loop is @@ -302,10 +431,6 @@ MainWindow::running() start(); }
- /* Start the proxy server, if configured */ - if (settings.runProxyAtStart()) - startProxy(); - #if defined(USE_AUTOUPDATE) if (settings.isAutoUpdateEnabled()) { QDateTime lastCheckedAt = settings.lastCheckedForUpdates(); @@ -351,428 +476,446 @@ MainWindow::aboutToQuit() ServerSettings settings(_torControl); settings.cleanupPortForwarding();
- if (_proxyProcess->state() != QProcess::NotRunning) { - /* Close the proxy server (Polipo ignores the WM_CLOSE event sent by - * terminate() so we have to kill() it) */ - _proxyProcess->kill(); - } - /* Kill the browser and IM client if using the new launcher */ VidaliaSettings vidalia_settings;
- if (! vidalia_settings.getBrowserDirectory().isEmpty()) { - /* Disconnect the finished signals so that we won't try to exit Vidalia again */ - QObject::disconnect(_browserProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0); - QObject::disconnect(_imProcess, SIGNAL(finished(int, QProcess::ExitStatus)), 0, 0); - - /* Use QProcess terminate function */ - if (_browserProcess->state() == QProcess::Running) - _browserProcess->terminate(); - -#if defined(Q_OS_WIN) - /* Kill any processes which might have been forked off */ - win32_end_process_by_filename(vidalia_settings.getBrowserExecutable()); -#endif - - if (_imProcess->state() == QProcess::Running) - _imProcess->terminate(); - } - /* Disconnect all of the TorControl object's signals */ QObject::disconnect(_torControl, 0, 0, 0); }
-/** Called when the application is closing, by selecting "Exit" from the tray - * menu. If we're running a Tor server, then ask if we want to kill Tor now, - * or do a delayed shutdown. */ -void -MainWindow::close() -{ - if (_torControl->isVidaliaRunningTor()) { - /* If we're running a server currently, ask if we want to do a delayed - * shutdown. If we do, then close Vidalia only when Tor stops. Otherwise, - * kill Tor and bail now. */ - ServerSettings settings(_torControl); - if (_torControl->isConnected() && settings.isServerEnabled()) { - connect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit())); - if (!stop()) - QObject::disconnect(_torControl, SIGNAL(stopped()), vApp, SLOT(quit())); - return; - } - } - vApp->quit(); -}
-/** Create and bind actions to events. Setup for initial - * tray menu configuration. */ +/** Attempts to start Tor. If Tor fails to start, then startFailed() will be + * called with an error message containing the reason. */ void -MainWindow::createActions() +MainWindow::start() { - _actionStartStopTor = new QAction(tr("Start Tor"), this); - connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start())); - - _actionExit = new QAction(tr("Exit"), this); - connect(_actionExit, SIGNAL(triggered()), this, SLOT(close())); - - _actionShowBandwidth = new QAction(tr("Bandwidth Graph"), this); - connect(_actionShowBandwidth, SIGNAL(triggered()), - _bandwidthGraph, SLOT(showWindow())); - connect(ui.lblBandwidthGraph, SIGNAL(clicked()), - _bandwidthGraph, SLOT(showWindow())); - - _actionShowMessageLog = new QAction(tr("Message Log"), this); - connect(_actionShowMessageLog, SIGNAL(triggered()), - _messageLog, SLOT(showWindow())); - connect(ui.lblMessageLog, SIGNAL(clicked()), - _messageLog, SLOT(showWindow())); - - _actionShowNetworkMap = new QAction(tr("Network Map"), this); - connect(_actionShowNetworkMap, SIGNAL(triggered()), - _netViewer, SLOT(showWindow())); - connect(ui.lblViewNetwork, SIGNAL(clicked()), - _netViewer, SLOT(showWindow())); - - _actionShowControlPanel = new QAction(tr("Control Panel"), this); - connect(_actionShowControlPanel, SIGNAL(triggered()), this, SLOT(show())); + TorSettings settings; + QStringList args;
- _actionShowConfig = new QAction(tr("Settings"), this); - connect(_actionShowConfig, SIGNAL(triggered()), this, SLOT(showConfigDialog())); - - _actionShowAbout = new QAction(tr("About"), this); - connect(_actionShowAbout, SIGNAL(triggered()), this, SLOT(showAboutDialog())); + updateTorStatus(Starting);
- _actionShowHelp = new QAction(tr("Help"), this); - connect(_actionShowHelp, SIGNAL(triggered()), this, SLOT(showHelpDialog())); - connect(ui.lblHelpBrowser, SIGNAL(clicked()), this, SLOT(showHelpDialog())); + /* Check if Tor is already running separately */ + if(settings.getControlMethod() == ControlMethod::Port) { + if (net_test_connect(settings.getControlAddress(), + settings.getControlPort())) { + started(); + return; + } + } else { + if (socket_test_connect(settings.getSocketPath())) { + started(); + return; + } + }
- _actionNewIdentity = new QAction(tr("New Identity"), this); - _actionNewIdentity->setEnabled(false); - connect(_actionNewIdentity, SIGNAL(triggered()), this, SLOT(newIdentity())); + /* Make sure the torrc we want to use really exists. */ + QString torrc = settings.getTorrc(); + if (!torrc.isEmpty()) { + if (!QFileInfo(torrc).exists()) + touch_file(torrc, true); + args << "-f" << torrc; + }
-#if !defined(Q_WS_MAC) - /* Don't give the menu items icons on OS X, since they end up in the - * application menu bar. Menu bar items on OS X typically do not have - * icons. */ - _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16)); - _actionExit->setIcon(QIcon(IMG_EXIT)); - _actionShowBandwidth->setIcon(QIcon(IMG_BWGRAPH)); - _actionShowMessageLog->setIcon(QIcon(IMG_MESSAGELOG)); - _actionShowNetworkMap->setIcon(QIcon(IMG_NETWORK)); - _actionShowControlPanel->setIcon(QIcon(IMG_CONTROL_PANEL)); - _actionShowConfig->setIcon(QIcon(IMG_CONFIG)); - _actionShowAbout->setIcon(QIcon(IMG_ABOUT)); - _actionShowHelp->setIcon(QIcon(IMG_HELP)); - _actionNewIdentity->setIcon(QIcon(IMG_IDENTITY)); -#endif + /* Specify Tor's data directory, if different from the default */ + QString dataDirectory = settings.getDataDirectory(); + if (!dataDirectory.isEmpty()) + args << "DataDirectory" << expand_filename(dataDirectory); + + if(settings.getControlMethod() == ControlMethod::Port) { + /* Add the intended control port value */ + quint16 controlPort = settings.getControlPort(); + if (controlPort) + args << "ControlPort" << QString::number(controlPort); + } else { + QString path = settings.getSocketPath(); + args << "ControlSocket" << path; + } + + /* Add the control port authentication arguments */ + switch (settings.getAuthenticationMethod()) { + case TorSettings::PasswordAuth: + if (! vApp->readPasswordFromStdin()) { + if (settings.useRandomPassword()) { + _controlPassword = TorSettings::randomPassword(); + _useSavedPassword = false; + } else { + _controlPassword = settings.getControlPassword(); + _useSavedPassword = true; + } + } + args << "HashedControlPassword" + << TorSettings::hashPassword(_controlPassword); + break; + case TorSettings::CookieAuth: + args << "CookieAuthentication" << "1"; + break; + default: + args << "CookieAuthentication" << "0"; + } + + /* This doesn't get set to false until Tor is actually up and running, so we + * don't yell at users twice if their Tor doesn't even start, due to the fact + * that QProcess::stopped() is emitted even if the process didn't even + * start. */ + _isIntentionalExit = true; + /* Kick off the Tor process */ + _torControl->start(settings.getExecutable(), args); }
-/** Creates a tray icon with a context menu and adds it to the system - * notification area. On Mac, we also set up an application menubar. */ -void -MainWindow::createTrayIcon() +/** Slot: Called when the Tor process is started. It will connect the control + * socket and set the icons and tooltips accordingly. */ +void +MainWindow::started() { - QMenu *menu = createTrayMenu(); - - /* Add the menu it to the tray icon */ - _trayIcon.setContextMenu(menu); + TorSettings settings;
- connect(&_trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), - this, SLOT(trayIconActivated(QSystemTrayIcon::ActivationReason))); + updateTorStatus(Started);
-#if defined(Q_WS_MAC) - createMenuBar(); - qt_mac_set_dock_menu(menu); -#endif + /* Now that Tor is running, we want to know if it dies when we didn't want + * it to. */ + _isIntentionalExit = false; + /* We haven't started a delayed shutdown yet. */ + _delayedShutdownStarted = false; + /* Remember whether we started Tor or not */ + _isVidaliaRunningTor = _torControl->isVidaliaRunningTor(); + /* Try to connect to Tor's control port */ + if(settings.getControlMethod() == ControlMethod::Port) + _torControl->connect(settings.getControlAddress(), + settings.getControlPort()); + else + _torControl->connect(settings.getSocketPath()); + setStartupProgress(STARTUP_PROGRESS_CONNECTING, tr("Connecting to Tor")); }
-/** Creates a QMenu object that contains QActions which compose the system - * tray menu. */ -QMenu* -MainWindow::createTrayMenu() +/** Disconnects the control socket and stops the Tor process. */ +bool +MainWindow::stop() { - QMenu *menu = new QMenu(this); - menu->addAction(_actionStartStopTor); - menu->addSeparator(); - menu->addAction(_actionShowBandwidth); - menu->addAction(_actionShowMessageLog); - menu->addAction(_actionShowNetworkMap); - menu->addAction(_actionNewIdentity); - menu->addSeparator(); - menu->addAction(_actionShowControlPanel); - -#if !defined(Q_WS_MAC) - /* These aren't added to the dock menu on Mac, since they are in the - * standard Mac locations in the menu bar. */ - menu->addAction(_actionShowConfig); - menu->addAction(_actionShowHelp); - menu->addAction(_actionShowAbout); - menu->addSeparator(); - menu->addAction(_actionExit); -#endif - return menu; -} + ServerSettings server(_torControl); + QString errmsg; + TorStatus prevStatus; + bool rc;
-/** Creates a new menubar with no parent, so Qt will use this as the "default - * menubar" on Mac. This adds on to the existing actions from the createMens() - * method. */ -void -MainWindow::createMenuBar() -{ -#if defined(Q_WS_MAC) - /* Mac users sure like their shortcuts. Actions NOT mentioned below - * don't explicitly need shortcuts, since they are merged to the default - * menubar and get the default shortcuts anyway. */ - _actionStartStopTor->setShortcut(tr("Ctrl+T")); - _actionShowBandwidth->setShortcut(tr("Ctrl+B")); - _actionShowMessageLog->setShortcut(tr("Ctrl+L")); - _actionShowNetworkMap->setShortcut(tr("Ctrl+N")); - _actionShowHelp->setShortcut(tr("Ctrl+?")); - _actionNewIdentity->setShortcut(tr("Ctrl+I")); - _actionShowControlPanel->setShortcut(tr("Ctrl+P")); - - /* Force Qt to put merge the Exit, Configure, and About menubar options into - * the default menu, even if Vidalia is currently not speaking English. */ - _actionShowConfig->setText("config"); - _actionShowConfig->setMenuRole(QAction::PreferencesRole); - _actionShowAbout->setText("about"); - _actionShowAbout->setMenuRole(QAction::AboutRole); - _actionExit->setText("quit"); - _actionExit->setMenuRole(QAction::QuitRole); - - /* The File, Help, and Configure menus will get merged into the application - * menu by Qt. */ - if (_menuBar) - delete _menuBar; - _menuBar = new QMenuBar(0); - QMenu *fileMenu = _menuBar->addMenu("File"); - fileMenu->addAction(_actionExit); - fileMenu->addAction(_actionShowConfig); - - QMenu *torMenu = _menuBar->addMenu(tr("Tor")); - torMenu->addAction(_actionStartStopTor); - torMenu->addSeparator(); - torMenu->addAction(_actionNewIdentity); - - QMenu *viewMenu = _menuBar->addMenu(tr("View")); - viewMenu->addAction(_actionShowControlPanel); - viewMenu->addSeparator(); - viewMenu->addAction(_actionShowBandwidth); - viewMenu->addAction(_actionShowMessageLog); - viewMenu->addAction(_actionShowNetworkMap); + /* If we're running a server, give users the option of terminating + * gracefully so clients have time to find new servers. */ + if (server.isServerEnabled() && !_delayedShutdownStarted) { + /* Ask the user if they want to shutdown nicely. */ + int response = VMessageBox::question(this, tr("Relaying is Enabled"), + tr("You are currently running a relay. " + "Terminating your relay will interrupt any " + "open connections from clients.\n\n" + "Would you like to shutdown gracefully and " + "give clients time to find a new relay?"), + VMessageBox::Yes|VMessageBox::Default, + VMessageBox::No, + VMessageBox::Cancel|VMessageBox::Escape); + if (response == VMessageBox::Yes) + _delayedShutdownStarted = true; + else if (response == VMessageBox::Cancel) + return false; + }
- QMenu *helpMenu = _menuBar->addMenu(tr("Help")); - _actionShowHelp->setText(tr("Vidalia Help")); - helpMenu->addAction(_actionShowHelp); - helpMenu->addAction(_actionShowAbout); -#endif + prevStatus = updateTorStatus(Stopping); + if (_delayedShutdownStarted) { + /* Start a delayed shutdown */ + rc = _torControl->signal(TorSignal::Shutdown, &errmsg); + } else { + /* We want Tor to stop now, regardless of whether we're a server. */ + _isIntentionalExit = true; + rc = _torControl->stop(&errmsg); + } + + if (!rc) { + /* We couldn't tell Tor to stop, for some reason. */ + int response = VMessageBox::warning(this, tr("Error Shutting Down"), + p(tr("Vidalia was unable to stop the Tor software.")) + + p(errmsg), + VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, + VMessageBox::Help); + + if (response == VMessageBox::Help) { + /* Show some troubleshooting help */ + showHelpDialog("troubleshooting.stop"); + } + /* Tor is still running since stopping failed */ + _isIntentionalExit = false; + _delayedShutdownStarted = false; + updateTorStatus(prevStatus); + } + return rc; }
-/** Sets the current tray or dock icon image to <b>iconFile</b>. */ -void -MainWindow::setTrayIcon(const QString &iconFile) +/** Slot: Called when the Tor process has exited. It will adjust the tray + * icons and tooltips accordingly. */ +void +MainWindow::stopped(int exitCode, QProcess::ExitStatus exitStatus) { -#if defined(Q_WS_MAC) - QApplication::setWindowIcon(QPixmap(iconFile)); -#endif - _trayIcon.setIcon(QIcon(iconFile)); -} + updateTorStatus(Stopped);
-/** Respond to a double-click on the tray icon by opening the Control Panel - * window. */ -void -MainWindow::trayIconActivated(QSystemTrayIcon::ActivationReason reason) -{ - if (reason == QSystemTrayIcon::DoubleClick) - setVisible(true); + /* If we didn't intentionally close Tor, then check to see if it crashed or + * if it closed itself and returned an error code. */ + if (!_isIntentionalExit) { + /* A quick overview of Tor's code tells me that if it catches a SIGTERM or + * SIGINT, Tor will exit(0). We might need to change this warning message + * if this turns out to not be the case. */ + if (exitStatus == QProcess::CrashExit || exitCode != 0) { + int ret = VMessageBox::warning(this, tr("Unexpected Error"), + tr("Vidalia detected that the Tor software exited " + "unexpectedly.\n\n" + "Please check the message log for recent " + "warning or error messages."), + VMessageBox::Ok|VMessageBox::Escape, + VMessageBox::ShowLog|VMessageBox::Default, + VMessageBox::Help); + if (ret == VMessageBox::ShowLog) + showMessageLogTab(); + else if (ret == VMessageBox::Help) + showHelpDialog("troubleshooting.torexited"); + } + } }
-/** Start a web browser when given the directory containing the executable and profile */ +/** Called when the Tor process fails to start, for example, because the path + * specified to the Tor executable didn't lead to an executable. */ void -MainWindow::launchBrowserFromDirectory() +MainWindow::startFailed(QString errmsg) { - VidaliaSettings settings; + /* We don't display the error message for now, because the error message + * that Qt gives us in this instance is almost always "Unknown Error". That + * will make users sad. */ + Q_UNUSED(errmsg); + + updateTorStatus(Stopped);
- QString browserDirectory = settings.getBrowserDirectory(); - QString browserDirectoryFilename = settings.getBrowserExecutable(); - - /* Set TZ=UTC (to stop leaking timezone information) and - * MOZ_NO_REMOTE=1 (to allow multiple instances of Firefox */ - QStringList env = QProcess::systemEnvironment(); - env << "TZ=UTC"; - env << "MOZ_NO_REMOTE=1"; - _browserProcess->setEnvironment(env); - - /* The browser is in <browserDirectory>/App/Firefox/<browserDirectoryFilename> */ - QString browserExecutable = - QDir::toNativeSeparators(browserDirectory + "/App/Firefox/" + browserDirectoryFilename); - /* The profile is in <browserDirectory>/Data/profile */ - QString profileDir = - QDir::toNativeSeparators(browserDirectory + "/Data/profile"); - - /* Copy the profile directory if it's not already there */ - QDir browserDirObj = QDir(browserDirectory); - - /* Copy the profile directory if it's not already there */ - if (!browserDirObj.exists("Data/profile")) { - browserDirObj.mkdir("Data/profile"); - copy_dir(browserDirectory + "/App/DefaultData/profile", browserDirectory + "/Data/profile"); - } + /* Display an error message and see if the user wants some help */ + int response = VMessageBox::warning(this, tr("Error Starting Tor"), + tr("Vidalia was unable to start Tor. Check your settings " + "to ensure the correct name and location of your Tor " + "executable is specified."), + VMessageBox::ShowSettings|VMessageBox::Default, + VMessageBox::Cancel|VMessageBox::Escape, + VMessageBox::Help);
- /* Copy the plugins directory if it's not already there */ - if (!browserDirObj.exists("Data/plugins")) { - browserDirObj.mkdir("Data/plugins"); - copy_dir(browserDirectory + "/App/DefaultData/plugins", browserDirectory + "/Data/plugins"); + if (response == VMessageBox::ShowSettings) { + /* Show the settings dialog so the user can make sure they're pointing to + * the correct Tor. */ + showConfigDialog(); + } else if (response == VMessageBox::Help) { + /* Show troubleshooting information about starting Tor */ + showHelpDialog("troubleshooting.start"); } - - /* Build the command line arguments */ - QStringList commandLine; - // Is this better or worse than MOZ_NO_REMOTE? - //commandLine << "-no-remote"; - commandLine << "-profile"; - commandLine << profileDir; - - /* Launch the browser */ - _browserProcess->start(browserExecutable, commandLine); }
-/** Starts the web browser and IM client, if appropriately configured */ +/** Called when the control socket has successfully connected to Tor. */ void -MainWindow::startSubprocesses() +MainWindow::connected() { - VidaliaSettings settings; - QString subprocess; - - /* Launch the web browser */ - if (!(subprocess = settings.getBrowserDirectory()).isEmpty()) { - /* The user has set BrowserDirectory; use this */ - launchBrowserFromDirectory(); - } else if (!(subprocess = settings.getBrowserExecutable()).isEmpty()) { - /* BrowserDirectory is not set, but BrowserExecutable is; use this */ - _browserProcess->setEnvironment(QProcess::systemEnvironment() << "TZ=UTC"); - _browserProcess->start(subprocess, QStringList()); - } - - /* Launch the IM client */ - subprocess = settings.getIMExecutable(); - - if (!subprocess.isEmpty()) - _imProcess->start(subprocess, QStringList()); + authenticate(); }
-/** Called when browser or IM client have exited */ +/** Called when the connection to the control socket fails. The reason will be + * given in the errmsg parameter. */ void -MainWindow::onSubprocessFinished(int exitCode, QProcess::ExitStatus exitStatus) +MainWindow::connectFailed(QString errmsg) { - Q_UNUSED(exitCode) - Q_UNUSED(exitStatus) + /* Ok, ok. It really isn't going to connect. I give up. */ + int response = VMessageBox::warning(this, + tr("Connection Error"), p(errmsg), + VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, + VMessageBox::Retry, VMessageBox::Help);
- /* Get path to browser and IM client */ - VidaliaSettings settings; - QString browserExecutable = settings.getBrowserExecutable(); - QString browserDirectory = settings.getBrowserDirectory(); - QString imExecutable = settings.getIMExecutable(); - - /* A subprocess is finished if it successfully exited or was never asked to start */ - bool browserDone = (browserExecutable.isEmpty() - && browserDirectory.isEmpty()) - || _browserProcess->isDone(); - bool imDone = imExecutable.isEmpty() || _imProcess->isDone(); - - /* Exit if both subprocesses are finished */ - if (browserDone && imDone) { - if (browserDirectory.isEmpty()) { - /* We are using the standard launcher, exit immediately */ - vApp->quit(); - } else { - /* We are using the alternate launcher, wait until the browser has really died */ - QTimer *browserWatcher = new QTimer(this); - connect(browserWatcher, SIGNAL(timeout()), this, SLOT(onCheckForBrowser())); - browserWatcher->start(2000); - } - } -}
-/** Called periodically to check if the browser is running. If it is not, - * exit Vidalia cleanly */ -void -MainWindow::onCheckForBrowser() -{ -/* This only works on Windows for now */ -#if defined(Q_OS_WIN) - - VidaliaSettings settings; - QString browserDirectoryFilename = settings.getBrowserExecutable(); + if (response == VMessageBox::Retry) { + /* Let's give it another try. */ + TorSettings settings; + _torControl->connect(settings.getControlAddress(), + settings.getControlPort()); + } else { + /* Show the help browser (if requested) */ + if (response == VMessageBox::Help) + showHelpDialog("troubleshooting.connect"); + /* Since Vidalia can't connect, we can't really do much, so stop Tor. */ + _torControl->stop(); + } +}
- /* Get list of running processes */ - QHash<qint64, QString> procList = win32_process_list(); +/** Called when Vidalia has successfully authenticated to Tor. */ +void +MainWindow::authenticated() +{ + ServerSettings serverSettings(_torControl); + QString errmsg;
- /* On old versions of Windows win32_process_list() will return - an empty list. In this case, just keep Vidalia open */ - if (procList.isEmpty()) { - return; + updateTorStatus(Authenticated); + + /* If Tor doesn't have bootstrapping events, then update the current + * status string and bump the progress bar along a bit. */ + if (_torControl->getTorVersion() < 0x020101) { + setStartupProgress(STARTUP_PROGRESS_CIRCUITBUILD, + tr("Connecting to the Tor network")); } + + /* Let people click on their beloved "New Identity" button */ + _actionNewIdentity->setEnabled(true);
- /* Loop over all processes or until we find <browserDirectoryFilename> */ - QHashIterator<qint64, QString> i(procList); - while (i.hasNext()) { - i.next(); - if (i.value().toLower() == browserDirectoryFilename) { - /* The browser is still running, so Vidalia should keep running too */ - return; - } + /* Register for any pertinent asynchronous events. */ + if (!_torControl->setEvents(&errmsg)) { + VMessageBox::warning(this, tr("Error Registering for Events"), + p(tr("Vidalia was unable to register for some events. " + "Many of Vidalia's features may be unavailable.")) + + p(errmsg), + VMessageBox::Ok); + } else { + /* Stop reading from Tor's stdout immediately, since we successfully + * registered for Tor events, including any desired log events. */ + _torControl->closeTorStdout(); }
- /* The browser isn't running, exit Vidalia */ - vApp->quit(); -#endif -} + /* Configure UPnP port forwarding if needed */ + serverSettings.configurePortForwarding();
-/** Called when the web browser failed to start, for example, because the path - * specified to the web browser executable didn't lead to an executable. */ -void -MainWindow::onBrowserFailed(QString errmsg) -{ - Q_UNUSED(errmsg); - - /* Display an error message and see if the user wants some help */ - VMessageBox::warning(this, tr("Error starting web browser"), - tr("Vidalia was unable to start the configured web browser"), - VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape); + /* Check if Tor has a circuit established */ + if (_torControl->isCircuitEstablished()) { + circuitEstablished(); + } + /* Check the status of Tor's version */ + if (_torControl->getTorVersion() >= 0x020001) + checkTorVersion(); + if (_torControl->getTorVersion() >= 0x020102) { + BootstrapStatus status = _torControl->bootstrapStatus(); + if (status.isValid()) + bootstrapStatusChanged(status); + } }
-/** Called when the IM client failed to start, for example, because the path - * specified to the IM client executable didn't lead to an executable. */ +/** Called when Vidalia fails to authenticate to Tor. The failure reason is + * specified in <b>errmsg</b>. */ void -MainWindow::onIMFailed(QString errmsg) +MainWindow::authenticationFailed(QString errmsg) { - Q_UNUSED(errmsg); - - /* Display an error message and see if the user wants some help */ - VMessageBox::warning(this, tr("Error starting IM client"), - tr("Vidalia was unable to start the configured IM client"), - VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape); + bool retry = false; + + vWarn("Authentication failed: %1").arg(errmsg); + + /* Parsing log messages is evil, but we're left with little option */ + if (errmsg.contains("Password did not match")) { + ControlPasswordInputDialog dlg; + connect(&dlg, SIGNAL(helpRequested(QString)), + this, SLOT(showHelpDialog(QString))); + + qint64 torPid = 0; + +#if defined(Q_OS_WIN32) + QHash<qint64, QString> procs = process_list(); + foreach (qint64 pid, procs.keys()) { + if (! procs.value(pid).compare("tor.exe", Qt::CaseInsensitive)) { + torPid = pid; + break; + } + } + dlg.setResetEnabled(torPid > 0); +#else + dlg.setResetEnabled(false); +#endif + + int ret = dlg.exec(); + if (ret == QDialogButtonBox::Ok) { + if (dlg.isSavePasswordChecked()) { + TorSettings settings; + settings.setAuthenticationMethod(TorSettings::PasswordAuth); + settings.setUseRandomPassword(false); + settings.setControlPassword(dlg.password()); + _useSavedPassword = true; + } else { + _controlPassword = dlg.password(); + _useSavedPassword = false; + } + retry = true; + } else if (ret == QDialogButtonBox::Reset) { + if (! process_kill(torPid)) { + VMessageBox::warning(this, + tr("Password Reset Failed"), + p(tr("Vidalia tried to reset Tor's control password, but was not " + "able to restart the Tor software. Please check your Task " + "Manager to ensure there are no other Tor processes running.")), + VMessageBox::Ok|VMessageBox::Default); + } else { + retry = true; + } + } + } else { + /* Something else went wrong */ + int ret = VMessageBox::warning(this, + tr("Authentication Error"), + p(tr("Vidalia was unable to authenticate to the Tor software. " + "(%1)").arg(errmsg)) + + p(tr("Please check your control port authentication " + "settings.")), + VMessageBox::ShowSettings|VMessageBox::Default, + VMessageBox::Cancel|VMessageBox::Escape); + + if (ret == VMessageBox::ShowSettings) + showConfigDialog(ConfigDialog::Advanced); + } + + if (_torControl->isRunning()) + if (_isVidaliaRunningTor) + stop(); + else + disconnect(); + if (retry) + start(); }
-/** Starts the proxy server, if appropriately configured */ +/** Called when Tor thinks its version is old or unrecommended, and displays + * a message notifying the user. */ void -MainWindow::startProxy() +MainWindow::dangerousTorVersion(tc::TorVersionStatus reason, + const QString ¤t, + const QStringList &recommended) { - VidaliaSettings settings; - QString executable = settings.getProxyExecutable(); - _proxyProcess->start(executable, settings.getProxyExecutableArguments()); + Q_UNUSED(current); + Q_UNUSED(recommended); + + if (reason == tc::ObsoleteTorVersion + || reason == tc::UnrecommendedTorVersion) + displayTorVersionWarning(); }
-/** Called when the proxy server fails to start, for example, because - * the path specified didn't lead to an executable. */ +/** Called when Tor thinks its version is old or unrecommended, and displays a + * message notifying the user. */ void -MainWindow::onProxyFailed(QString errmsg) +MainWindow::displayTorVersionWarning() { - Q_UNUSED(errmsg); - - /* Display an error message and see if the user wants some help */ - VMessageBox::warning(this, tr("Error starting proxy server"), - tr("Vidalia was unable to start the configured proxy server"), - VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape); + static bool alreadyWarned = false; + + if (!alreadyWarned) { +#if !defined(USE_AUTOUPDATE) + QString website = "https://www.torproject.org/"; +# if QT_VERSION >= 0x040200 + website = QString("<a href="%1">%1</a>").arg(website); +# endif + + VMessageBox::information(this, tr("Tor Update Available"), + p(tr("The currently installed version of Tor is out of date or no longer " + "recommended. Please visit the Tor website to download the latest " + "version.")) + p(tr("Tor website: %1").arg(website)), + VMessageBox::Ok); +#else + int ret = VMessageBox::information(this, + tr("Tor Update Available"), + p(tr("The currently installed version of Tor is out of date " + "or no longer recommended.")) + + p(tr("Would you like to check if a newer package is " + "available for installation?")), + VMessageBox::Yes|VMessageBox::Default, + VMessageBox::No|VMessageBox::Escape); + + if (ret == VMessageBox::Yes) + checkForUpdatesWithUi(); +#endif + alreadyWarned = true; + } }
/** Called when Tor's bootstrapping status changes. <b>bse</b> represents @@ -858,423 +1001,115 @@ MainWindow::bootstrapStatusChanged(const BootstrapStatus &bs) setStartupProgress(percentComplete, description); }
-/** Updates the UI to reflect Tor's current <b>status</b>. Returns the - * previously set TorStatus value.*/ -MainWindow::TorStatus -MainWindow::updateTorStatus(TorStatus status) +/** Called when Tor has successfully established a circuit. */ +void +MainWindow::circuitEstablished() { - QString statusText, actionText; - QString trayIconFile, statusIconFile; - TorStatus prevStatus = _status; - - vNotice("Tor status changed from '%1' to '%2'.") - .arg(toString(prevStatus)).arg(toString(status)); - _status = status; + updateTorStatus(CircuitEstablished); + // TODO: fix hardcoded total length + setStartupProgress(130, + tr("Connected to the Tor network!"));
- if (status == Stopped) { - statusText = tr("Tor is not running"); - actionText = tr("Start Tor"); - trayIconFile = IMG_TOR_STOPPED; - statusIconFile = IMG_TOR_STOPPED_48; - _actionStartStopTor->setEnabled(true); - _actionStartStopTor->setText(actionText); - _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16)); - ui.lblStartStopTor->setEnabled(true); - ui.lblStartStopTor->setText(actionText); - ui.lblStartStopTor->setPixmap(QPixmap(IMG_START_TOR_48)); - ui.lblStartStopTor->setStatusTip(actionText); +#if defined(USE_AUTOUPDATE) + VidaliaSettings settings; + if (settings.isAutoUpdateEnabled()) { + QDateTime lastCheckedAt = settings.lastCheckedForUpdates(); + if (UpdateProcess::shouldCheckForUpdates(lastCheckedAt)) { + /* Initiate a background check for updates now */ + _updateTimer.stop(); + checkForUpdates(); + } + } +#endif +}
- /* XXX: This might need to be smarter if we ever start connecting other - * slots to these triggered() and clicked() signals. */ - QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0); - QObject::disconnect(ui.lblStartStopTor, SIGNAL(clicked()), this, 0); - connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start())); - connect(ui.lblStartStopTor, SIGNAL(clicked()), this, SLOT(start())); - setStartupProgressVisible(false); - } else if (status == Stopping) { - if (_delayedShutdownStarted) { - statusText = tr("Your relay is shutting down.\n" - "Click 'Stop' again to stop your relay now."); - } else { - statusText = tr("Tor is shutting down"); - } - trayIconFile = IMG_TOR_STOPPING; - statusIconFile = IMG_TOR_STOPPING_48; - - ui.lblStartStopTor->setStatusTip(tr("Stop Tor Now")); - } else if (status == Started) { - actionText = tr("Stop Tor"); - _actionStartStopTor->setEnabled(true); - _actionStartStopTor->setText(actionText); - _actionStartStopTor->setIcon(QIcon(IMG_STOP_TOR_16)); - ui.lblStartStopTor->setEnabled(true); - ui.lblStartStopTor->setText(actionText); - ui.lblStartStopTor->setPixmap(QPixmap(IMG_STOP_TOR_48)); - ui.lblStartStopTor->setStatusTip(actionText); - - /* XXX: This might need to be smarter if we ever start connecting other - * slots to these triggered() and clicked() signals. */ - QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0); - QObject::disconnect(ui.lblStartStopTor, SIGNAL(clicked()), this, 0); - connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(stop())); - connect(ui.lblStartStopTor, SIGNAL(clicked()), this, SLOT(stop())); - } else if (status == Starting) { - statusText = tr("Starting the Tor software"); - trayIconFile = IMG_TOR_STARTING; - statusIconFile = IMG_TOR_STARTING_48; - _actionStartStopTor->setEnabled(false); - ui.lblStartStopTor->setText(tr("Starting Tor")); - ui.lblStartStopTor->setEnabled(false); - ui.lblStartStopTor->setStatusTip(statusText); - setStartupProgressVisible(true); - setStartupProgress(STARTUP_PROGRESS_STARTING, statusText); - } else if (status == CircuitEstablished) { - statusText = tr("Connected to the Tor network!"); - trayIconFile = IMG_TOR_RUNNING; - statusIconFile = IMG_TOR_RUNNING_48; - setStartupProgressVisible(false); - } - - /* Update the tray icon */ - if (!trayIconFile.isEmpty()) { - setTrayIcon(trayIconFile); - } - /* Update the status banner on the control panel */ - if (!statusIconFile.isEmpty()) - ui.lblTorStatusImg->setPixmap(QPixmap(statusIconFile)); - if (!statusText.isEmpty()) { - _trayIcon.setToolTip(statusText); - ui.lblTorStatus->setText(statusText); - } - return prevStatus; -} - -/** Called when the "show on startup" checkbox is toggled. */ -void -MainWindow::toggleShowOnStartup(bool checked) -{ - VidaliaSettings settings; - settings.setShowMainWindowAtStart(checked); -} - -/** Sets the visibility of the startup status description and progress bar to - * <b>visible</b>. */ -void -MainWindow::setStartupProgressVisible(bool visible) -{ - /* XXX: We force a repaint() to make sure the progress bar and onion status - * icon don't overlap briefly. This is pretty hacktastic. */ - if (visible) { - ui.lblTorStatus->setVisible(false); - ui.lblTorStatusImg->setVisible(false); - repaint(ui.grpStatus->rect()); - ui.lblStartupProgress->setVisible(true); - ui.progressBar->setVisible(true); - } else { - ui.lblStartupProgress->setVisible(false); - ui.progressBar->setVisible(false); - repaint(ui.grpStatus->rect()); - ui.lblTorStatus->setVisible(true); - ui.lblTorStatusImg->setVisible(true); - } -} - -/** Sets the progress bar completion value to <b>progressValue</b> and sets - * the status text to <b>description</b>. */ +/** Called when Tor thinks the user has tried to connect to a port that + * typically is used for unencrypted applications. Warns the user and allows + * them to ignore future warnings on <b>port</b>. It is possible that Tor + * will produce multiple asynchronous status events warning of dangerous ports + * while the message box is displayed (for example, while the user is away + * from the keyboard), so subsequent messages will be discarded until the + * first message box is dismissed. */ void -MainWindow::setStartupProgress(int progressValue, - const QString &description) -{ - ui.progressBar->setValue(progressValue); - ui.lblStartupProgress->setText(description); - _trayIcon.setToolTip(description); -} - -/** Attempts to start Tor. If Tor fails to start, then startFailed() will be - * called with an error message containing the reason. */ -void -MainWindow::start() +MainWindow::warnDangerousPort(quint16 port, bool rejected) { - TorSettings settings; - QStringList args; - - updateTorStatus(Starting); + static QMessageBox *dlg = 0;
- /* Check if Tor is already running separately */ - if(settings.getControlMethod() == ControlMethod::Port) { - if (net_test_connect(settings.getControlAddress(), - settings.getControlPort())) { - started(); - return; - } - } else { - if (socket_test_connect(settings.getSocketPath())) { - started(); - return; - } - } + /* Don't display another message box until the first one is dismissed */ + if (dlg) + return;
- /* Make sure the torrc we want to use really exists. */ - QString torrc = settings.getTorrc(); - if (!torrc.isEmpty()) { - if (!QFileInfo(torrc).exists()) - touch_file(torrc, true); - args << "-f" << torrc; - } + QString application; + switch (port) { + case 23: + application = tr(", probably Telnet, "); + break;
- /* Specify Tor's data directory, if different from the default */ - QString dataDirectory = settings.getDataDirectory(); - if (!dataDirectory.isEmpty()) - args << "DataDirectory" << expand_filename(dataDirectory); - - if(settings.getControlMethod() == ControlMethod::Port) { - /* Add the intended control port value */ - quint16 controlPort = settings.getControlPort(); - if (controlPort) - args << "ControlPort" << QString::number(controlPort); - } else { - QString path = settings.getSocketPath(); - args << "ControlSocket" << path; - } - - /* Add the control port authentication arguments */ - switch (settings.getAuthenticationMethod()) { - case TorSettings::PasswordAuth: - if (! vApp->readPasswordFromStdin()) { - if (settings.useRandomPassword()) { - _controlPassword = TorSettings::randomPassword(); - _useSavedPassword = false; - } else { - _controlPassword = settings.getControlPassword(); - _useSavedPassword = true; - } - } - args << "HashedControlPassword" - << TorSettings::hashPassword(_controlPassword); - break; - case TorSettings::CookieAuth: - args << "CookieAuthentication" << "1"; + case 109: + case 110: + case 143: + application = tr(", probably an email client, "); break; - default: - args << "CookieAuthentication" << "0"; - }
- /* This doesn't get set to false until Tor is actually up and running, so we - * don't yell at users twice if their Tor doesn't even start, due to the fact - * that QProcess::stopped() is emitted even if the process didn't even - * start. */ - _isIntentionalExit = true; - /* Kick off the Tor process */ - _torControl->start(settings.getExecutable(), args); -} - -/** Called when the user changes a setting that needs Tor restarting */ -void -MainWindow::restart() -{ - if(_torControl->stop()) { - start(); + default: + application = " "; } -} - -/** Called when the Tor process fails to start, for example, because the path - * specified to the Tor executable didn't lead to an executable. */ -void -MainWindow::startFailed(QString errmsg) -{ - /* We don't display the error message for now, because the error message - * that Qt gives us in this instance is almost always "Unknown Error". That - * will make users sad. */ - Q_UNUSED(errmsg); - - updateTorStatus(Stopped);
- /* Display an error message and see if the user wants some help */ - int response = VMessageBox::warning(this, tr("Error Starting Tor"), - tr("Vidalia was unable to start Tor. Check your settings " - "to ensure the correct name and location of your Tor " - "executable is specified."), - VMessageBox::ShowSettings|VMessageBox::Default, - VMessageBox::Cancel|VMessageBox::Escape, - VMessageBox::Help); + QString text = tr("One of your applications%1appears to be making a " + "potentially unencrypted and unsafe connection to port %2.") + .arg(application).arg(port);
- if (response == VMessageBox::ShowSettings) { - /* Show the settings dialog so the user can make sure they're pointing to - * the correct Tor. */ - showConfigDialog(); - } else if (response == VMessageBox::Help) { - /* Show troubleshooting information about starting Tor */ - showHelpDialog("troubleshooting.start"); + QString extraText = p(tr("Anything sent over this connection could be " + "monitored. Please check your application's " + "configuration and use only encrypted protocols, " + "such as SSL, if possible.")); + if (rejected) { + extraText.append(p(tr("Tor has automatically closed your connection in " + "order to protect your anonymity."))); } -} - -/** Slot: Called when the Tor process is started. It will connect the control - * socket and set the icons and tooltips accordingly. */ -void -MainWindow::started() -{ - TorSettings settings; - - updateTorStatus(Started); - - /* Now that Tor is running, we want to know if it dies when we didn't want - * it to. */ - _isIntentionalExit = false; - /* We haven't started a delayed shutdown yet. */ - _delayedShutdownStarted = false; - /* Remember whether we started Tor or not */ - _isVidaliaRunningTor = _torControl->isVidaliaRunningTor(); - /* Try to connect to Tor's control port */ - if(settings.getControlMethod() == ControlMethod::Port) - _torControl->connect(settings.getControlAddress(), - settings.getControlPort()); - else - _torControl->connect(settings.getSocketPath()); - setStartupProgress(STARTUP_PROGRESS_CONNECTING, tr("Connecting to Tor")); -} - -/** Called when the connection to the control socket fails. The reason will be - * given in the errmsg parameter. */ -void -MainWindow::connectFailed(QString errmsg) -{ - /* Ok, ok. It really isn't going to connect. I give up. */ - int response = VMessageBox::warning(this, - tr("Connection Error"), p(errmsg), - VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, - VMessageBox::Retry, VMessageBox::Help);
+ dlg = new QMessageBox(QMessageBox::Warning, + tr("Potentially Unsafe Connection"), text, + QMessageBox::Ok | QMessageBox::Ignore); + dlg->setInformativeText(extraText); + dlg->setDefaultButton(QMessageBox::Ok); + dlg->setEscapeButton(QMessageBox::Ok);
- if (response == VMessageBox::Retry) { - /* Let's give it another try. */ + int ret = dlg->exec(); + if (ret == QMessageBox::Ignore) { + TorControl *tc = Vidalia::torControl(); TorSettings settings; - _torControl->connect(settings.getControlAddress(), - settings.getControlPort()); - } else { - /* Show the help browser (if requested) */ - if (response == VMessageBox::Help) - showHelpDialog("troubleshooting.connect"); - /* Since Vidalia can't connect, we can't really do much, so stop Tor. */ - _torControl->stop(); - } -} - -/** Disconnects the control socket and stops the Tor process. */ -bool -MainWindow::stop() -{ - ServerSettings server(_torControl); - QString errmsg; - TorStatus prevStatus; - bool rc; - - /* If we're running a server, give users the option of terminating - * gracefully so clients have time to find new servers. */ - if (server.isServerEnabled() && !_delayedShutdownStarted) { - /* Ask the user if they want to shutdown nicely. */ - int response = VMessageBox::question(this, tr("Relaying is Enabled"), - tr("You are currently running a relay. " - "Terminating your relay will interrupt any " - "open connections from clients.\n\n" - "Would you like to shutdown gracefully and " - "give clients time to find a new relay?"), - VMessageBox::Yes|VMessageBox::Default, - VMessageBox::No, - VMessageBox::Cancel|VMessageBox::Escape); - if (response == VMessageBox::Yes) - _delayedShutdownStarted = true; - else if (response == VMessageBox::Cancel) - return false; - } - - prevStatus = updateTorStatus(Stopping); - if (_delayedShutdownStarted) { - /* Start a delayed shutdown */ - rc = _torControl->signal(TorSignal::Shutdown, &errmsg); - } else { - /* We want Tor to stop now, regardless of whether we're a server. */ - _isIntentionalExit = true; - rc = _torControl->stop(&errmsg); - } - - if (!rc) { - /* We couldn't tell Tor to stop, for some reason. */ - int response = VMessageBox::warning(this, tr("Error Shutting Down"), - p(tr("Vidalia was unable to stop the Tor software.")) - + p(errmsg), - VMessageBox::Ok|VMessageBox::Default|VMessageBox::Escape, - VMessageBox::Help); - - if (response == VMessageBox::Help) { - /* Show some troubleshooting help */ - showHelpDialog("troubleshooting.stop"); - } - /* Tor is still running since stopping failed */ - _isIntentionalExit = false; - _delayedShutdownStarted = false; - updateTorStatus(prevStatus); - } - return rc; -} + QStringList portList; + QList<quint16> ports; + int idx;
-/** Slot: Called when the Tor process has exited. It will adjust the tray - * icons and tooltips accordingly. */ -void -MainWindow::stopped(int exitCode, QProcess::ExitStatus exitStatus) -{ - updateTorStatus(Stopped); + ports = settings.getWarnPlaintextPorts(); + idx = ports.indexOf(port); + if (idx >= 0) { + ports.removeAt(idx); + settings.setWarnPlaintextPorts(ports);
- /* If we didn't intentionally close Tor, then check to see if it crashed or - * if it closed itself and returned an error code. */ - if (!_isIntentionalExit) { - /* A quick overview of Tor's code tells me that if it catches a SIGTERM or - * SIGINT, Tor will exit(0). We might need to change this warning message - * if this turns out to not be the case. */ - if (exitStatus == QProcess::CrashExit || exitCode != 0) { - int ret = VMessageBox::warning(this, tr("Unexpected Error"), - tr("Vidalia detected that the Tor software exited " - "unexpectedly.\n\n" - "Please check the message log for recent " - "warning or error messages."), - VMessageBox::Ok|VMessageBox::Escape, - VMessageBox::ShowLog|VMessageBox::Default, - VMessageBox::Help); - if (ret == VMessageBox::ShowLog) - _messageLog->showWindow(); - else if (ret == VMessageBox::Help) - showHelpDialog("troubleshooting.torexited"); + foreach (quint16 port, ports) { + portList << QString::number(port); + } + tc->setConf("WarnPlaintextPorts", portList.join(",")); + portList.clear(); } - } -} - -/** Called when the control socket has successfully connected to Tor. */ -void -MainWindow::connected() -{ - authenticate(); -}
-/** Called when Vidalia wants to disconnect from a Tor it did not start. */ -void -MainWindow::disconnect() -{ - _torControl->disconnect(); -} + ports = settings.getRejectPlaintextPorts(); + idx = ports.indexOf(port); + if (idx >= 0) { + ports.removeAt(idx); + settings.setRejectPlaintextPorts(ports);
-/** Called when the control socket has been disconnected. */ -void -MainWindow::disconnected() -{ - if (!_isVidaliaRunningTor) { - /* If we didn't start our own Tor process, interpret losing the control - * connection as "Tor is stopped". */ - updateTorStatus(Stopped); + foreach (quint16 port, ports) { + portList << QString::number(port); + } + tc->setConf("RejectPlaintextPorts", portList.join(",")); + } } - - /*XXX We should warn here if we get disconnected when we didn't intend to */ - _actionNewIdentity->setEnabled(false); - ui.lblNewIdentity->setEnabled(false); - _isVidaliaRunningTor = false; + delete dlg; + dlg = 0; }
/** Attempts to authenticate to Tor's control port, depending on the @@ -1353,132 +1188,19 @@ cancel: return false; }
-/** Called when Vidalia has successfully authenticated to Tor. */ -void -MainWindow::authenticated() -{ - ServerSettings serverSettings(_torControl); - QString errmsg; - - updateTorStatus(Authenticated); - - /* If Tor doesn't have bootstrapping events, then update the current - * status string and bump the progress bar along a bit. */ - if (_torControl->getTorVersion() < 0x020101) { - setStartupProgress(STARTUP_PROGRESS_CIRCUITBUILD, - tr("Connecting to the Tor network")); - } - - /* Let people click on their beloved "New Identity" button */ - _actionNewIdentity->setEnabled(true); - ui.lblNewIdentity->setEnabled(true); - - /* Register for any pertinent asynchronous events. */ - if (!_torControl->setEvents(&errmsg)) { - VMessageBox::warning(this, tr("Error Registering for Events"), - p(tr("Vidalia was unable to register for some events. " - "Many of Vidalia's features may be unavailable.")) - + p(errmsg), - VMessageBox::Ok); - } else { - /* Stop reading from Tor's stdout immediately, since we successfully - * registered for Tor events, including any desired log events. */ - _torControl->closeTorStdout(); - } - - /* Configure UPnP port forwarding if needed */ - serverSettings.configurePortForwarding(); - - /* Check if Tor has a circuit established */ - if (_torControl->isCircuitEstablished()) - circuitEstablished(); - /* Check the status of Tor's version */ - if (_torControl->getTorVersion() >= 0x020001) - checkTorVersion(); - if (_torControl->getTorVersion() >= 0x020102) { - BootstrapStatus status = _torControl->bootstrapStatus(); - if (status.isValid()) - bootstrapStatusChanged(status); - } -} - -/** Called when Vidalia fails to authenticate to Tor. The failure reason is - * specified in <b>errmsg</b>. */ +/** Checks the status of the current version of Tor to see if it's old, + * unrecommended, or obsolete. */ void -MainWindow::authenticationFailed(QString errmsg) +MainWindow::checkTorVersion() { - bool retry = false; - - vWarn("Authentication failed: %1").arg(errmsg); - - /* Parsing log messages is evil, but we're left with little option */ - if (errmsg.contains("Password did not match")) { - ControlPasswordInputDialog dlg; - connect(&dlg, SIGNAL(helpRequested(QString)), - this, SLOT(showHelpDialog(QString))); - - qint64 torPid = 0; - -#if defined(Q_OS_WIN32) - QHash<qint64, QString> procs = process_list(); - foreach (qint64 pid, procs.keys()) { - if (! procs.value(pid).compare("tor.exe", Qt::CaseInsensitive)) { - torPid = pid; - break; - } - } - dlg.setResetEnabled(torPid > 0); -#else - dlg.setResetEnabled(false); -#endif - - int ret = dlg.exec(); - if (ret == QDialogButtonBox::Ok) { - if (dlg.isSavePasswordChecked()) { - TorSettings settings; - settings.setAuthenticationMethod(TorSettings::PasswordAuth); - settings.setUseRandomPassword(false); - settings.setControlPassword(dlg.password()); - _useSavedPassword = true; - } else { - _controlPassword = dlg.password(); - _useSavedPassword = false; - } - retry = true; - } else if (ret == QDialogButtonBox::Reset) { - if (! process_kill(torPid)) { - VMessageBox::warning(this, - tr("Password Reset Failed"), - p(tr("Vidalia tried to reset Tor's control password, but was not " - "able to restart the Tor software. Please check your Task " - "Manager to ensure there are no other Tor processes running.")), - VMessageBox::Ok|VMessageBox::Default); - } else { - retry = true; - } + QString status; + if (_torControl->getInfo("status/version/current", status)) { + if (!status.compare("old", Qt::CaseInsensitive) + || !status.compare("unrecommended", Qt::CaseInsensitive) + || !status.compare("obsolete", Qt::CaseInsensitive)) { + displayTorVersionWarning(); } - } else { - /* Something else went wrong */ - int ret = VMessageBox::warning(this, - tr("Authentication Error"), - p(tr("Vidalia was unable to authenticate to the Tor software. " - "(%1)").arg(errmsg)) + - p(tr("Please check your control port authentication " - "settings.")), - VMessageBox::ShowSettings|VMessageBox::Default, - VMessageBox::Cancel|VMessageBox::Escape); - - if (ret == VMessageBox::ShowSettings) - showConfigDialog(ConfigDialog::Advanced); } - - if (_torControl->isRunning()) - if (_isVidaliaRunningTor) - stop(); - else - disconnect(); - if (retry) - start(); }
/** Searches for and attempts to load the control authentication cookie. This @@ -1529,222 +1251,173 @@ MainWindow::loadControlCookie(QString cookiePath) return QByteArray(); }
-/** Called when Tor has successfully established a circuit. */ -void -MainWindow::circuitEstablished() +/** Updates the UI to reflect Tor's current <b>status</b>. Returns the + * previously set TorStatus value.*/ +MainWindow::TorStatus +MainWindow::updateTorStatus(TorStatus status) { - updateTorStatus(CircuitEstablished); - setStartupProgress(ui.progressBar->maximum(), - tr("Connected to the Tor network!")); - startSubprocesses(); + QString statusText, actionText; + QString trayIconFile, statusIconFile; + TorStatus prevStatus = _status; + + vNotice("Tor status changed from '%1' to '%2'.") + .arg(toString(prevStatus)).arg(toString(status)); + _status = status;
-#if defined(USE_AUTOUPDATE) - VidaliaSettings settings; - if (settings.isAutoUpdateEnabled()) { - QDateTime lastCheckedAt = settings.lastCheckedForUpdates(); - if (UpdateProcess::shouldCheckForUpdates(lastCheckedAt)) { - /* Initiate a background check for updates now */ - _updateTimer.stop(); - checkForUpdates(); - } - } -#endif -} + if (status == Stopped) { + statusText = tr("Tor is not running"); + actionText = tr("Start Tor"); + trayIconFile = IMG_TOR_STOPPED; + statusIconFile = IMG_TOR_STOPPED_48; + _actionStartStopTor->setEnabled(true); + _actionStartStopTor->setIcon(QIcon(IMG_START_TOR_16)); + _actionStartStopTor->setText(actionText); + _actionStartTor->setEnabled(true);
-/** Checks the status of the current version of Tor to see if it's old, - * unrecommended, or obsolete. */ -void -MainWindow::checkTorVersion() -{ - QString status; - if (_torControl->getInfo("status/version/current", status)) { - if (!status.compare("old", Qt::CaseInsensitive) - || !status.compare("unrecommended", Qt::CaseInsensitive) - || !status.compare("obsolete", Qt::CaseInsensitive)) { - displayTorVersionWarning(); - } + /* XXX: This might need to be smarter if we ever start connecting other + * slots to these triggered() and clicked() signals. */ + QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0); + connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(start())); + setStartupProgressVisible(false); + } else if (status == Stopping) { + _actionStopTor->setEnabled(false); + _actionRestartTor->setEnabled(false); + if (_delayedShutdownStarted) { + statusText = tr("Your relay is shutting down.\n" + "Click 'Stop' again to stop your relay now."); + } else { + statusText = tr("Tor is shutting down"); + } + trayIconFile = IMG_TOR_STOPPING; + statusIconFile = IMG_TOR_STOPPING_48; + +// ui.btnStartStopTor->setStatusTip(tr("Stop Tor Now")); + } else if (status == Started) { + actionText = tr("Stop Tor"); + _actionStartStopTor->setEnabled(true); + _actionStartStopTor->setIcon(QIcon(IMG_STOP_TOR_16)); + _actionStartStopTor->setText(actionText); + + /* XXX: This might need to be smarter if we ever start connecting other + * slots to these triggered() and clicked() signals. */ + QObject::disconnect(_actionStartStopTor, SIGNAL(triggered()), this, 0); + connect(_actionStartStopTor, SIGNAL(triggered()), this, SLOT(stop())); + } else if (status == Starting) { + statusText = tr("Starting the Tor software"); + trayIconFile = IMG_TOR_STARTING; + statusIconFile = IMG_TOR_STARTING_48; + _actionStartStopTor->setEnabled(false); + _actionStartTor->setEnabled(false); + setStartupProgressVisible(true); + setStartupProgress(STARTUP_PROGRESS_STARTING, statusText); + } else if (status == CircuitEstablished) { + statusText = tr("Connected to the Tor network!"); + trayIconFile = IMG_TOR_RUNNING; + statusIconFile = IMG_TOR_RUNNING_48; + setStartupProgressVisible(false); } -} - -/** Called when Tor thinks its version is old or unrecommended, and displays - * a message notifying the user. */ -void -MainWindow::dangerousTorVersion(tc::TorVersionStatus reason, - const QString ¤t, - const QStringList &recommended) -{ - Q_UNUSED(current); - Q_UNUSED(recommended);
- if (reason == tc::ObsoleteTorVersion - || reason == tc::UnrecommendedTorVersion) - displayTorVersionWarning(); + /* Update the tray icon */ + if (!trayIconFile.isEmpty()) { + setTrayIcon(trayIconFile); + } + /* Update the status banner on the control panel */ + if (!statusIconFile.isEmpty()) + _statusTab.setTorStatus(QPixmap(statusIconFile)); + if (!statusText.isEmpty()) { + _trayIcon.setToolTip(statusText); + _statusTab.setTorStatus(statusText); + } + return prevStatus; }
-/** Called when Tor thinks its version is old or unrecommended, and displays a - * message notifying the user. */ +/** Sets the current tray or dock icon image to <b>iconFile</b>. */ void -MainWindow::displayTorVersionWarning() +MainWindow::setTrayIcon(const QString &iconFile) { - static bool alreadyWarned = false; - - if (!alreadyWarned) { -#if !defined(USE_AUTOUPDATE) - QString website = "https://www.torproject.org/"; -# if QT_VERSION >= 0x040200 - website = QString("<a href="%1">%1</a>").arg(website); -# endif - - VMessageBox::information(this, tr("Tor Update Available"), - p(tr("The currently installed version of Tor is out of date or no longer " - "recommended. Please visit the Tor website to download the latest " - "version.")) + p(tr("Tor website: %1").arg(website)), - VMessageBox::Ok); -#else - int ret = VMessageBox::information(this, - tr("Tor Update Available"), - p(tr("The currently installed version of Tor is out of date " - "or no longer recommended.")) - + p(tr("Would you like to check if a newer package is " - "available for installation?")), - VMessageBox::Yes|VMessageBox::Default, - VMessageBox::No|VMessageBox::Escape); - - if (ret == VMessageBox::Yes) - checkForUpdatesWithUi(); +#if defined(Q_WS_MAC) + QApplication::setWindowIcon(QPixmap(iconFile)); #endif - alreadyWarned = true; - } + _trayIcon.setIcon(QIcon(iconFile)); }
-/** Called when Tor thinks the user has tried to connect to a port that - * typically is used for unencrypted applications. Warns the user and allows - * them to ignore future warnings on <b>port</b>. It is possible that Tor - * will produce multiple asynchronous status events warning of dangerous ports - * while the message box is displayed (for example, while the user is away - * from the keyboard), so subsequent messages will be discarded until the - * first message box is dismissed. */ -void -MainWindow::warnDangerousPort(quint16 port, bool rejected) +/** Converts a TorStatus enum value to a string for debug logging purposes. */ +QString +MainWindow::toString(TorStatus status) { - static QMessageBox *dlg = 0; - - /* Don't display another message box until the first one is dismissed */ - if (dlg) - return; - - QString application; - switch (port) { - case 23: - application = tr(", probably Telnet, "); - break; - - case 109: - case 110: - case 143: - application = tr(", probably an email client, "); - break; - - default: - application = " "; - } - - QString text = tr("One of your applications %1 appears to be making a " - "potentially unencrypted and unsafe connection to port %2.") - .arg(application).arg(port); - - QString extraText = p(tr("Anything sent over this connection could be " - "monitored. Please check your application's " - "configuration and use only encrypted protocols, " - "such as SSL, if possible.")); - if (rejected) { - extraText.append(p(tr("Tor has automatically closed your connection in " - "order to protect your anonymity."))); + switch (status) { + /* These strings only appear in debug logs, so they should not be + * translated. */ + case Unset: return "Unset"; + case Stopping: return "Stopping"; + case Stopped: return "Stopped"; + case Starting: return "Starting"; + case Started: return "Started"; + case Authenticating: return "Authenticating"; + case Authenticated: return "Authenticated"; + case CircuitEstablished: return "Circuit Established"; + default: break; } + return "Unknown"; +}
- dlg = new QMessageBox(QMessageBox::Warning, - tr("Potentially Unsafe Connection"), text, - QMessageBox::Ok | QMessageBox::Ignore); - dlg->setInformativeText(extraText); - dlg->setDefaultButton(QMessageBox::Ok); - dlg->setEscapeButton(QMessageBox::Ok); - - int ret = dlg->exec(); - if (ret == QMessageBox::Ignore) { - TorControl *tc = Vidalia::torControl(); - TorSettings settings; - QStringList portList; - QList<quint16> ports; - int idx; - - ports = settings.getWarnPlaintextPorts(); - idx = ports.indexOf(port); - if (idx >= 0) { - ports.removeAt(idx); - settings.setWarnPlaintextPorts(ports); - - foreach (quint16 port, ports) { - portList << QString::number(port); - } - tc->setConf("WarnPlaintextPorts", portList.join(",")); - portList.clear(); - } - - ports = settings.getRejectPlaintextPorts(); - idx = ports.indexOf(port); - if (idx >= 0) { - ports.removeAt(idx); - settings.setRejectPlaintextPorts(ports); - - foreach (quint16 port, ports) { - portList << QString::number(port); - } - tc->setConf("RejectPlaintextPorts", portList.join(",")); - } +/** Called when the user changes a setting that needs Tor restarting */ +void +MainWindow::restart() +{ + if(_torControl->stop()) { + start(); } - delete dlg; - dlg = 0; }
-/** Creates and displays Vidalia's About dialog. */ +/** Sets the visibility of the startup status description and progress bar to + * <b>visible</b>. */ void -MainWindow::showAboutDialog() +MainWindow::setStartupProgressVisible(bool visible) { - AboutDialog dlg(this); - dlg.exec(); + _statusTab.setTorStatusVisible(!visible); + _statusTab.setProgressVisible(visible); }
-/** Displays the help browser and displays the most recently viewed help - * topic. */ +/** Sets the progress bar completion value to <b>progressValue</b> and sets + * the status text to <b>description</b>. */ void -MainWindow::showHelpDialog() +MainWindow::setStartupProgress(int progressValue, + const QString &description) { - showHelpDialog(QString()); + _statusTab.setProgress(progressValue, description); + _trayIcon.setToolTip(description); }
-/**< Shows the help browser and displays the given help <b>topic</b>. */ +/** Called when Vidalia wants to disconnect from a Tor it did not start. */ void -MainWindow::showHelpDialog(const QString &topic) +MainWindow::disconnect() { - static HelpBrowser *helpBrowser = 0; - if (!helpBrowser) - helpBrowser = new HelpBrowser(this); - helpBrowser->showWindow(topic); + _torControl->disconnect(); }
-/** Creates and displays the Configuration dialog with the current page set to - * <b>page</b>. */ +/** Called when the control socket has been disconnected. */ void -MainWindow::showConfigDialog(ConfigDialog::Page page) +MainWindow::disconnected() { - _configDialog->showWindow(page); + if (!_isVidaliaRunningTor) { + /* If we didn't start our own Tor process, interpret losing the control + * connection as "Tor is stopped". */ + updateTorStatus(Stopped); + } + + /*XXX We should warn here if we get disconnected when we didn't intend to */ + _actionNewIdentity->setEnabled(false); + _isVidaliaRunningTor = false; }
-/** Displays the Configuration dialog, set to the Server page. */ void -MainWindow::showServerConfigDialog() +MainWindow::showConfigDialog(ConfigDialog::Page page) { - showConfigDialog(ConfigDialog::Server); + ConfigDialog *configDialog = new ConfigDialog(); + connect(configDialog, SIGNAL(helpRequested(QString)), + this, SLOT(showHelpDialog(QString))); + configDialog->showWindow(page); }
/** Called when the user selects the "New Identity" action from the menu. */ @@ -1765,7 +1438,7 @@ MainWindow::newIdentity()
/* Disable the New Identity button for MIN_NEWIDENTITY_INTERVAL */ _actionNewIdentity->setEnabled(false); - ui.lblNewIdentity->setEnabled(false); +// ui.lblNewIdentity->setEnabled(false); QTimer::singleShot(MIN_NEWIDENTITY_INTERVAL, this, SLOT(enableNewIdentity()));
@@ -1787,28 +1460,106 @@ MainWindow::enableNewIdentity() { if (_torControl->isConnected()) { _actionNewIdentity->setEnabled(true); - ui.lblNewIdentity->setEnabled(true); } }
-/** Converts a TorStatus enum value to a string for debug logging purposes. */ -QString -MainWindow::toString(TorStatus status) +void +MainWindow::handleCloseTab(int index) { - switch (status) { - /* These strings only appear in debug logs, so they should not be - * translated. */ - case Unset: return "Unset"; - case Stopping: return "Stopping"; - case Stopped: return "Stopped"; - case Starting: return "Starting"; - case Started: return "Started"; - case Authenticating: return "Authenticating"; - case Authenticated: return "Authenticated"; - case CircuitEstablished: return "Circuit Established"; - default: break; + /* If the tab that's going to be closed is the status one + * don't do it */ + if(index == 0) + return; + + delTab(index); +} + +void +MainWindow::addTab(VidaliaTab *tab) +{ + /** If the tab's already open, display it and delete the + * instanse passed */ + if(_tabMap.contains(tab->getTitle())) { + ui.tabWidget->setCurrentIndex(_tabMap.indexOf(tab->getTitle())); + /** Exception for tabs that need to be always created */ + if(tab != _messageLog && tab != &_statusTab && tab != &_netViewer) + tab->deleteLater(); + return; } - return "Unknown"; + + ui.tabWidget->addTab(tab, tab->getTitle()); + ui.tabWidget->setCurrentIndex(ui.tabWidget->count() - 1); + /** The new tab is added to the last position */ + _tabMap << tab->getTitle(); + connect(tab, SIGNAL(helpRequested(QString)), + this, SLOT(showHelpDialog(QString))); +} + +void +MainWindow::delTab(int index) +{ + if(index == -1) + index = ui.tabWidget->currentIndex(); + + VidaliaTab *tab = qobject_cast<VidaliaTab*>(ui.tabWidget->widget(index)); + if(tab != _messageLog && tab != &_statusTab && tab != &_netViewer) { + QObject::disconnect(ui.tabWidget->widget(index), 0, 0, 0); + tab->deleteLater(); + } + ui.tabWidget->removeTab(index); + QString key = _tabMap.at(index); + _tabMap.removeAll(key); +} + +void +MainWindow::showStatusTab() +{ + addTab(&_statusTab); +} + +void +MainWindow::showMessageLogTab() +{ + addTab(_messageLog); +} + +void +MainWindow::showBandwithTab() +{ + BandwidthGraph *graph = new BandwidthGraph(this->statusBar()); + addTab(graph); +} + +/** Creates and displays Vidalia's About dialog. */ +void +MainWindow::showAboutDialog() +{ + AboutDialog dlg(this); + dlg.exec(); +} + +/** Displays the help browser and displays the most recently viewed help + * topic. */ +void +MainWindow::showHelpDialog() +{ + showHelpDialog(QString()); +} + +/**< Shows the help browser and displays the given help <b>topic</b>. */ +void +MainWindow::showHelpDialog(const QString &topic) +{ + static HelpBrowser *helpBrowser = 0; + if (!helpBrowser) + helpBrowser = new HelpBrowser(this); + helpBrowser->showWindow(topic); +} + +void +MainWindow::showNetViewerTab() +{ + addTab(&_netViewer); }
#if defined(USE_MINIUPNPC) diff --git a/src/vidalia/MainWindow.h b/src/vidalia/MainWindow.h index 1d913d0..20f5ef1 100644 --- a/src/vidalia/MainWindow.h +++ b/src/vidalia/MainWindow.h @@ -20,16 +20,10 @@ #include "ui_MainWindow.h"
#include "VidaliaWindow.h" -#include "HelperProcess.h" -#include "AboutDialog.h" -#include "MessageLog.h" -#include "BandwidthGraph.h" +#include "StatusTab.h" #include "ConfigDialog.h" -#include "HelpBrowser.h" +#include "MessageLog.h" #include "NetViewer.h" - -#include "TorControl.h" - #if defined(USE_AUTOUPDATE) #include "UpdateProcess.h" #include "UpdateProgressDialog.h" @@ -38,6 +32,8 @@ #include "UPNPControl.h" #endif
+#include "TorControl.h" + #include <QMainWindow> #include <QTimer> #include <QSystemTrayIcon> @@ -64,11 +60,6 @@ private slots: /** Respond to a double-click on the tray icon by opening the Control Panel * window. */ void trayIconActivated(QSystemTrayIcon::ActivationReason reason); - /** Displays the help browser and displays the most recently viewed help - * topic. */ - void showHelpDialog(); - /** Called when a child window requests the given help <b>topic</b>. */ - void showHelpDialog(const QString &topic); /** Called when the user selects "Start" from the menu. */ void start(); /** Called when the user changes a setting that needs Tor restarting */ @@ -107,26 +98,6 @@ private slots: /** Terminate the Tor process if it is being run under Vidalia, disconnect * all TorControl signals, and exit Vidalia. */ void aboutToQuit(); - /** Creates and displays Vidalia's About dialog. */ - void showAboutDialog(); - /** Creates and displays the Configuration dialog with the current page set - * to <b>page</b>. */ - void showConfigDialog(ConfigDialog::Page page = ConfigDialog::General); - /** Displays the Configuration dialog, set to the Server page. */ - void showServerConfigDialog(); - /** Called when the "show on startup" checkbox is toggled. */ - void toggleShowOnStartup(bool checked); - /** Called when the web browser or IM client have stopped */ - void onSubprocessFinished(int exitCode, QProcess::ExitStatus exitStatus); - /** Called periodically to check if the browser is running. If it is not, - * exit Vidalia cleanly */ - void onCheckForBrowser(); - /** Called web the web browser failed to start */ - void onBrowserFailed(QString errmsg); - /** Called web the IM client failed to start */ - void onIMFailed(QString errmsg); - /** Called when the proxy server fails to start */ - void onProxyFailed(QString errmsg);
/** Called when Tor has successfully established a circuit. */ void circuitEstablished(); @@ -142,6 +113,30 @@ private slots: void dangerousTorVersion(tc::TorVersionStatus reason, const QString &version, const QStringList &recommended); + void handleCloseTab(int index); + /** Creates and displays the Configuration dialog with the current page set + * to <b>page</b>. */ + void showConfigDialog(ConfigDialog::Page page = ConfigDialog::General); + /** Displays the Message Log tab */ + void showMessageLogTab(); + /** Displays the General Tor Status tab */ + void showStatusTab(); + /** Displays the Bandwidth graph tab */ + void showBandwithTab(); + /** Displays the Network map tab */ + void showNetViewerTab(); + /** Creates and displays Vidalia's About dialog. */ + void showAboutDialog(); + /** Displays the help browser and displays the most recently viewed help + * topic. */ + void showHelpDialog(); + /** Called when a child window requests the given help <b>topic</b>. */ + void showHelpDialog(const QString &topic); + + /** Adds a new tab to the MainWindow */ + void addTab(VidaliaTab *tab); + /** Deletes the tab at index if it exists and it isn't the Status tab */ + void delTab(int index = -1);
#if defined(USE_AUTOUPDATE) /** Called when the user clicks the 'Check Now' button in the General @@ -166,6 +161,7 @@ private slots: void installUpdatesFailed(const QString &errmsg); #endif
+ #if defined(USE_MINIUPNPC) /** Called when a UPnP error occurs. */ void upnpError(UPNPControl::UPNPError error); @@ -182,6 +178,9 @@ private: Authenticated, /**< Vidalia has authenticated to Tor. */ CircuitEstablished /**< Tor has built a circuit. */ }; + + void createGUI(); + void createConnections(); /** Create the actions on the tray menu or menubar */ void createActions(); /** Creates a tray icon with a context menu and adds it to the system @@ -189,19 +188,15 @@ private: void createTrayIcon(); /** Create the tray popup menu and it's submenus */ QMenu* createTrayMenu(); - /** Creates a default menubar on Mac */ + /** Creates a menubar */ void createMenuBar(); + /** Creates a toolbar */ + void createToolBar(); /** Sets the current tray or dock icon image to <b>iconFile</b>. */ void setTrayIcon(const QString &iconFile); /** Updates the UI to reflect Tor's current <b>status</b>. Returns the * previously set TorStatus value. */ TorStatus updateTorStatus(TorStatus status); - /** Start a web browser when given the directory containing the executable and profile */ - void launchBrowserFromDirectory(); - /** Starts the web browser, if appropriately configured */ - void startSubprocesses(); - /** Starts the proxy server, if appropriately configured */ - void startProxy(); /** Converts a TorStatus enum value to a string for debug logging purposes. */ QString toString(TorStatus status); /** Authenticates Vidalia to Tor's control port. */ @@ -234,22 +229,8 @@ private: bool _delayedShutdownStarted; /** Set to true if Vidalia started its own Tor process. */ bool _isVidaliaRunningTor; - /** A MessageLog object which handles logging Tor messages */ - MessageLog* _messageLog; - /** A BandwidthGraph object which handles monitoring Tor bandwidth usage */ - BandwidthGraph* _bandwidthGraph; - /** A NetViewer object which displays the Tor network graphically */ - NetViewer* _netViewer; - /** A ConfigDialog object which lets the user configure Tor and Vidalia */ - ConfigDialog* _configDialog; /** A TorControl object that handles communication with Tor */ TorControl* _torControl; - /** A HelperProcess object that manages the web browser */ - HelperProcess* _browserProcess; - /** A HelperProcess object that manages the IM client */ - HelperProcess* _imProcess; - /** A HelperProcess object that manages the proxy server */ - HelperProcess* _proxyProcess; /** Remembers the control password between when we start Tor with a hash of * the password and when we need to provide the password itself. */ QString _controlPassword; @@ -270,24 +251,30 @@ private: /** Set to true if Vidalia should restart Tor after a software upgrade. */ bool _restartTorAfterUpgrade; #endif - /** The menubar (Mac OS X only). */ - QMenuBar *_menuBar;
/** Defines the actions for the tray menu */ - QAction* _actionShowControlPanel; - QAction* _actionStartStopTor; - QAction* _actionShowConfig; - QAction* _actionShowAbout; - QAction* _actionExit; - QAction* _actionShowBandwidth; - QAction* _actionShowMessageLog; - QAction* _actionShowHelp; - QAction* _actionShowNetworkMap; - QAction* _actionNewIdentity; + QAction *_actionShowControlPanel; + QAction *_actionStartStopTor; + QAction *_actionStartTor; + QAction *_actionStopTor; + QAction *_actionRestartTor; + QAction *_actionNewIdentity; + QAction *_actionStatus; + QAction *_actionNetworkMap; + QAction *_actionMessageLog; + QAction *_actionBandwidthGraph; + QAction *_actionConfigure; + QAction *_actionVidaliaHelp; + QAction *_actionAbout; + QAction *_actionExit;
Ui::MainWindow ui; /**< Qt Designer generated object. */ + + StatusTab _statusTab; /**< Status tab that displays the load progress and a short log */ + MessageLog *_messageLog; /**< Message log that displays a more detailed log from Tor */ + NetViewer _netViewer; /**< Network map that draws circuits */ + QStringList _tabMap; /**< Map to handle opened tabs */ };
#endif
- diff --git a/src/vidalia/MainWindow.ui b/src/vidalia/MainWindow.ui index 5668cdc..d8bb5ce 100644 --- a/src/vidalia/MainWindow.ui +++ b/src/vidalia/MainWindow.ui @@ -1,603 +1,73 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>MainWindow</class> - <widget class="QMainWindow" name="MainWindow" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <widget class="QMainWindow" name="MainWindow"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>600</height> + </rect> </property> - <property name="maximumSize" > - <size> - <width>16777215</width> - <height>1</height> - </size> - </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Vidalia Control Panel</string> </property> - <property name="windowIcon" > - <iconset resource="res/vidalia.qrc" >:/images/32x32/tor-logo.png</iconset> + <property name="windowIcon"> + <iconset resource="res/vidalia.qrc"> + <normaloff>:/images/128x128/tor-logo.png</normaloff>:/images/128x128/tor-logo.png</iconset> </property> - <widget class="QWidget" name="centralwidget" > - <layout class="QVBoxLayout" > - <property name="margin" > - <number>20</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QGroupBox" name="grpStatus" > - <property name="geometry" > - <rect> - <x>20</x> - <y>10</y> - <width>400</width> - <height>72</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="title" > - <string>Status</string> - </property> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>4</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QLabel" name="lblStartupProgress" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>3</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize" > - <size> - <width>16777215</width> - <height>16777215</height> - </size> - </property> - <property name="text" > - <string>Starting Tor</string> - </property> - <property name="wordWrap" > - <bool>false</bool> - </property> - <property name="visible" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QProgressBar" name="progressBar" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>3</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize" > - <size> - <width>16777215</width> - <height>16777215</height> - </size> - </property> - <property name="visible" > - <bool>false</bool> - </property> - <property name="minimum" > - <number>0</number> - </property> - <property name="maximum" > - <number>130</number> - </property> - <property name="textVisible" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>4</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>4</hsizetype> - <vsizetype>4</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="lblTorStatusImg" > - <property name="pixmap" > - <pixmap>:/images/48x48/tor-off.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblTorStatus" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>3</hsizetype> - <vsizetype>3</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="maximumSize" > - <size> - <width>16777215</width> - <height>16777215</height> - </size> - </property> - <property name="text" > - <string>Tor is not running</string> - </property> - <property name="wordWrap" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>1</hsizetype> - <vsizetype>1</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </widget> - </item> - <item> - <widget class="QGroupBox" name="grpShortcuts" > - <property name="geometry" > - <rect> - <x>20</x> - <y>10</y> - <width>400</width> - <height>225</height> - </rect> - </property> - <property name="minimumSize" > - <size> - <width>0</width> - <height>0</height> - </size> - </property> - <property name="title" > - <string>Vidalia Shortcuts</string> - </property> - <layout class="QGridLayout" > - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="0" column="0" colspan="2" > - <widget class="VClickLabel" native="1" name="lblStartStopTor" > - <property name="text" > - <string>Start Tor</string> - </property> - <property name="statusTip" > - <string>Start Tor</string> - </property> - <property name="pixmap" > - <pixmap>:/images/48x48/start-tor.png</pixmap> - </property> - </widget> - </item> - <item row="0" column="2" colspan="2" > - <widget class="VClickLabel" native="1" name="lblSetupRelaying" > - <property name="text" > - <string>Setup Relaying</string> - </property> - <property name="statusTip" > - <string>Set up a relay and help the network grow</string> - </property> - <property name="pixmap" > - <pixmap>:/images/48x48/preferences-system-network-sharing.png</pixmap> - </property> - </widget> - </item> - <item row="1" column="0" colspan="2" > - <widget class="VClickLabel" native="1" name="lblViewNetwork" > - <property name="text" > - <string>View the Network</string> - </property> - <property name="statusTip" > - <string>View a map of the Tor network</string> - </property> - <property name="pixmap" > - <pixmap>:/images/48x48/applications-internet.png</pixmap> - </property> - </widget> - </item> - <item row="1" column="2" colspan="2" > - <widget class="VClickLabel" native="1" name="lblNewIdentity" > - <property name="enabled" > - <bool>false</bool> - </property> - <property name="text" > - <string>Use a New Identity</string> - </property> - <property name="statusTip" > - <string>Make subsequent connections appear new</string> - </property> - <property name="pixmap" > - <pixmap>:/images/48x48/view-media-artist.png</pixmap> - </property> - </widget> - </item> - <item row="2" column="0" colspan="4" > - <widget class="Line" name="line" > - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="3" column="0" colspan="4" > - <widget class="QWidget" name="lowerLayout" > - <layout class="QHBoxLayout"> - <item> - <widget class="QWidget" name="leftVerticalLayout" > - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="VClickLabel" name="lblBandwidthGraph" > - <property name="text" > - <string>Bandwidth Graph</string> - </property> - <property name="statusTip" > - <string>View recent bandwidth usage</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/utilities-system-monitor.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="VClickLabel" name="lblMessageLog" > - <property name="text" > - <string>Message Log</string> - </property> - <property name="statusTip" > - <string>View log message history</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/format-justify-fill.png</pixmap> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>18</width> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QWidget" name="midVerticalLayout" > - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="VClickLabel" name="lblHelpBrowser" > - <property name="text" > - <string>Help</string> - </property> - <property name="statusTip" > - <string>View help documentation</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/system-help.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="VClickLabel" name="lblSettings" > - <property name="text" > - <string>Settings</string> - </property> - <property name="statusTip" > - <string>Configure Vidalia</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/preferences-system.png</pixmap> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>18</width> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QWidget" name="rightVerticalLayout" > - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="VClickLabel" name="lblAboutVidalia" > - <property name="text" > - <string>About</string> - </property> - <property name="statusTip" > - <string>View version and license information</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/help-about.png</pixmap> - </property> - </widget> - </item> - <item> - <widget class="VClickLabel" name="lblExit" > - <property name="text" > - <string>Exit</string> - </property> - <property name="statusTip" > - <string>Exit Vidalia</string> - </property> - <property name="pixmap" > - <pixmap>:/images/22x22/application-exit.png</pixmap> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>0</height> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>18</width> - </size> - </property> - </spacer> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QCheckBox" name="chkShowOnStartup" > - <property name="text" > - <string>Show this window on startup</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>18</width> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="btnHide" > - <property name="text" > - <string>Hide</string> + <widget class="QWidget" name="centralwidget"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="VTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>-1</number> </property> - <property name="statusTip" > - <string>Hide this window</string> + <property name="tabsClosable"> + <bool>true</bool> </property> </widget> </item> </layout> </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>0</width> - <height>0</height> - </size> - </property> - </spacer> - </item> </layout> </widget> - <widget class="QStatusBar" name="statusbar" /> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>21</height> + </rect> + </property> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <widget class="QToolBar" name="toolBar"> + <property name="windowTitle"> + <string>toolBar</string> + </property> + <attribute name="toolBarArea"> + <enum>TopToolBarArea</enum> + </attribute> + <attribute name="toolBarBreak"> + <bool>false</bool> + </attribute> + </widget> </widget> <customwidgets> <customwidget> - <class>VClickLabel</class> - <extends>QWidget</extends> - <header>VClickLabel.h</header> + <class>VTabWidget</class> + <extends>QTabWidget</extends> + <header>VTabWidget.h</header> + <container>1</container> </customwidget> </customwidgets> <resources> - <include location="res/vidalia.qrc" /> + <include location="res/vidalia.qrc"/> </resources> - <connections> - <connection> - <sender>lblStartStopTor</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>start()</slot> - </connection> - <connection> - <sender>lblNewIdentity</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>newIdentity()</slot> - </connection> - <connection> - <sender>lblSetupRelaying</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>showServerConfigDialog()</slot> - </connection> - <connection> - <sender>lblSettings</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>showConfigDialog()</slot> - </connection> - <connection> - <sender>lblAboutVidalia</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>showAboutDialog()</slot> - </connection> - <connection> - <sender>lblExit</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>close()</slot> - </connection> - <connection> - <sender>chkShowOnStartup</sender> - <signal>toggled(bool)</signal> - <receiver>MainWindow</receiver> - <slot>toggleShowOnStartup(bool)</slot> - </connection> - <connection> - <sender>btnHide</sender> - <signal>clicked()</signal> - <receiver>MainWindow</receiver> - <slot>hide()</slot> - </connection> - </connections> + <connections/> </ui> diff --git a/src/vidalia/StatusTab.cpp b/src/vidalia/StatusTab.cpp new file mode 100644 index 0000000..f32924b --- /dev/null +++ b/src/vidalia/StatusTab.cpp @@ -0,0 +1,93 @@ +#include "StatusTab.h" +#include "VidaliaSettings.h" + +#define DEFAULT_MAX_MSG_COUNT 50 +#define SETTING_MAX_MSG_COUNT "MaxMsgCount" + +StatusTab::StatusTab(QWidget *parent) + : VidaliaTab(tr("Status"), "MessageLog", parent) +{ + ui.setupUi(this); + ui.listNotifications->sortItems(0, Qt::AscendingOrder); + uint maxMsgCount = getSetting(SETTING_MAX_MSG_COUNT, + DEFAULT_MAX_MSG_COUNT).toUInt(); + ui.listNotifications->setMaximumItemCount(maxMsgCount); +} + +StatusTab::~StatusTab() +{ + +} + +void +StatusTab::setTorStatus(const QString &text) +{ + ui.lblTorStatus->setText(text); +} + +void +StatusTab::setTorStatus(const QPixmap &icon) +{ + ui.lblTorStatusImg->setPixmap(icon); +} + +void +StatusTab::setTorStatus(const QPixmap &icon, const QString &text) +{ + ui.lblTorStatusImg->setPixmap(icon); + ui.lblTorStatus->setText(text); +} + +void +StatusTab::setTorStatusVisible(bool visible) +{ + ui.lblTorStatusImg->setVisible(visible); + ui.lblTorStatus->setVisible(visible); +} + +void +StatusTab::setProgress(int progress, const QString &description) +{ + ui.progressBar->setValue(progress); + ui.lblStartupProgress->setText(description); +} + +void +StatusTab::setProgressVisible(bool visible) +{ + ui.progressBar->setVisible(visible); + ui.lblStartupProgress->setVisible(visible); +} + +bool +StatusTab::isCheckedShowOnStartup() +{ + return ui.chkShowOnStartup->isChecked(); +} + +void +StatusTab::checkShowOnStartup(bool check) +{ + ui.chkShowOnStartup->setChecked(check); +} + +void +StatusTab::hideCheckShowOnStartup() +{ + ui.chkShowOnStartup->hide(); +} + +/** Called when the "show on startup" checkbox is toggled. */ +void +StatusTab::toggleShowOnStartup(bool checked) +{ + VidaliaSettings settings; + settings.setShowMainWindowAtStart(checked); +} + +void +StatusTab::retranslateUi() +{ + ui.retranslateUi(this); + setTitle(tr("Status")); +} diff --git a/src/vidalia/StatusTab.h b/src/vidalia/StatusTab.h new file mode 100644 index 0000000..440c2b7 --- /dev/null +++ b/src/vidalia/StatusTab.h @@ -0,0 +1,65 @@ +/* +** This file is part of Vidalia, and is subject to the license terms in the +** LICENSE file, found in the top level directory of this distribution. If you +** did not receive the LICENSE file with this file, you may obtain it from the +** Vidalia source package distributed by the Vidalia Project at +** http://www.vidalia-project.net/. No part of Vidalia, including this file, +** may be copied, modified, propagated, or distributed except according to the +** terms described in the LICENSE file. +*/ + +/* +** \file StatusTab.h +** \brief Main tab that shows the current Tor status +*/ + +#ifndef _STATUSTAB_H +#define _STATUSTAB_H + +#include "ui_StatusTab.h" +#include "VidaliaTab.h" + +class StatusTab : public VidaliaTab +{ + Q_OBJECT + +public: + /** Default constructor */ + StatusTab(QWidget *parent = 0); + /** Destructor. */ + ~StatusTab(); + + /** Sets the icon to the general Tor status display */ + void setTorStatus(const QPixmap &icon); + /** Sets the text to the general Tor status display */ + void setTorStatus(const QString &text); + /** Wrapper for the first two methods for ease of use */ + void setTorStatus(const QPixmap &icon, const QString &text); + /** Sets the Tor status display to visible or hidden */ + void setTorStatusVisible(bool visible); + + /** Sets the progress bar and its description */ + void setProgress(int progress, const QString &description); + /** Sets the visibility of the progress bar */ + void setProgressVisible(bool visible); + + /** Returns true if the "Show on start up" checkbox is checked */ + bool isCheckedShowOnStartup(); + /** Sets "Show on start up" checkbox checked if check is true */ + void checkShowOnStartup(bool check); + /** Hides the "Show on start up" checkbox */ + void hideCheckShowOnStartup(); + +private slots: + /** Called when the "show on startup" checkbox is toggled. */ + void toggleShowOnStartup(bool checked); + +protected: + /** Called when the user changes the UI translation. */ + void retranslateUi(); + +private: + Ui::StatusTab ui; +}; + +#endif diff --git a/src/vidalia/StatusTab.ui b/src/vidalia/StatusTab.ui new file mode 100644 index 0000000..a89f303 --- /dev/null +++ b/src/vidalia/StatusTab.ui @@ -0,0 +1,154 @@ +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> + <class>StatusTab</class> + <widget class="QWidget" name="StatusTab"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>513</width> + <height>421</height> + </rect> + </property> + <property name="windowTitle"> + <string notr="true"/> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QGroupBox" name="grpStatus"> + <property name="title"> + <string>Status</string> + </property> + <layout class="QGridLayout" name="gridLayout_4"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout_2"> + <item row="0" column="0"> + <widget class="QLabel" name="lblTorStatusImg"> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="lblTorStatus"> + <property name="text"> + <string notr="true">Tor is not running</string> + </property> + </widget> + </item> + </layout> + </item> + <item row="1" column="0"> + <layout class="QGridLayout" name="gridLayout_3"> + <item row="1" column="0"> + <widget class="QLabel" name="lblStartupProgress"> + <property name="text"> + <string notr="true">Starting Tor</string> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QProgressBar" name="progressBar"> + <property name="maximum"> + <number>130</number> + </property> + <property name="value"> + <number>24</number> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item row="4" column="0"> + <widget class="QGroupBox" name="grpLog"> + <property name="title"> + <string>Message Log</string> + </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="StatusEventWidget" name="listNotifications"> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="horizontalScrollBarPolicy"> + <enum>Qt::ScrollBarAsNeeded</enum> + </property> + <property name="showDropIndicator" stdset="0"> + <bool>false</bool> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="selectionBehavior"> + <enum>QAbstractItemView::SelectRows</enum> + </property> + <property name="indentation"> + <number>0</number> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <attribute name="headerShowSortIndicator" stdset="0"> + <bool>true</bool> + </attribute> + <column> + <property name="text"> + <string>Tor Status</string> + </property> + </column> + </widget> + </item> + </layout> + </widget> + </item> + <item row="5" column="0"> + <widget class="QCheckBox" name="chkShowOnStartup"> + <property name="text"> + <string>Show on startup</string> + </property> + </widget> + </item> + </layout> + </widget> + <customwidgets> + <customwidget> + <class>StatusEventWidget</class> + <extends>QTreeWidget</extends> + <header>StatusEventWidget.h</header> + </customwidget> + </customwidgets> + <resources/> + <connections> + <connection> + <sender>chkShowOnStartup</sender> + <signal>toggled(bool)</signal> + <receiver>StatusTab</receiver> + <slot>toggleShowOnStartup(bool)</slot> + <hints> + <hint type="sourcelabel"> + <x>256</x> + <y>368</y> + </hint> + <hint type="destinationlabel"> + <x>256</x> + <y>210</y> + </hint> + </hints> + </connection> + </connections> + <slots> + <slot>toggleShowOnStartup(bool)</slot> + </slots> +</ui> diff --git a/src/vidalia/VClickLabel.cpp b/src/vidalia/VClickLabel.cpp deleted file mode 100644 index 61e11fe..0000000 --- a/src/vidalia/VClickLabel.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* -** This file is part of Vidalia, and is subject to the license terms in the -** LICENSE file, found in the top level directory of this distribution. If you -** did not receive the LICENSE file with this file, you may obtain it from the -** Vidalia source package distributed by the Vidalia Project at -** http://www.vidalia-project.net/. No part of Vidalia, including this file, -** may be copied, modified, propagated, or distributed except according to the -** terms described in the LICENSE file. -*/ - -/* -** \file VClickLabel.cpp -** \brief Custom widget to create a clickable label with both an image and text. -*/ - -#include "VClickLabel.h" -#include "Vidalia.h" - -#include <QPainter> - - -/** Default constructor. */ -VClickLabel::VClickLabel(QWidget *parent) - : QWidget(parent) -{ - setCursor(Qt::PointingHandCursor); -} - -/** Returns the current size hint for this widget's current contents. */ -QSize -VClickLabel::sizeHint() const -{ - int height = qMax(_pixmap.height(), fontMetrics().height())+2; - int width = _pixmap.width() + fontMetrics().width(_text)+2; - return QSize(width, height); -} - -/** Returns the minimum size hint for this widget's current contents. */ -QSize -VClickLabel::minimumSizeHint() const -{ - return sizeHint(); -} - -/** Overloaded paint event to draw a pixmap and a text label. */ -void -VClickLabel::paintEvent(QPaintEvent *e) -{ - QPainter p(this); - QRect rect = this->rect(); - - if (vApp->isLeftToRight()) { - if (!_pixmap.isNull()) - p.drawPixmap(0, qMax((rect.height()-_pixmap.height())/2, 0), _pixmap); - if (!_text.isEmpty()) - p.drawText(_pixmap.width()+2, (rect.height()+fontInfo().pixelSize())/2, _text); - } else { - if (!_pixmap.isNull()) - p.drawPixmap(qMax(rect.right()-_pixmap.width(), 0), - qMax((rect.height()-_pixmap.height())/2, 0), _pixmap); - if (!_text.isEmpty()) { - int textWidth = fontMetrics().width(_text); - p.drawText(qMax(rect.right()-_pixmap.width()-textWidth-2, 0), - (rect.height()+fontInfo().pixelSize())/2, _text); - } - } - e->accept(); -} - -/** Overloaded mouse event to catch left mouse button clicks. */ -void -VClickLabel::mouseReleaseEvent(QMouseEvent *e) -{ - if (e->button() == Qt::LeftButton) { - emit clicked(); - } - e->accept(); -} - -/** Sets the label text to <b>text</b>. */ -void -VClickLabel::setText(const QString &text) -{ - _text = text; - update(); -} - -/** Sets the widget's image to <b>img</b>. */ -void -VClickLabel::setPixmap(const QPixmap &pixmap) -{ - _pixmap = pixmap; - update(); -} - diff --git a/src/vidalia/VClickLabel.h b/src/vidalia/VClickLabel.h deleted file mode 100644 index ae4ec5a..0000000 --- a/src/vidalia/VClickLabel.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -** This file is part of Vidalia, and is subject to the license terms in the -** LICENSE file, found in the top level directory of this distribution. If you -** did not receive the LICENSE file with this file, you may obtain it from the -** Vidalia source package distributed by the Vidalia Project at -** http://www.vidalia-project.net/. No part of Vidalia, including this file, -** may be copied, modified, propagated, or distributed except according to the -** terms described in the LICENSE file. -*/ - -/* -** \file VClickLabel.h -** \brief Custom widget to create a clickable label with both an image and text. -*/ - -#ifndef _VCLICKLABEL_H -#define _VCLICKLABEL_H - -#include <QWidget> -#include <QPixmap> -#include <QMouseEvent> -#include <QSize> - - -class VClickLabel : public QWidget -{ - Q_OBJECT - -public: - /** Default constructor. */ - VClickLabel(QWidget *parent = 0); - - /** Returns the current size hint for this widget's current contents. */ - virtual QSize sizeHint() const; - /** Returns the minimum size hint for this widget's current contents. */ - virtual QSize minimumSizeHint() const; - - /** Sets the label text to <b>text</b>. */ - void setText(const QString &text); - /** Sets the widget's image to <b>img</b>. */ - void setPixmap(const QPixmap &img); - -signals: - /** Emitted when the widget is left-clicked. */ - void clicked(); - -protected: - /** Overloaded paint event to draw a pixmap and a text label. */ - virtual void paintEvent(QPaintEvent *e); - /** Overloaded mouse event to catch left mouse button clicks. */ - virtual void mouseReleaseEvent(QMouseEvent *e); - -private: - QString _text; /**< Text label to display in the widget. */ - QPixmap _pixmap; /**< Image to display in the widget. */ -}; - -#endif - diff --git a/src/vidalia/VTabWidget.cpp b/src/vidalia/VTabWidget.cpp new file mode 100644 index 0000000..421f069 --- /dev/null +++ b/src/vidalia/VTabWidget.cpp @@ -0,0 +1,52 @@ +#include <QTabBar> + +#include "VTabWidget.h" +#include "VidaliaTab.h" + +VTabWidget::VTabWidget(QWidget *parent) : QTabWidget(parent) +{ + connect(this, SIGNAL(currentChanged(int)), this, SLOT(updateTop(int))); +} + +VTabWidget::~VTabWidget() +{ + +} + +void +VTabWidget::pinTab(int position) +{ + tabBar()->setTabButton(position, QTabBar::RightSide, 0); +} + +void +VTabWidget::updateTop(int index) +{ + for(int i=0; i<count(); i++) + if(widget(i)) + qobject_cast<VidaliaTab *>(widget(i))->setOnTop(false); + if(widget(index)) + qobject_cast<VidaliaTab *>(widget(index))->setOnTop(true); +} + +void +VTabWidget::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + retranslateUi(); + e->accept(); + return; + } + QTabWidget::changeEvent(e); +} + +void +VTabWidget::retranslateUi() +{ + for(int i=0; i<count(); i++) { + // We have to translate twice the tabs because otherwise the titles won't + // get updated + QApplication::sendEvent(qobject_cast<VidaliaTab *>(widget(i)), new QEvent(QEvent::LanguageChange)); + setTabText(i, qobject_cast<VidaliaTab *>(widget(i))->getTitle()); + } +} diff --git a/src/vidalia/VTabWidget.h b/src/vidalia/VTabWidget.h new file mode 100644 index 0000000..c3eb8ce --- /dev/null +++ b/src/vidalia/VTabWidget.h @@ -0,0 +1,43 @@ +/* +** This file is part of Vidalia, and is subject to the license terms in the +** LICENSE file, found in the top level directory of this distribution. If you +** did not receive the LICENSE file with this file, you may obtain it from the +** Vidalia source package distributed by the Vidalia Project at +** http://www.vidalia-project.net/. No part of Vidalia, including this file, +** may be copied, modified, propagated, or distributed except according to the +** terms described in the LICENSE file. +*/ + +/* +** \file VTabWidget.h +** \brief Implements a tab bar for more flexible handle of tabs +*/ + +#ifndef _VTABWIDGET_H +#define _VTABWIDGET_H + +#include <QTabWidget> + +class VTabWidget : public QTabWidget +{ + Q_OBJECT + +public: + /** Default constructor */ + VTabWidget(QWidget *parent = 0); + /** Destructor */ + ~VTabWidget(); + + /** Makes the tab at position unclosable */ + void pinTab(int position); + +protected: + void changeEvent(QEvent *e); + void retranslateUi(); + +private slots: + void updateTop(int index); +}; + +#endif + diff --git a/src/vidalia/VidaliaTab.cpp b/src/vidalia/VidaliaTab.cpp new file mode 100644 index 0000000..ec5f1bf --- /dev/null +++ b/src/vidalia/VidaliaTab.cpp @@ -0,0 +1,66 @@ +#include "VidaliaTab.h" +#include "Vidalia.h" + +VidaliaTab::VidaliaTab(const QString &title, const QString &name, QWidget *parent) + : QWidget(parent), _title(title) +{ + _settings = NULL; + if(!name.isEmpty()) + _settings = new VSettings(name); +} + +VidaliaTab::~VidaliaTab() +{ + if(_settings) + delete _settings; +} + +/** Gets the saved value of a property associated with this window object. + * If no value was saved, the default value is returned. */ +QVariant +VidaliaTab::getSetting(QString setting, QVariant defaultValue) +{ + return _settings->value(setting, defaultValue); +} + +/** Saves a value associated with a property name for this window object. */ +void +VidaliaTab::saveSetting(QString prop, QVariant value) +{ + _settings->setValue(prop, value); +} + +/** Associates a shortcut key sequence with a slot. */ +void +VidaliaTab::setShortcut(const QString &shortcut, const char *slot) +{ + vApp->createShortcut(QKeySequence(shortcut), this, this, slot); +} + +/** Reimplement the windows' changeEvent() method to check if the event + * is a QEvent::LanguageChange event. If so, call retranslateUi(), which + * subclasses of VidaliaWindow can reimplement to update their UI. */ +void +VidaliaTab::changeEvent(QEvent *e) +{ + if (e->type() == QEvent::LanguageChange) { + retranslateUi(); + e->accept(); + return; + } + QWidget::changeEvent(e); +} + +/** Called when the user wants to change the currently visible language. + * Subclasses can reimplement this to update their UI. */ +void +VidaliaTab::retranslateUi() +{ + /* The default retranslateUi() implementation does nothing */ +} + +void +VidaliaTab::setOnTop(bool top) +{ + _onTop = top; +} diff --git a/src/vidalia/VidaliaTab.h b/src/vidalia/VidaliaTab.h new file mode 100644 index 0000000..ac6edb1 --- /dev/null +++ b/src/vidalia/VidaliaTab.h @@ -0,0 +1,70 @@ +/* +** This file is part of Vidalia, and is subject to the license terms in the +** LICENSE file, found in the top level directory of this distribution. If you +** did not receive the LICENSE file with this file, you may obtain it from the +** Vidalia source package distributed by the Vidalia Project at +** http://www.vidalia-project.net/. No part of Vidalia, including this file, +** may be copied, modified, propagated, or distributed except according to the +** terms described in the LICENSE file. +*/ + +/* +** \file VidaliaTab.h +** \brief Main tab that shows the current Tor status +*/ + +#ifndef _VIDALIATAB_H +#define _VIDALIATAB_H + +#include "VSettings.h" + +#include <QtGui> + +class VidaliaTab : public QWidget +{ + Q_OBJECT + +public: + /** Default constructor. */ + VidaliaTab(const QString &title, const QString &name = "", QWidget *parent = 0); + /** Destructor. */ + ~VidaliaTab(); + + /** Returns the tab's title */ + QString getTitle() const { return _title; } + /** Sets the tab's title to title */ + void setTitle(const QString &title) { _title = title; } + + /** Associates a shortcut key sequence with a slot. */ + void setShortcut(const QString &shortcut, const char *slot); + + /** Gets the saved value of a property associated with this window object. + * If no value was saved, the default value is returned. */ + QVariant getSetting(QString name, QVariant defaultValue); + /** Saves a value associated with a setting name for this window object. */ + void saveSetting(QString name, QVariant value); + /** Sets the onTop property of the tab to top */ + void setOnTop(bool top); + +signals: + /** Emitted when a VidaliaWindow requests help information on the specified + * <b>topic</b>. */ + void helpRequested(const QString &topic); + +protected: + /** Reimplement the windows' changeEvent() method to check if the event + * is a QEvent::LanguageChange event. If so, call retranslateUi(), which + * subclasses of VidaliaWindow can reimplement to update their UI. */ + virtual void changeEvent(QEvent *e); + /** Called when the user wants to change the currently visible language. */ + virtual void retranslateUi(); + + bool _onTop; /**< True if the current tab is the one being displayed */ + +private: + QString _title; /**< Title displayed in the tab */ + VSettings* _settings; /**< Object used to store window properties */ +}; + +#endif + diff --git a/src/vidalia/bwgraph/BandwidthGraph.cpp b/src/vidalia/bwgraph/BandwidthGraph.cpp index 938f54e..8223a36 100644 --- a/src/vidalia/bwgraph/BandwidthGraph.cpp +++ b/src/vidalia/bwgraph/BandwidthGraph.cpp @@ -38,8 +38,9 @@
/** Default constructor */ -BandwidthGraph::BandwidthGraph(QWidget *parent, Qt::WFlags flags) - : VidaliaWindow("BandwidthGraph", parent, flags) +BandwidthGraph::BandwidthGraph(QStatusBar *st, QWidget *parent) + : VidaliaTab(tr("Bandwidth Graph"), "BandwidthGraph", parent), + _statusBar(st) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); @@ -50,8 +51,8 @@ BandwidthGraph::BandwidthGraph(QWidget *parent, Qt::WFlags flags) this, SLOT(updateGraph(quint64,quint64)));
/* Pressing 'Esc' or 'Ctrl+W' will close the window */ - setShortcut("Esc", SLOT(close())); - setShortcut("Ctrl+W", SLOT(close())); +// setShortcut("Esc", SLOT(close())); +// setShortcut("Ctrl+W", SLOT(close()));
/* Bind events to actions */ createActions(); @@ -81,6 +82,7 @@ void BandwidthGraph::retranslateUi() { ui.retranslateUi(this); + setTitle(tr("Bandwidth Graph")); }
/** Binds events to actions. */ @@ -151,9 +153,10 @@ void BandwidthGraph::reset() { /* Set to current time */ - ui.statusbar->showMessage(tr("Since:") + " " + - QDateTime::currentDateTime() - .toString(DATETIME_FMT)); + if(_statusBar && _onTop) + _statusBar->showMessage(tr("Since:") + " " + + QDateTime::currentDateTime() + .toString(DATETIME_FMT)); /* Reset the graph */ ui.frmGraph->resetGraph(); } @@ -255,13 +258,3 @@ BandwidthGraph::setOpacity(int value) #endif }
-/** Overloads the default show() slot so we can set opacity. */ -void -BandwidthGraph::showWindow() -{ - /* Load saved settings */ - loadSettings(); - /* Show the window */ - VidaliaWindow::showWindow(); -} - diff --git a/src/vidalia/bwgraph/BandwidthGraph.h b/src/vidalia/bwgraph/BandwidthGraph.h index 4de9d22..f818723 100644 --- a/src/vidalia/bwgraph/BandwidthGraph.h +++ b/src/vidalia/bwgraph/BandwidthGraph.h @@ -17,7 +17,7 @@ #define _BWGRAPH_H
#include "ui_BandwidthGraph.h" -#include "VidaliaWindow.h" +#include "VidaliaTab.h" #include "VidaliaSettings.h" #include "TorControl.h"
@@ -28,17 +28,13 @@ #define REFRESH_RATE 1000
-class BandwidthGraph : public VidaliaWindow +class BandwidthGraph : public VidaliaTab { Q_OBJECT
public: /** Default constructor */ - BandwidthGraph(QWidget *parent = 0, Qt::WFlags flags = 0); - -public slots: - /** Overloaded QWidget.show */ - void showWindow(); + BandwidthGraph(QStatusBar *st = 0, QWidget *parent = 0);
protected: /** Called when the user changes the UI translation. */ @@ -68,6 +64,8 @@ private: TorControl* _torControl; /** A VidaliaSettings object that handles getting/saving settings */ VidaliaSettings* _settings; + + QStatusBar *_statusBar;
/** Qt Designer generated object */ Ui::BandwidthGraph ui; diff --git a/src/vidalia/bwgraph/BandwidthGraph.ui b/src/vidalia/bwgraph/BandwidthGraph.ui index 173168c..76a5a31 100644 --- a/src/vidalia/bwgraph/BandwidthGraph.ui +++ b/src/vidalia/bwgraph/BandwidthGraph.ui @@ -1,323 +1,234 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>BandwidthGraph</class> - <widget class="QMainWindow" name="BandwidthGraph" > - <property name="geometry" > + <widget class="QWidget" name="BandwidthGraph"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>283</width> - <height>138</height> + <width>588</width> + <height>437</height> </rect> </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> + <property name="windowTitle"> + <string notr="true"/> </property> - <property name="windowTitle" > - <string>Tor Bandwidth Usage</string> - </property> - <property name="windowIcon" > - <iconset resource="../res/vidalia_common.qrc" >:/images/32x32/utilities-system-monitor.png</iconset> - </property> - <widget class="QWidget" name="centralwidget" > - <layout class="QGridLayout" > - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item row="1" column="0" > - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QPushButton" name="btnToggleSettings" > - <property name="text" > - <string>Show Settings</string> - </property> - <property name="checkable" > - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>21</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QPushButton" name="btnReset" > - <property name="text" > - <string>Reset</string> - </property> - </widget> - </item> - </layout> - </item> - <item row="0" column="0" > - <widget class="GraphFrame" name="frmGraph" > - <property name="minimumSize" > - <size> - <width>120</width> - <height>80</height> - </size> - </property> - <property name="font" > - <font> - <pointsize>10</pointsize> - </font> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="frameShape" > - <enum>QFrame::Box</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - </widget> - </item> - <item row="2" column="0" > - <widget class="QFrame" name="frmSettings" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>0</hsizetype> - <vsizetype>0</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize" > - <size> - <width>355</width> - <height>85</height> - </size> - </property> - <property name="maximumSize" > - <size> - <width>355</width> - <height>82</height> - </size> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> - </property> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>9</number> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="GraphFrame" name="frmGraph"> + <property name="minimumSize"> + <size> + <width>120</width> + <height>80</height> + </size> </property> - <property name="spacing" > - <number>6</number> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> </property> - <item> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>3</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QCheckBox" name="chkReceiveRate" > - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip" > - <string/> - </property> - <property name="layoutDirection" > - <enum>Qt::RightToLeft</enum> - </property> - <property name="text" > - <string>Receive Rate</string> - </property> - <property name="checked" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkSendRate" > - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip" > - <string/> - </property> - <property name="layoutDirection" > - <enum>Qt::RightToLeft</enum> - </property> - <property name="text" > - <string>Send Rate</string> - </property> - <property name="checked" > - <bool>false</bool> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkAlwaysOnTop" > - <property name="layoutDirection" > - <enum>Qt::RightToLeft</enum> - </property> - <property name="text" > - <string>Always on Top</string> - </property> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>21</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>1</number> - </property> - <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>20</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="lblGraphStyle" > - <property name="text" > - <string>Style</string> - </property> - </widget> - </item> - <item> - <widget class="QComboBox" name="cmbGraphStyle" > - <item> - <property name="text" > - <string/> - </property> - <property name="icon" > - <iconset resource="../res/vidalia_common.qrc" >:/images/16x16/graph-line.png</iconset> - </property> - </item> - <item> - <property name="text" > - <string/> - </property> - <property name="icon" > - <iconset resource="../res/vidalia_common.qrc" >:/images/16x16/graph-area.png</iconset> - </property> - </item> - </widget> - </item> - </layout> - </item> - <item> - <widget class="QFrame" name="frmOpacity" > - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="frameShape" > - <enum>QFrame::NoFrame</enum> - </property> - <property name="frameShadow" > - <enum>QFrame::Plain</enum> - </property> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="frameShape"> + <enum>QFrame::Box</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + </widget> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeType"> + <enum>QSizePolicy::Expanding</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>0</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="btnToggleSettings"> + <property name="text"> + <string>Show Settings</string> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QPushButton" name="btnReset"> + <property name="text"> + <string>Reset</string> + </property> + </widget> + </item> + </layout> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QFrame" name="frmSettings"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Minimum" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>355</width> + <height>85</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>82</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QHBoxLayout" name="_2"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>9</number> + </property> + <item> + <layout class="QVBoxLayout" name="_3"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>3</number> + </property> + <item> + <widget class="QCheckBox" name="chkReceiveRate"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> </property> - <property name="spacing" > - <number>3</number> + <property name="toolTip"> + <string/> + </property> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string>Receive Rate</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="chkSendRate"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string>Send Rate</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="chkAlwaysOnTop"> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string>Always on Top</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>21</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <layout class="QVBoxLayout" name="_4"> + <property name="spacing"> + <number>1</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <layout class="QHBoxLayout" name="_5"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>0</number> </property> - <item> - <widget class="QSlider" name="sldrOpacity" > - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip" > - <string>Changes the transparency of the Bandwidth Graph</string> - </property> - <property name="minimum" > - <number>30</number> - </property> - <property name="maximum" > - <number>100</number> - </property> - <property name="value" > - <number>100</number> - </property> - <property name="sliderPosition" > - <number>100</number> - </property> - <property name="tracking" > - <bool>false</bool> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="invertedAppearance" > - <bool>false</bool> - </property> - <property name="tickPosition" > - <enum>QSlider::NoTicks</enum> - </property> - <property name="tickInterval" > - <number>10</number> - </property> - </widget> - </item> <item> <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>20</height> @@ -326,160 +237,264 @@ </spacer> </item> <item> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>0</number> + <widget class="QLabel" name="lblGraphStyle"> + <property name="text"> + <string>Style</string> </property> - <property name="spacing" > - <number>0</number> - </property> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>21</width> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QLabel" name="lblPercentOpacity" > - <property name="minimumSize" > - <size> - <width>25</width> - <height>0</height> - </size> - </property> - <property name="font" > - <font> - <pointsize>10</pointsize> - </font> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="layoutDirection" > - <enum>Qt::RightToLeft</enum> - </property> - <property name="text" > - <string>100</string> - </property> - </widget> - </item> + </widget> + </item> + <item> + <widget class="QComboBox" name="cmbGraphStyle"> <item> - <widget class="QLabel" name="label" > - <property name="font" > - <font> - <pointsize>10</pointsize> - </font> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="text" > - <string>% Opaque</string> - </property> - </widget> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/graph-line.png</normaloff>:/images/16x16/graph-line.png</iconset> + </property> </item> <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>21</width> - </size> - </property> - </spacer> + <property name="text"> + <string/> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/graph-area.png</normaloff>:/images/16x16/graph-area.png</iconset> + </property> </item> - </layout> + </widget> </item> </layout> - </widget> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Vertical</enum> - </property> - <property name="sizeHint" > - <size> - <width>21</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item> - <spacer> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>21</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>1</number> - </property> - <item> - <widget class="QPushButton" name="btnSaveSettings" > - <property name="text" > - <string>Save</string> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnCancelSettings" > - <property name="text" > - <string>Cancel</string> - </property> - </widget> - </item> - </layout> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QStatusBar" name="statusbar" /> + </item> + <item> + <widget class="QFrame" name="frmOpacity"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="frameShape"> + <enum>QFrame::NoFrame</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Plain</enum> + </property> + <layout class="QVBoxLayout" name="_6"> + <property name="spacing"> + <number>3</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QSlider" name="sldrOpacity"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string>Changes the transparency of the Bandwidth Graph</string> + </property> + <property name="minimum"> + <number>30</number> + </property> + <property name="maximum"> + <number>100</number> + </property> + <property name="value"> + <number>100</number> + </property> + <property name="sliderPosition"> + <number>100</number> + </property> + <property name="tracking"> + <bool>false</bool> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + <property name="tickPosition"> + <enum>QSlider::NoTicks</enum> + </property> + <property name="tickInterval"> + <number>10</number> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="_7"> + <property name="spacing"> + <number>0</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>21</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QLabel" name="lblPercentOpacity"> + <property name="minimumSize"> + <size> + <width>25</width> + <height>0</height> + </size> + </property> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="layoutDirection"> + <enum>Qt::RightToLeft</enum> + </property> + <property name="text"> + <string>100</string> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label"> + <property name="font"> + <font> + <pointsize>10</pointsize> + </font> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="text"> + <string>% Opaque</string> + </property> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>21</width> + <height>0</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>21</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="_8"> + <property name="spacing"> + <number>1</number> + </property> + <property name="margin"> + <number>0</number> + </property> + <item> + <widget class="QPushButton" name="btnSaveSettings"> + <property name="text"> + <string>Save</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnCancelSettings"> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + </layout> + </item> + </layout> </widget> <customwidgets> <customwidget> <class>GraphFrame</class> <extends>QFrame</extends> <header>bwgraph/GraphFrame.h</header> + <container>1</container> </customwidget> </customwidgets> <resources> - <include location="../res/vidalia_common.qrc" /> + <include location="../res/vidalia.qrc"/> </resources> - <tabstops> - <tabstop>btnToggleSettings</tabstop> - <tabstop>btnReset</tabstop> - <tabstop>chkReceiveRate</tabstop> - <tabstop>chkSendRate</tabstop> - <tabstop>chkAlwaysOnTop</tabstop> - <tabstop>cmbGraphStyle</tabstop> - <tabstop>sldrOpacity</tabstop> - <tabstop>btnSaveSettings</tabstop> - <tabstop>btnCancelSettings</tabstop> - </tabstops> <connections/> </ui> diff --git a/src/vidalia/config/BridgeUsageDialog.ui b/src/vidalia/config/BridgeUsageDialog.ui index 66ef1df..e3c0056 100644 --- a/src/vidalia/config/BridgeUsageDialog.ui +++ b/src/vidalia/config/BridgeUsageDialog.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>BridgeUsageDialog</class> - <widget class="QDialog" name="BridgeUsageDialog" > - <property name="geometry" > + <widget class="QDialog" name="BridgeUsageDialog"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,49 +10,53 @@ <height>408</height> </rect> </property> - <property name="windowTitle" > + <property name="windowTitle"> <string>Bridge Usage Summary</string> </property> - <layout class="QVBoxLayout" name="verticalLayout_2" > + <property name="windowIcon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/128x128/tor-logo.png</normaloff>:/images/128x128/tor-logo.png</iconset> + </property> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <widget class="QGroupBox" name="groupBox" > - <property name="title" > + <widget class="QGroupBox" name="groupBox"> + <property name="title"> <string>Client Summary</string> </property> - <layout class="QVBoxLayout" name="verticalLayout" > + <layout class="QVBoxLayout" name="verticalLayout"> <item> - <widget class="QLabel" name="lblClientSummary" > - <property name="text" > - <string></string> + <widget class="QLabel" name="lblClientSummary"> + <property name="text"> + <string/> </property> - <property name="alignment" > + <property name="alignment"> <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set> </property> - <property name="wordWrap" > + <property name="wordWrap"> <bool>true</bool> </property> </widget> </item> <item> - <widget class="QTreeWidget" name="treeClientSummary" > - <property name="alternatingRowColors" > + <widget class="QTreeWidget" name="treeClientSummary"> + <property name="alternatingRowColors"> <bool>false</bool> </property> - <property name="sortingEnabled" > + <property name="sortingEnabled"> <bool>true</bool> </property> <column> - <property name="text" > - <string></string> + <property name="text"> + <string/> </property> </column> <column> - <property name="text" > + <property name="text"> <string>Country</string> </property> </column> <column> - <property name="text" > + <property name="text"> <string># Clients</string> </property> </column> @@ -61,18 +66,20 @@ </widget> </item> <item> - <widget class="QDialogButtonBox" name="buttonBox" > - <property name="orientation" > + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> <enum>Qt::Horizontal</enum> </property> - <property name="standardButtons" > + <property name="standardButtons"> <set>QDialogButtonBox::Close</set> </property> </widget> </item> </layout> </widget> - <resources/> + <resources> + <include location="../res/vidalia.qrc"/> + </resources> <connections> <connection> <sender>buttonBox</sender> @@ -80,11 +87,11 @@ <receiver>BridgeUsageDialog</receiver> <slot>accept()</slot> <hints> - <hint type="sourcelabel" > + <hint type="sourcelabel"> <x>248</x> <y>254</y> </hint> - <hint type="destinationlabel" > + <hint type="destinationlabel"> <x>157</x> <y>274</y> </hint> @@ -96,11 +103,11 @@ <receiver>BridgeUsageDialog</receiver> <slot>reject()</slot> <hints> - <hint type="sourcelabel" > + <hint type="sourcelabel"> <x>316</x> <y>260</y> </hint> - <hint type="destinationlabel" > + <hint type="destinationlabel"> <x>286</x> <y>274</y> </hint> diff --git a/src/vidalia/config/ConfigDialog.h b/src/vidalia/config/ConfigDialog.h index 1362038..f8815d9 100644 --- a/src/vidalia/config/ConfigDialog.h +++ b/src/vidalia/config/ConfigDialog.h @@ -33,9 +33,9 @@ public: General = 0, /** General configuration page. */ Network, /** Network configuration page. */ Server, /** Server configuration page. */ + Service, /** Service Configuration page */ Appearance, /** Appearance configuration page. */ - Advanced, /** Advanced configuration page. */ - Service /** Service Configuration page */ + Advanced /** Advanced configuration page. */ };
/** Default Constructor */ diff --git a/src/vidalia/config/ServicePage.h b/src/vidalia/config/ServicePage.h index bdb0c51..56756f0 100644 --- a/src/vidalia/config/ServicePage.h +++ b/src/vidalia/config/ServicePage.h @@ -16,7 +16,6 @@ #include "TorSettings.h" #include "ServiceSettings.h" #include "ExitPolicy.h" -#include "HelpBrowser.h"
#include "TorControl.h"
diff --git a/src/vidalia/config/ServicePage.ui b/src/vidalia/config/ServicePage.ui index 8be3a59..8fc6c57 100644 --- a/src/vidalia/config/ServicePage.ui +++ b/src/vidalia/config/ServicePage.ui @@ -1,7 +1,8 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>ServicePage</class> - <widget class="QWidget" name="ServicePage" > - <property name="geometry" > + <widget class="QWidget" name="ServicePage"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> @@ -9,133 +10,137 @@ <height>400</height> </rect> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> <width>600</width> <height>400</height> </size> </property> - <property name="windowTitle" > - <string>Form</string> + <property name="windowTitle"> + <string notr="true"/> </property> - <layout class="QVBoxLayout" > + <layout class="QVBoxLayout"> <item> - <widget class="QGroupBox" name="groupBox" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Fixed" hsizetype="Preferred" > + <widget class="QGroupBox" name="groupBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="title" > + <property name="title"> <string>Provided Hidden Services</string> </property> - <layout class="QGridLayout" > - <item rowspan="5" row="0" column="0" > - <widget class="QTableWidget" name="serviceWidget" > - <property name="sizePolicy" > - <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > + <layout class="QGridLayout"> + <item row="0" column="0" rowspan="5"> + <widget class="QTableWidget" name="serviceWidget"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>0</horstretch> <verstretch>0</verstretch> </sizepolicy> </property> - <property name="selectionMode" > + <property name="selectionMode"> <enum>QAbstractItemView::SingleSelection</enum> </property> - <property name="selectionBehavior" > + <property name="selectionBehavior"> <enum>QAbstractItemView::SelectRows</enum> </property> - <property name="textElideMode" > + <property name="textElideMode"> <enum>Qt::ElideLeft</enum> </property> - <property name="showGrid" > + <property name="showGrid"> <bool>true</bool> </property> <column> - <property name="text" > + <property name="text"> <string>Onion Address</string> </property> </column> <column> - <property name="text" > + <property name="text"> <string>Virtual Port</string> </property> </column> <column> - <property name="text" > + <property name="text"> <string>Target</string> </property> </column> <column> - <property name="text" > + <property name="text"> <string>Directory Path</string> </property> </column> <column> - <property name="text" > + <property name="text"> <string>Enabled</string> </property> </column> </widget> </item> - <item row="0" column="1" > - <widget class="QToolButton" name="addButton" > - <property name="toolTip" > + <item row="0" column="1"> + <widget class="QToolButton" name="addButton"> + <property name="toolTip"> <string>Add new service to list</string> </property> - <property name="text" > + <property name="text"> <string/> </property> - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/22x22/list-add.png</iconset> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/list-add.png</normaloff>:/images/22x22/list-add.png</iconset> </property> </widget> </item> - <item row="1" column="1" > - <widget class="QToolButton" name="removeButton" > - <property name="toolTip" > + <item row="1" column="1"> + <widget class="QToolButton" name="removeButton"> + <property name="toolTip"> <string>Remove selected service from list</string> </property> - <property name="text" > + <property name="text"> <string/> </property> - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/22x22/list-remove.png</iconset> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/list-remove.png</normaloff>:/images/22x22/list-remove.png</iconset> </property> </widget> </item> - <item row="2" column="1" > - <widget class="QToolButton" name="copyButton" > - <property name="toolTip" > + <item row="2" column="1"> + <widget class="QToolButton" name="copyButton"> + <property name="toolTip"> <string>Copy onion address of selected service to clipboard</string> </property> - <property name="text" > + <property name="text"> <string/> </property> - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/22x22/edit-copy.png</iconset> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/edit-copy.png</normaloff>:/images/22x22/edit-copy.png</iconset> </property> </widget> </item> - <item row="3" column="1" > - <widget class="QToolButton" name="browseButton" > - <property name="toolTip" > + <item row="3" column="1"> + <widget class="QToolButton" name="browseButton"> + <property name="toolTip"> <string>Browse in local file system and choose directory for selected service</string> </property> - <property name="text" > + <property name="text"> <string/> </property> - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/22x22/folder.png</iconset> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/folder.png</normaloff>:/images/22x22/folder.png</iconset> </property> </widget> </item> - <item row="4" column="1" > + <item row="4" column="1"> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0"> <size> <width>21</width> <height>46</height> @@ -148,10 +153,10 @@ </item> <item> <spacer> - <property name="orientation" > + <property name="orientation"> <enum>Qt::Vertical</enum> </property> - <property name="sizeHint" > + <property name="sizeHint" stdset="0"> <size> <width>20</width> <height>141</height> @@ -161,6 +166,8 @@ </item> </layout> </widget> - <resources/> + <resources> + <include location="../res/vidalia.qrc"/> + </resources> <connections/> </ui> diff --git a/src/vidalia/config/TorrcDialog.cpp b/src/vidalia/config/TorrcDialog.cpp index 81d1a4a..677ae59 100644 --- a/src/vidalia/config/TorrcDialog.cpp +++ b/src/vidalia/config/TorrcDialog.cpp @@ -19,6 +19,7 @@ #include "Vidalia.h"
#include <QMessageBox> +#include <QToolBar>
void TorHighlighter::highlightBlock(const QString &text) @@ -43,6 +44,8 @@ TorrcDialog::TorrcDialog(QWidget *parent) { /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); + loadToolBar(); + TorHighlighter *highlighter = new TorHighlighter(ui.teditTorrc);
/* Retrieve the global TorControl instance */ @@ -61,6 +64,21 @@ TorrcDialog::~TorrcDialog()
}
+void +TorrcDialog::loadToolBar() +{ + QToolBar *tb = new QToolBar(this); + tb->addAction(ui.actionCut); + tb->addAction(ui.actionCopy); + tb->addAction(ui.actionPaste); + tb->addAction(ui.actionUndo); + tb->addAction(ui.actionRedo); + tb->addAction(ui.actionSelect_All); + + tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + ui.verticalLayout->insertWidget(0, tb); +} + /** Gives a shallow parse phase to the settings to catch most errors * and passes on the error messages from Tor if the setting's value isn't * valid. It returns false if something went wrong. diff --git a/src/vidalia/config/TorrcDialog.h b/src/vidalia/config/TorrcDialog.h index b5eadcc..c784df1 100644 --- a/src/vidalia/config/TorrcDialog.h +++ b/src/vidalia/config/TorrcDialog.h @@ -49,6 +49,7 @@ private slots: void saveTorrc();
private: + void loadToolBar(); /** Loads the contents of the torrc file that Tor has loaded */ void loadTorrc(); /** Parses the options edited and sets them through SETCONF diff --git a/src/vidalia/config/TorrcDialog.ui b/src/vidalia/config/TorrcDialog.ui index c72a255..42971b4 100644 --- a/src/vidalia/config/TorrcDialog.ui +++ b/src/vidalia/config/TorrcDialog.ui @@ -19,158 +19,11 @@ </property> <layout class="QGridLayout" name="gridLayout_2"> <item row="0" column="0"> - <layout class="QGridLayout" name="gridLayout"> - <item row="1" column="0"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> <widget class="QTextEdit" name="teditTorrc"/> </item> - <item row="5" column="0"> - <widget class="QCheckBox" name="chkSave"> - <property name="text"> - <string>Save settings. If unchecked it will only apply settings to the current Tor instance.</string> - </property> - <property name="checked"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="0" column="0"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QPushButton" name="btnCut"> - <property name="text"> - <string>Cut</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/editcut.png</normaloff>:/images/22x22/editcut.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnCopy"> - <property name="text"> - <string>Copy</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/edit-copy.png</normaloff>:/images/22x22/edit-copy.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnPaste"> - <property name="text"> - <string>Paste</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/editpaste.png</normaloff>:/images/22x22/editpaste.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnUndo"> - <property name="text"> - <string>Undo</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/edit_undo.png</normaloff>:/images/22x22/edit_undo.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnRedo"> - <property name="text"> - <string>Redo</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/edit_redo.png</normaloff>:/images/22x22/edit_redo.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <widget class="QPushButton" name="btnSelectAll"> - <property name="text"> - <string>Select All</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/22x22/edit_select_all.png</normaloff>:/images/22x22/edit_select_all.png</iconset> - </property> - <property name="iconSize"> - <size> - <width>22</width> - <height>22</height> - </size> - </property> - <property name="flat"> - <bool>true</bool> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - <item row="3" column="0"> + <item> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> <widget class="QRadioButton" name="rdoAll"> @@ -191,6 +44,16 @@ </item> </layout> </item> + <item> + <widget class="QCheckBox" name="chkSave"> + <property name="text"> + <string>Save settings. If unchecked it will only apply settings to the current Tor instance.</string> + </property> + <property name="checked"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </item> <item row="1" column="0"> @@ -204,6 +67,78 @@ </widget> </item> </layout> + <action name="actionCut"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/editcut.png</normaloff>:/images/22x22/editcut.png</iconset> + </property> + <property name="text"> + <string>Cut</string> + </property> + <property name="shortcut"> + <string>Ctrl+X</string> + </property> + </action> + <action name="actionCopy"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/edit-copy.png</normaloff>:/images/22x22/edit-copy.png</iconset> + </property> + <property name="text"> + <string>Copy</string> + </property> + <property name="shortcut"> + <string>Ctrl+C</string> + </property> + </action> + <action name="actionPaste"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/editpaste.png</normaloff>:/images/22x22/editpaste.png</iconset> + </property> + <property name="text"> + <string>Paste</string> + </property> + <property name="shortcut"> + <string>Ctrl+V</string> + </property> + </action> + <action name="actionUndo"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/edit_undo.png</normaloff>:/images/22x22/edit_undo.png</iconset> + </property> + <property name="text"> + <string>Undo</string> + </property> + <property name="shortcut"> + <string>Ctrl+Z</string> + </property> + </action> + <action name="actionRedo"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/edit_redo.png</normaloff>:/images/22x22/edit_redo.png</iconset> + </property> + <property name="text"> + <string>Redo</string> + </property> + <property name="shortcut"> + <string>Ctrl+Shift+Z</string> + </property> + </action> + <action name="actionSelect_All"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/22x22/edit_select_all.png</normaloff>:/images/22x22/edit_select_all.png</iconset> + </property> + <property name="text"> + <string>Select All</string> + </property> + <property name="shortcut"> + <string>Ctrl+A</string> + </property> + </action> </widget> <resources> <include location="../res/vidalia.qrc"/> @@ -226,8 +161,8 @@ </hints> </connection> <connection> - <sender>btnUndo</sender> - <signal>clicked()</signal> + <sender>actionUndo</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>undo()</slot> <hints> @@ -242,8 +177,8 @@ </hints> </connection> <connection> - <sender>btnRedo</sender> - <signal>clicked()</signal> + <sender>actionRedo</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>redo()</slot> <hints> @@ -258,8 +193,8 @@ </hints> </connection> <connection> - <sender>btnSelectAll</sender> - <signal>clicked()</signal> + <sender>actionSelect_All</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>selectAll()</slot> <hints> @@ -274,8 +209,8 @@ </hints> </connection> <connection> - <sender>btnCopy</sender> - <signal>clicked()</signal> + <sender>actionCopy</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>copy()</slot> <hints> @@ -290,8 +225,8 @@ </hints> </connection> <connection> - <sender>btnPaste</sender> - <signal>clicked()</signal> + <sender>actionPaste</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>paste()</slot> <hints> @@ -306,8 +241,8 @@ </hints> </connection> <connection> - <sender>btnCut</sender> - <signal>clicked()</signal> + <sender>actionCut</sender> + <signal>triggered()</signal> <receiver>teditTorrc</receiver> <slot>cut()</slot> <hints> diff --git a/src/vidalia/log/MessageLog.cpp b/src/vidalia/log/MessageLog.cpp index e15799e..1638916 100644 --- a/src/vidalia/log/MessageLog.cpp +++ b/src/vidalia/log/MessageLog.cpp @@ -26,6 +26,8 @@ #include <QMessageBox> #include <QClipboard>
+#include <QToolBar> + /* Message log settings */ #define SETTING_MSG_FILTER "MessageFilter" #define SETTING_MAX_MSG_COUNT "MaxMsgCount" @@ -54,8 +56,9 @@ * \param parent The parent widget of this MessageLog object. * \param flags Any desired window creation flags. */ -MessageLog::MessageLog(QWidget *parent, Qt::WFlags flags) -: VidaliaWindow("MessageLog", parent, flags) +MessageLog::MessageLog(QStatusBar *st, QWidget *parent) +: VidaliaTab(tr("Message Log"), "MessageLog", parent), + _statusBar(st) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); @@ -77,7 +80,8 @@ MessageLog::MessageLog(QWidget *parent, Qt::WFlags flags) /* Sort in ascending chronological order */ ui.listMessages->sortItems(LogTreeWidget::TimeColumn, Qt::AscendingOrder); - ui.listNotifications->sortItems(0, Qt::AscendingOrder); + + ui.frmSettings->setVisible(false); }
/** Default Destructor. Simply frees up any memory allocated for member @@ -121,6 +125,19 @@ MessageLog::createActions() connect(ui.btnBrowse, SIGNAL(clicked()), this, SLOT(browse()));
+ QToolBar *tb = new QToolBar(tr("toolbar")); + tb->addAction(ui.actionSave_All); + tb->addAction(ui.actionSave_Selected); + tb->addAction(ui.actionCopy); + tb->addAction(ui.actionSelect_All); + tb->addAction(ui.actionFind); + tb->addAction(ui.actionClear); + tb->addAction(ui.actionSettings); + tb->addAction(ui.actionHelp); + + tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + ui.verticalLayout->insertWidget(0, tb); + #if defined(Q_WS_MAC) ui.actionHelp->setShortcut(QString("Ctrl+?")); #endif @@ -152,6 +169,7 @@ void MessageLog::retranslateUi() { ui.retranslateUi(this); + setTitle(tr("Message Log")); setToolTips(); }
@@ -164,7 +182,6 @@ MessageLog::loadSettings() DEFAULT_MAX_MSG_COUNT).toUInt(); ui.spnbxMaxCount->setValue(maxMsgCount); ui.listMessages->setMaximumMessageCount(maxMsgCount); - ui.listNotifications->setMaximumItemCount(maxMsgCount);
/* Set whether or not logging to file is enabled */ _enableLogging = getSetting(SETTING_ENABLE_LOGFILE, @@ -262,7 +279,6 @@ MessageLog::saveSettings() /* Update the maximum displayed item count */ saveSetting(SETTING_MAX_MSG_COUNT, ui.spnbxMaxCount->value()); ui.listMessages->setMaximumMessageCount(ui.spnbxMaxCount->value()); - ui.listNotifications->setMaximumItemCount(ui.spnbxMaxCount->value());
/* Save message filter and refilter the list */ uint filter = 0; @@ -351,29 +367,20 @@ MessageLog::save(const QStringList &messages) void MessageLog::saveSelected() { - if (ui.tabWidget->currentIndex() == 0) - save(ui.listNotifications->selectedEvents()); - else - save(ui.listMessages->selectedMessages()); + save(ui.listMessages->selectedMessages()); }
/** Saves all shown messages to a file. */ void MessageLog::saveAll() { - if (ui.tabWidget->currentIndex() == 0) - save(ui.listNotifications->allEvents()); - else - save(ui.listMessages->allMessages()); + save(ui.listMessages->allMessages()); }
void MessageLog::selectAll() { - if (ui.tabWidget->currentIndex() == 0) - ui.listNotifications->selectAll(); - else - ui.listMessages->selectAll(); + ui.listMessages->selectAll(); }
/** Copies contents of currently selected messages to the 'clipboard'. */ @@ -382,10 +389,7 @@ MessageLog::copy() { QString contents;
- if (ui.tabWidget->currentIndex() == 0) - contents = ui.listNotifications->selectedEvents().join("\n"); - else - contents = ui.listMessages->selectedMessages().join("\n"); + contents = ui.listMessages->selectedMessages().join("\n");
if (!contents.isEmpty()) { /* Copy the selected messages to the clipboard */ @@ -398,10 +402,7 @@ MessageLog::copy() void MessageLog::clear() { - if (ui.tabWidget->currentIndex() == 0) - ui.listNotifications->clear(); - else - ui.listMessages->clearMessages(); + ui.listMessages->clearMessages(); }
/** Prompts the user for a search string. If the search string is not found in @@ -421,18 +422,10 @@ MessageLog::find() QTreeWidgetItem *firstItem = 0;
/* Pick the right tree widget to search based on the current tab */ - if (ui.tabWidget->currentIndex() == 0) { - QList<StatusEventItem *> results = ui.listNotifications->find(text, true); - if (results.size() > 0) { - tree = ui.listNotifications; - firstItem = dynamic_cast<QTreeWidgetItem *>(results.at(0)); - } - } else { - QList<LogTreeItem *> results = ui.listMessages->find(text, true); - if (results.size() > 0) { - tree = ui.listMessages; - firstItem = dynamic_cast<QTreeWidgetItem *>(results.at(0)); - } + QList<LogTreeItem *> results = ui.listMessages->find(text, true); + if (results.size() > 0) { + tree = ui.listMessages; + firstItem = dynamic_cast<QTreeWidgetItem *>(results.at(0)); }
if (! firstItem) { @@ -461,11 +454,13 @@ MessageLog::log(tc::Severity type, const QString &message)
/* This is a workaround to force Qt to update the statusbar text (if any * is currently displayed) to reflect the new message added. */ - QString currStatusTip = ui.statusbar->currentMessage(); - if (!currStatusTip.isEmpty()) { - currStatusTip = ui.listMessages->statusTip(); - ui.statusbar->showMessage(currStatusTip); - } + QString currStatusTip; + if(_statusBar && _onTop) + currStatusTip = _statusBar->currentMessage(); + if (!currStatusTip.isEmpty()) { + currStatusTip = ui.listMessages->statusTip(); + _statusBar->showMessage(currStatusTip); + }
/* If we're saving log messages to a file, go ahead and do that now */ if (_enableLogging) { diff --git a/src/vidalia/log/MessageLog.h b/src/vidalia/log/MessageLog.h index 3462ae1..56a938e 100644 --- a/src/vidalia/log/MessageLog.h +++ b/src/vidalia/log/MessageLog.h @@ -17,7 +17,7 @@ #define _MESSAGELOG_H
#include "ui_MessageLog.h" -#include "VidaliaWindow.h" +#include "VidaliaTab.h" #include "LogFile.h" #include "TorControl.h" #include "VidaliaSettings.h" @@ -25,13 +25,13 @@ class LogTreeItem; class QStringList;
-class MessageLog : public VidaliaWindow +class MessageLog : public VidaliaTab { Q_OBJECT
public: /** Default constructor **/ - MessageLog(QWidget *parent = 0, Qt::WFlags flags = 0); + MessageLog(QStatusBar *st = 0, QWidget *parent = 0); /** Default destructor **/ ~MessageLog();
@@ -90,6 +90,8 @@ private: /* The log file used to store log messages. */ LogFile _logFile;
+ QStatusBar *_statusBar; + /** Qt Designer generatated QObject **/ Ui::MessageLog ui; }; diff --git a/src/vidalia/log/MessageLog.ui b/src/vidalia/log/MessageLog.ui index f5a90cf..c72c0ba 100644 --- a/src/vidalia/log/MessageLog.ui +++ b/src/vidalia/log/MessageLog.ui @@ -1,237 +1,273 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MessageLog</class> - <widget class="QMainWindow" name="MessageLog"> + <widget class="QWidget" name="MessageLog"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>698</width> - <height>625</height> + <width>534</width> + <height>521</height> </rect> </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> <property name="windowTitle"> - <string>Message Log</string> - </property> - <property name="windowIcon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/32x32/format-justify-fill.png</normaloff>:/images/32x32/format-justify-fill.png</iconset> - </property> - <property name="statusTip"> - <string/> - </property> - <property name="autoFillBackground"> - <bool>true</bool> + <string notr="true"/> </property> - <property name="unifiedTitleAndToolBarOnMac"> - <bool>false</bool> - </property> - <widget class="QWidget" name="centralwidget"> - <layout class="QVBoxLayout"> - <property name="leftMargin"> - <number>12</number> - </property> - <property name="topMargin"> - <number>12</number> - </property> - <property name="rightMargin"> - <number>12</number> - </property> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>0</number> - </property> - <widget class="QWidget" name="tabBasic"> - <attribute name="title"> - <string>Basic</string> - </attribute> - <layout class="QGridLayout" name="basicTabLayout"> - <property name="margin"> - <number>12</number> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <item> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="LogTreeWidget" name="listMessages"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="autoFillBackground"> + <bool>false</bool> + </property> + <property name="alternatingRowColors"> + <bool>true</bool> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="rootIsDecorated"> + <bool>false</bool> + </property> + <property name="uniformRowHeights"> + <bool>true</bool> + </property> + <property name="itemsExpandable"> + <bool>false</bool> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <column> + <property name="text"> + <string>Time</string> </property> - <item row="0" column="0"> - <widget class="StatusEventWidget" name="listNotifications"> - <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> - </property> - <property name="horizontalScrollBarPolicy"> - <enum>Qt::ScrollBarAsNeeded</enum> - </property> - <property name="showDropIndicator" stdset="0"> - <bool>false</bool> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="selectionBehavior"> - <enum>QAbstractItemView::SelectRows</enum> - </property> - <property name="indentation"> - <number>0</number> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <attribute name="headerShowSortIndicator" stdset="0"> - <bool>true</bool> - </attribute> - <attribute name="headerShowSortIndicator" stdset="0"> - <bool>true</bool> - </attribute> - <column> - <property name="text"> - <string>Tor Status</string> - </property> - </column> - </widget> - </item> - </layout> + </column> + <column> + <property name="text"> + <string>Type</string> + </property> + </column> + <column> + <property name="text"> + <string>Message</string> + </property> + </column> </widget> - <widget class="QWidget" name="tabAdvanced"> - <attribute name="title"> - <string>Advanced</string> - </attribute> - <layout class="QGridLayout" name="advancedTabLayout"> + </item> + <item> + <widget class="QFrame" name="frmSettings"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>520</width> + <height>183</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>520</width> + <height>183</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="visible"> + <bool>true</bool> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> + </property> + <layout class="QGridLayout"> <property name="margin"> - <number>12</number> + <number>3</number> </property> - <item row="0" column="0"> - <widget class="LogTreeWidget" name="listMessages"> + <property name="spacing"> + <number>3</number> + </property> + <item row="0" column="2"> + <layout class="QHBoxLayout" name="_2"> + <item> + <spacer> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QVBoxLayout" name="_3"> + <item> + <widget class="QPushButton" name="btnSaveSettings"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string>Saves the current Message Log settings</string> + </property> + <property name="text"> + <string>Save Settings</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="btnCancelSettings"> + <property name="minimumSize"> + <size> + <width>90</width> + <height>0</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string>Cancels changes made to settings</string> + </property> + <property name="text"> + <string>Cancel</string> + </property> + </widget> + </item> + </layout> + </item> + </layout> + </item> + <item row="0" column="0" rowspan="2"> + <widget class="QGroupBox" name="groupBox"> <property name="contextMenuPolicy"> <enum>Qt::NoContextMenu</enum> </property> - <property name="autoFillBackground"> - <bool>false</bool> - </property> - <property name="alternatingRowColors"> - <bool>true</bool> - </property> - <property name="selectionMode"> - <enum>QAbstractItemView::ExtendedSelection</enum> - </property> - <property name="rootIsDecorated"> - <bool>false</bool> - </property> - <property name="uniformRowHeights"> - <bool>true</bool> + <property name="title"> + <string>Message Filter</string> </property> - <property name="itemsExpandable"> - <bool>false</bool> - </property> - <property name="sortingEnabled"> - <bool>true</bool> - </property> - <column> - <property name="text"> - <string>Time</string> - </property> - </column> - <column> - <property name="text"> - <string>Type</string> - </property> - </column> - <column> - <property name="text"> - <string>Message</string> - </property> - </column> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <widget class="QFrame" name="frmSettings"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="sizePolicy"> - <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>520</width> - <height>183</height> - </size> - </property> - <property name="maximumSize"> - <size> - <width>520</width> - <height>183</height> - </size> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="visible"> - <bool>false</bool> - </property> - <property name="frameShape"> - <enum>QFrame::StyledPanel</enum> - </property> - <property name="frameShadow"> - <enum>QFrame::Raised</enum> - </property> - <layout class="QGridLayout"> - <property name="margin"> - <number>3</number> - </property> - <property name="spacing"> - <number>3</number> - </property> - <item row="0" column="2"> - <layout class="QHBoxLayout"> - <item> - <spacer> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" > - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <layout class="QVBoxLayout"> + <layout class="QVBoxLayout" name="_4"> + <item> + <widget class="QCheckBox" name="chkTorErr"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="whatsThis"> + <string/> + </property> + <property name="text"> + <string>Error</string> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/emblem-important.png</normaloff>:/images/16x16/emblem-important.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="chkTorWarn"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>Warning</string> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/dialog-warning.png</normaloff>:/images/16x16/dialog-warning.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="chkTorNote"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>Notice</string> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/preferences-desktop-notification.png</normaloff>:/images/16x16/preferences-desktop-notification.png</iconset> + </property> + </widget> + </item> + <item> + <widget class="QCheckBox" name="chkTorInfo"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string/> + </property> + <property name="text"> + <string>Info</string> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/dialog-information.png</normaloff>:/images/16x16/dialog-information.png</iconset> + </property> + </widget> + </item> <item> - <widget class="QPushButton" name="btnSaveSettings"> + <widget class="QCheckBox" name="chkTorDebug"> <property name="contextMenuPolicy"> <enum>Qt::NoContextMenu</enum> </property> <property name="toolTip"> - <string>Saves the current Message Log settings</string> + <string/> </property> <property name="text"> - <string>Save Settings</string> + <string>Debug</string> + </property> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/16x16/applications-system.png</normaloff>:/images/16x16/applications-system.png</iconset> </property> </widget> </item> + </layout> + </widget> + </item> + <item row="0" column="1"> + <widget class="QGroupBox" name="grou"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="title"> + <string>Message Log History</string> + </property> + <layout class="QHBoxLayout" name="_5"> <item> - <widget class="QPushButton" name="btnCancelSettings"> + <widget class="QSpinBox" name="spnbxMaxCount"> <property name="minimumSize"> <size> - <width>90</width> + <width>50</width> <height>0</height> </size> </property> @@ -239,261 +275,98 @@ <enum>Qt::NoContextMenu</enum> </property> <property name="toolTip"> - <string>Cancels changes made to settings</string> + <string>Number of messages to display in the message log window</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight</set> + </property> + <property name="minimum"> + <number>1</number> + </property> + <property name="maximum"> + <number>99999</number> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="lblMessageCount"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> </property> <property name="text"> - <string>Cancel</string> + <string>messages</string> + </property> + <property name="textFormat"> + <enum>Qt::AutoText</enum> + </property> + <property name="alignment"> + <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> </property> </widget> </item> </layout> - </item> - </layout> - </item> - <item row="0" column="0" rowspan="2"> - <widget class="QGroupBox" name="groupBox"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="title"> - <string>Message Filter</string> - </property> - <layout class="QVBoxLayout"> - <item> - <widget class="QCheckBox" name="chkTorErr"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string/> - </property> - <property name="whatsThis"> - <string/> - </property> - <property name="text"> - <string>Error</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/16x16/emblem-important.png</normaloff>:/images/16x16/emblem-important.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkTorWarn"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>Warning</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/16x16/dialog-warning.png</normaloff>:/images/16x16/dialog-warning.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkTorNote"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>Notice</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/16x16/preferences-desktop-notification.png</normaloff>:/images/16x16/preferences-desktop-notification.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkTorInfo"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>Info</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/16x16/dialog-information.png</normaloff>:/images/16x16/dialog-information.png</iconset> - </property> - </widget> - </item> - <item> - <widget class="QCheckBox" name="chkTorDebug"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string/> - </property> - <property name="text"> - <string>Debug</string> - </property> - <property name="icon"> - <iconset resource="../res/vidalia.qrc"> - <normaloff>:/images/16x16/applications-system.png</normaloff>:/images/16x16/applications-system.png</iconset> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="0" column="1"> - <widget class="QGroupBox" name="grou"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="title"> - <string>Message Log History</string> - </property> - <layout class="QHBoxLayout"> - <item> - <widget class="QSpinBox" name="spnbxMaxCount"> - <property name="minimumSize"> - <size> - <width>50</width> - <height>0</height> - </size> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string>Number of messages to display in the message log window</string> - </property> - <property name="alignment"> - <set>Qt::AlignRight</set> - </property> - <property name="minimum"> - <number>1</number> - </property> - <property name="maximum"> - <number>99999</number> - </property> - </widget> - </item> - <item> - <widget class="QLabel" name="lblMessageCount"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="text"> - <string>messages</string> - </property> - <property name="textFormat"> - <enum>Qt::AutoText</enum> - </property> - <property name="alignment"> - <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set> - </property> - </widget> - </item> - </layout> - </widget> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QGroupBox" name="groupBox_2"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="title"> - <string>Always Save New Log Messages </string> - </property> - <layout class="QGridLayout"> - <property name="margin"> - <number>6</number> + </widget> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QGroupBox" name="groupBox_2"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> </property> - <item row="1" column="1"> - <widget class="QPushButton" name="btnBrowse"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="text"> - <string>Browse</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLineEdit" name="lineFile"> - <property name="enabled"> - <bool>false</bool> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - </widget> - </item> - <item row="0" column="0"> - <widget class="QCheckBox" name="chkEnableLogFile"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="toolTip"> - <string>Enable automatically saving all new log messages to a file</string> - </property> - <property name="text"> - <string>Automatically save new log messages to a file</string> - </property> - <property name="checked"> - <bool>false</bool> - </property> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - </item> - </layout> - </widget> - <widget class="QStatusBar" name="statusbar"/> - <widget class="QToolBar" name="toolBar"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="movable"> - <bool>false</bool> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextUnderIcon</enum> - </property> - <attribute name="toolBarArea"> - <enum>TopToolBarArea</enum> - </attribute> - <attribute name="toolBarBreak"> - <bool>false</bool> - </attribute> - <addaction name="actionSave_All"/> - <addaction name="actionSave_Selected"/> - <addaction name="separator"/> - <addaction name="actionCopy"/> - <addaction name="actionSelect_All"/> - <addaction name="actionFind"/> - <addaction name="actionClear"/> - <addaction name="separator"/> - <addaction name="actionSettings"/> - <addaction name="actionHelp"/> - <addaction name="actionClose"/> - </widget> + <property name="title"> + <string>Always Save New Log Messages </string> + </property> + <layout class="QGridLayout" name="_6"> + <property name="margin"> + <number>6</number> + </property> + <item row="1" column="1"> + <widget class="QPushButton" name="btnBrowse"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="text"> + <string>Browse</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLineEdit" name="lineFile"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + </widget> + </item> + <item row="0" column="0"> + <widget class="QCheckBox" name="chkEnableLogFile"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="toolTip"> + <string>Enable automatically saving all new log messages to a file</string> + </property> + <property name="text"> + <string>Automatically save new log messages to a file</string> + </property> + <property name="checked"> + <bool>false</bool> + </property> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </widget> + </item> + </layout> + </item> + </layout> <action name="actionMessage_Filters"> <property name="text"> <string>Message Filters...</string> @@ -667,33 +540,12 @@ <extends>QTreeWidget</extends> <header>log/LogTreeWidget.h</header> </customwidget> - <customwidget> - <class>StatusEventWidget</class> - <extends>QTreeWidget</extends> - <header>StatusEventWidget.h</header> - </customwidget> </customwidgets> <resources> <include location="../res/vidalia.qrc"/> </resources> <connections> <connection> - <sender>actionClose</sender> - <signal>triggered()</signal> - <receiver>MessageLog</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel"> - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel"> - <x>407</x> - <y>378</y> - </hint> - </hints> - </connection> - <connection> <sender>actionSettings</sender> <signal>toggled(bool)</signal> <receiver>frmSettings</receiver> @@ -704,8 +556,8 @@ <y>-1</y> </hint> <hint type="destinationlabel"> - <x>407</x> - <y>393</y> + <x>264</x> + <y>424</y> </hint> </hints> </connection> @@ -716,12 +568,12 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>373</x> - <y>491</y> + <x>283</x> + <y>461</y> </hint> <hint type="destinationlabel"> - <x>348</x> - <y>516</y> + <x>283</x> + <y>487</y> </hint> </hints> </connection> @@ -732,12 +584,12 @@ <slot>setEnabled(bool)</slot> <hints> <hint type="sourcelabel"> - <x>20</x> - <y>20</y> + <x>283</x> + <y>461</y> </hint> <hint type="destinationlabel"> - <x>20</x> - <y>20</y> + <x>473</x> + <y>487</y> </hint> </hints> </connection> diff --git a/src/vidalia/network/NetViewer.cpp b/src/vidalia/network/NetViewer.cpp index 2501537..1b22768 100644 --- a/src/vidalia/network/NetViewer.cpp +++ b/src/vidalia/network/NetViewer.cpp @@ -20,6 +20,7 @@ #include "VMessageBox.h"
#include <QMessageBox> +#include <QToolBar> #include <QHeaderView> #include <QCoreApplication>
@@ -41,7 +42,7 @@ * \param parent The parent widget of this NetViewer object.\ */ NetViewer::NetViewer(QWidget *parent) - : VidaliaWindow("NetViewer", parent) + : VidaliaTab(tr("Network Map"), "", parent) { /* Invoke Qt Designer generated QObject setup routine */ ui.setupUi(this); @@ -51,8 +52,8 @@ NetViewer::NetViewer(QWidget *parent) #endif
/* Pressing 'Esc' or 'Ctrl+W' will close the window */ - ui.actionClose->setShortcut(QString("Esc")); - Vidalia::createShortcut("Ctrl+W", this, ui.actionClose, SLOT(trigger())); +// ui.actionClose->setShortcut(QString("Esc")); +// Vidalia::createShortcut("Ctrl+W", this, ui.actionClose, SLOT(trigger()));
/* Get the TorControl object */ _torControl = Vidalia::torControl(); @@ -99,7 +100,6 @@ NetViewer::NetViewer(QWidget *parent) #endif ui.gridLayout->addWidget(_map);
- /* Connect zoom buttons to TorMapWidget zoom slots */ connect(ui.actionZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn())); connect(ui.actionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut())); @@ -130,6 +130,17 @@ NetViewer::NetViewer(QWidget *parent) _torControl, SLOT(closeStream(StreamId)));
setupGeoIpResolver(); + + QToolBar *tb = new QToolBar(); + tb->addAction(ui.actionRefresh); + tb->addAction(ui.actionHelp); + tb->addAction(ui.actionZoomIn); + tb->addAction(ui.actionZoomOut); + tb->addAction(ui.actionZoomToFit); + tb->addAction(ui.actionZoomFullScreen); + + tb->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); + ui.horizontalLayout->addWidget(tb); }
/** Called when the user changes the UI translation. */ @@ -137,6 +148,7 @@ void NetViewer::retranslateUi() { ui.retranslateUi(this); + setTitle(tr("Network Map")); ui.treeRouterList->retranslateUi(); ui.treeCircuitList->retranslateUi();
diff --git a/src/vidalia/network/NetViewer.h b/src/vidalia/network/NetViewer.h index e5c7208..0f01cac 100644 --- a/src/vidalia/network/NetViewer.h +++ b/src/vidalia/network/NetViewer.h @@ -18,7 +18,7 @@
#include "config.h" #include "ui_NetViewer.h" -#include "VidaliaWindow.h" +#include "VidaliaTab.h" #include "GeoIpResolver.h"
#if defined(USE_MARBLE) @@ -38,7 +38,7 @@ class QDateTime;
-class NetViewer : public VidaliaWindow +class NetViewer : public VidaliaTab { Q_OBJECT
diff --git a/src/vidalia/network/NetViewer.ui b/src/vidalia/network/NetViewer.ui index 63c8d88..863907b 100644 --- a/src/vidalia/network/NetViewer.ui +++ b/src/vidalia/network/NetViewer.ui @@ -1,353 +1,334 @@ -<ui version="4.0" > +<?xml version="1.0" encoding="UTF-8"?> +<ui version="4.0"> <class>NetViewer</class> - <widget class="QMainWindow" name="NetViewer" > - <property name="geometry" > + <widget class="QWidget" name="NetViewer"> + <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>844</width> - <height>596</height> + <width>694</width> + <height>552</height> </rect> </property> - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> + <property name="windowTitle"> + <string>Network Map</string> </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="windowTitle" > - <string>Tor Network Map</string> - </property> - <property name="windowIcon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/applications-internet.png</iconset> - </property> - <property name="toolButtonStyle" > - <enum>Qt::ToolButtonTextUnderIcon</enum> - </property> - <widget class="QWidget" name="centralwidget" > - <layout class="QVBoxLayout" > - <property name="margin" > - <number>9</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - <item> - <widget class="QSplitter" name="splitter" > - <property name="contextMenuPolicy" > + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <layout class="QHBoxLayout" name="horizontalLayout"/> + </item> + <item> + <widget class="QSplitter" name="splitter"> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="childrenCollapsible"> + <bool>false</bool> + </property> + <widget class="RouterListWidget" name="treeRouterList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>175</width> + <height>0</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> + </property> + <property name="statusTip"> + <string/> + </property> + <property name="selectionMode"> + <enum>QAbstractItemView::ExtendedSelection</enum> + </property> + <property name="indentation"> + <number>0</number> + </property> + <property name="sortingEnabled"> + <bool>true</bool> + </property> + <property name="columnCount"> + <number>3</number> + </property> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string/> + </property> + </column> + <column> + <property name="text"> + <string>Relay</string> + </property> + </column> + </widget> + <widget class="QSplitter" name="splitter3"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>100</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="contextMenuPolicy"> <enum>Qt::NoContextMenu</enum> </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> + <property name="orientation"> + <enum>Qt::Vertical</enum> </property> - <property name="childrenCollapsible" > + <property name="childrenCollapsible"> <bool>false</bool> </property> - <widget class="RouterListWidget" name="treeRouterList" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>7</vsizetype> - <horstretch>1</horstretch> - <verstretch>0</verstretch> + <widget class="QFrame" name="frmMap"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> + <horstretch>100</horstretch> + <verstretch>100</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> - <width>175</width> - <height>0</height> + <width>400</width> + <height>300</height> </size> </property> - <property name="contextMenuPolicy" > - <enum>Qt::DefaultContextMenu</enum> - </property> - <property name="statusTip" > - <string/> - </property> - <property name="indentation" > - <number>0</number> + <property name="contextMenuPolicy"> + <enum>Qt::NoContextMenu</enum> </property> - <property name="sortingEnabled" > - <bool>true</bool> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> </property> - <property name="selectionMode" > - <enum>QAbstractItemView::ExtendedSelection</enum> + <property name="frameShadow"> + <enum>QFrame::Raised</enum> </property> + <layout class="QHBoxLayout"> + <property name="spacing"> + <number>6</number> + </property> + <property name="margin"> + <number>9</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayout"> + <property name="margin"> + <number>0</number> + </property> + <property name="spacing"> + <number>6</number> + </property> + </layout> + </item> + </layout> </widget> - <widget class="QSplitter" name="splitter3" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> + <widget class="QSplitter" name="splitter2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> <horstretch>100</horstretch> - <verstretch>0</verstretch> + <verstretch>1</verstretch> </sizepolicy> </property> - <property name="contextMenuPolicy" > + <property name="contextMenuPolicy"> <enum>Qt::NoContextMenu</enum> </property> - <property name="orientation" > - <enum>Qt::Vertical</enum> + <property name="orientation"> + <enum>Qt::Horizontal</enum> </property> - <property name="childrenCollapsible" > + <property name="childrenCollapsible"> <bool>false</bool> </property> - <widget class="QFrame" name="frmMap" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>7</vsizetype> + <widget class="CircuitListWidget" name="treeCircuitList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>100</horstretch> <verstretch>100</verstretch> </sizepolicy> </property> - <property name="minimumSize" > + <property name="minimumSize"> <size> - <width>400</width> - <height>300</height> + <width>300</width> + <height>0</height> </size> </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> </property> - <property name="frameShape" > - <enum>QFrame::StyledPanel</enum> + <property name="statusTip"> + <string/> </property> - <property name="frameShadow" > - <enum>QFrame::Raised</enum> + <property name="sortingEnabled"> + <bool>false</bool> + </property> + <property name="columnCount"> + <number>2</number> </property> - <layout class="QHBoxLayout" > - <property name="margin" > - <number>9</number> + <column> + <property name="text"> + <string>Connection</string> </property> - <property name="spacing" > - <number>6</number> + </column> + <column> + <property name="text"> + <string>Status</string> </property> - <item> - <layout class="QGridLayout" > - <property name="margin" > - <number>0</number> - </property> - <property name="spacing" > - <number>6</number> - </property> - </layout> - </item> - </layout> + </column> </widget> - <widget class="QSplitter" name="splitter2" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>7</hsizetype> - <vsizetype>1</vsizetype> + <widget class="RouterDescriptorView" name="textRouterInfo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <horstretch>100</horstretch> - <verstretch>1</verstretch> + <verstretch>100</verstretch> </sizepolicy> </property> - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <property name="childrenCollapsible" > - <bool>false</bool> + <property name="readOnly"> + <bool>true</bool> </property> - <widget class="CircuitListWidget" name="treeCircuitList" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>100</horstretch> - <verstretch>100</verstretch> - </sizepolicy> - </property> - <property name="minimumSize" > - <size> - <width>300</width> - <height>0</height> - </size> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::CustomContextMenu</enum> - </property> - <property name="statusTip" > - <string/> - </property> - <property name="sortingEnabled" > - <bool>false</bool> - </property> - </widget> - <widget class="RouterDescriptorView" name="textRouterInfo" > - <property name="sizePolicy" > - <sizepolicy> - <hsizetype>5</hsizetype> - <vsizetype>5</vsizetype> - <horstretch>100</horstretch> - <verstretch>100</verstretch> - </sizepolicy> - </property> - <property name="contextMenuPolicy" > - <enum>Qt::DefaultContextMenu</enum> - </property> - <property name="readOnly" > - <bool>true</bool> - </property> - </widget> </widget> </widget> </widget> - </item> - </layout> - </widget> - <widget class="QStatusBar" name="statusbar" /> - <widget class="QToolBar" name="toolBar" > - <property name="contextMenuPolicy" > - <enum>Qt::NoContextMenu</enum> - </property> - <property name="movable" > - <bool>false</bool> - </property> - <property name="orientation" > - <enum>Qt::Horizontal</enum> - </property> - <attribute name="toolBarArea" > - <number>4</number> - </attribute> - <addaction name="actionRefresh" /> - <addaction name="separator" /> - <addaction name="actionZoomIn" /> - <addaction name="actionZoomOut" /> - <addaction name="actionZoomToFit" /> - <addaction name="actionZoomFullScreen" /> - <addaction name="separator" /> - <addaction name="actionHelp" /> - <addaction name="actionClose" /> - </widget> - <action name="actionRefresh" > - <property name="enabled" > + </widget> + </item> + </layout> + <action name="actionRefresh"> + <property name="enabled"> <bool>false</bool> </property> - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/view-refresh.png</iconset> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/view-refresh.png</normaloff>:/images/32x32/view-refresh.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Refresh</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Refresh the list of Tor relays and connections</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Refresh the list of Tor relays and connections</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>Ctrl+R</string> </property> </action> - <action name="actionHelp" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/system-help.png</iconset> + <action name="actionHelp"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/system-help.png</normaloff>:/images/32x32/system-help.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Help</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Show the network map help</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Show network map help</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>F1</string> </property> </action> - <action name="actionClose" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/window-close.png</iconset> + <action name="actionClose"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/window-close.png</normaloff>:/images/32x32/window-close.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Close</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Close the network map</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Close the network map</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>Esc</string> </property> </action> - <action name="actionZoomIn" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/zoom-in.png</iconset> + <action name="actionZoomIn"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/zoom-in.png</normaloff>:/images/32x32/zoom-in.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Zoom In</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Zoom in on the network map</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Zoom in on the network map</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>+</string> </property> </action> - <action name="actionZoomOut" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/zoom-out.png</iconset> + <action name="actionZoomOut"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/zoom-out.png</normaloff>:/images/32x32/zoom-out.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Zoom Out</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Zoom out on the network map</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Zoom out on the network map</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>-</string> </property> </action> - <action name="actionZoomToFit" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/zoom-fit-best.png</iconset> + <action name="actionZoomToFit"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/zoom-fit-best.png</normaloff>:/images/32x32/zoom-fit-best.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Zoom To Fit</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>Zooms to fit all currently displayed circuits</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>Zooms to fit all currently displayed circuits</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>Ctrl+Z</string> </property> </action> - <action name="actionZoomFullScreen" > - <property name="icon" > - <iconset resource="../res/vidalia.qrc" >:/images/32x32/view-fullscreen.png</iconset> + <action name="actionZoomFullScreen"> + <property name="icon"> + <iconset resource="../res/vidalia.qrc"> + <normaloff>:/images/32x32/view-fullscreen.png</normaloff>:/images/32x32/view-fullscreen.png</iconset> </property> - <property name="text" > + <property name="text"> <string>Full Screen</string> </property> - <property name="toolTip" > + <property name="toolTip"> <string>View the network map as a full screen window</string> </property> - <property name="statusTip" > + <property name="statusTip"> <string>View the network map as a full screen window</string> </property> - <property name="shortcut" > + <property name="shortcut"> <string>Ctrl+F</string> </property> </action> @@ -370,24 +351,7 @@ </customwidget> </customwidgets> <resources> - <include location="../res/vidalia.qrc" /> + <include location="../res/vidalia.qrc"/> </resources> - <connections> - <connection> - <sender>actionClose</sender> - <signal>triggered()</signal> - <receiver>NetViewer</receiver> - <slot>close()</slot> - <hints> - <hint type="sourcelabel" > - <x>-1</x> - <y>-1</y> - </hint> - <hint type="destinationlabel" > - <x>403</x> - <y>322</y> - </hint> - </hints> - </connection> - </connections> + <connections/> </ui>