[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[vidalia-svn] r3503: Merge changes from trunk (r3426-r3502) (in vidalia/branches/alt-launcher: . cmake debian debian/patches debian/po pkg/win32 src/common src/torcontrol src/vidalia src/vidalia/about src/vidalia/config src/vidalia/i18n/es src/vidalia/i18n/sv src/vidalia/network src/vidalia/res src/vidalia/res/128x128 src/vidalia/res/16x16 src/vidalia/res/22x22 src/vidalia/res/32x32 src/vidalia/res/48x48 src/vidalia/res/64x64 src/vidalia/res/icons)



Author: sjmurdoch
Date: 2009-02-02 12:47:07 -0500 (Mon, 02 Feb 2009)
New Revision: 3503

Added:
   vidalia/branches/alt-launcher/cmake/FindMarble.cmake
   vidalia/branches/alt-launcher/debian/faq
   vidalia/branches/alt-launcher/debian/patches/
   vidalia/branches/alt-launcher/debian/patches/debians-tor-binary-path.patch
   vidalia/branches/alt-launcher/debian/patches/series
   vidalia/branches/alt-launcher/debian/po/sv.po
   vidalia/branches/alt-launcher/src/common/countryinfo.cpp
   vidalia/branches/alt-launcher/src/common/countryinfo.h
   vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.cpp
   vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.h
   vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.cpp
   vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.h
   vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.ui
   vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.h
   vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.ui
   vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.h
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.h
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.h
   vidalia/branches/alt-launcher/src/vidalia/res/22x22/tor-logo.png
   vidalia/branches/alt-launcher/src/vidalia/res/64x64/
   vidalia/branches/alt-launcher/src/vidalia/res/64x64/tor-logo.png
   vidalia/branches/alt-launcher/src/vidalia/res/icons/placemark-relay.png
Removed:
   vidalia/branches/alt-launcher/debian/FAQ
   vidalia/branches/alt-launcher/debian/patches/debians-tor-binary-path.patch
   vidalia/branches/alt-launcher/debian/patches/series
   vidalia/branches/alt-launcher/src/vidalia/res/128x128/vidalia-logo.png
   vidalia/branches/alt-launcher/src/vidalia/res/16x16/status-green.png
   vidalia/branches/alt-launcher/src/vidalia/res/16x16/status-orange.png
   vidalia/branches/alt-launcher/src/vidalia/res/16x16/status-red.png
   vidalia/branches/alt-launcher/src/vidalia/res/22x22/status-green.png
   vidalia/branches/alt-launcher/src/vidalia/res/22x22/status-orange.png
   vidalia/branches/alt-launcher/src/vidalia/res/22x22/status-red.png
   vidalia/branches/alt-launcher/src/vidalia/res/22x22/vidalia.png
   vidalia/branches/alt-launcher/src/vidalia/res/32x32/status-green.png
   vidalia/branches/alt-launcher/src/vidalia/res/32x32/status-orange.png
   vidalia/branches/alt-launcher/src/vidalia/res/32x32/status-red.png
   vidalia/branches/alt-launcher/src/vidalia/res/48x48/status-green.png
   vidalia/branches/alt-launcher/src/vidalia/res/48x48/status-orange.png
   vidalia/branches/alt-launcher/src/vidalia/res/48x48/status-red.png
   vidalia/branches/alt-launcher/src/vidalia/res/48x48/vidalia.png
   vidalia/branches/alt-launcher/src/vidalia/res/64x64/tor-logo.png
   vidalia/branches/alt-launcher/src/vidalia/res/icons/status-green.icns
   vidalia/branches/alt-launcher/src/vidalia/res/icons/status-orange.icns
   vidalia/branches/alt-launcher/src/vidalia/res/icons/status-red.icns
Modified:
   vidalia/branches/alt-launcher/
   vidalia/branches/alt-launcher/CMakeLists.txt
   vidalia/branches/alt-launcher/INSTALL
   vidalia/branches/alt-launcher/config.h.in
   vidalia/branches/alt-launcher/debian/changelog
   vidalia/branches/alt-launcher/debian/control
   vidalia/branches/alt-launcher/debian/docs
   vidalia/branches/alt-launcher/debian/rules
   vidalia/branches/alt-launcher/pkg/win32/vidalia.wxs.in
   vidalia/branches/alt-launcher/src/common/CMakeLists.txt
   vidalia/branches/alt-launcher/src/common/stringutil.cpp
   vidalia/branches/alt-launcher/src/common/stringutil.h
   vidalia/branches/alt-launcher/src/torcontrol/CMakeLists.txt
   vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.cpp
   vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.h
   vidalia/branches/alt-launcher/src/torcontrol/torcontrol.cpp
   vidalia/branches/alt-launcher/src/torcontrol/torcontrol.h
   vidalia/branches/alt-launcher/src/torcontrol/torevents.cpp
   vidalia/branches/alt-launcher/src/vidalia/CMakeLists.txt
   vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.cpp
   vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.h
   vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.ui
   vidalia/branches/alt-launcher/src/vidalia/config/serverpage.cpp
   vidalia/branches/alt-launcher/src/vidalia/config/serverpage.h
   vidalia/branches/alt-launcher/src/vidalia/config/serverpage.ui
   vidalia/branches/alt-launcher/src/vidalia/config/servicepage.cpp
   vidalia/branches/alt-launcher/src/vidalia/config/servicepage.h
   vidalia/branches/alt-launcher/src/vidalia/config/torsettings.cpp
   vidalia/branches/alt-launcher/src/vidalia/config/torsettings.h
   vidalia/branches/alt-launcher/src/vidalia/controlpasswordinputdialog.cpp
   vidalia/branches/alt-launcher/src/vidalia/helperprocess.cpp
   vidalia/branches/alt-launcher/src/vidalia/helperprocess.h
   vidalia/branches/alt-launcher/src/vidalia/i18n/es/qt_es.po
   vidalia/branches/alt-launcher/src/vidalia/i18n/sv/qt_sv.po
   vidalia/branches/alt-launcher/src/vidalia/i18n/sv/vidalia_sv.po
   vidalia/branches/alt-launcher/src/vidalia/mainwindow.cpp
   vidalia/branches/alt-launcher/src/vidalia/mainwindow.h
   vidalia/branches/alt-launcher/src/vidalia/mainwindow.ui
   vidalia/branches/alt-launcher/src/vidalia/network/circuitlistwidget.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/netviewer.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/netviewer.h
   vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.h
   vidalia/branches/alt-launcher/src/vidalia/network/routerlistitem.h
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.cpp
   vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.h
   vidalia/branches/alt-launcher/src/vidalia/res/icons/vidalia.icns
   vidalia/branches/alt-launcher/src/vidalia/res/vidalia.qrc
   vidalia/branches/alt-launcher/src/vidalia/vidalia.cpp
   vidalia/branches/alt-launcher/src/vidalia/vidalia.desktop
Log:
Merge changes from trunk (r3426-r3502)



Property changes on: vidalia/branches/alt-launcher
___________________________________________________________________
Added: svn:mergeinfo
   + /vidalia/branches/marble:3435-3484
/vidalia/trunk:3426-3502

Modified: vidalia/branches/alt-launcher/CMakeLists.txt
===================================================================
--- vidalia/branches/alt-launcher/CMakeLists.txt	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/CMakeLists.txt	2009-02-02 17:47:07 UTC (rev 3503)
@@ -25,20 +25,28 @@
   cmake_policy(SET CMP0003 OLD)
 endif(COMMAND cmake_policy)
 
-## Require Qt >= 4.2.0
-set(QT_MIN_VERSION    "4.2.0")
+## We declare this option here, because it determines the minimum
+## required Qt version
+option(USE_MARBLE "Enable the KDE Marble-based map widget." OFF)
 
+## Specify the minimum version of Qt required
+if (USE_MARBLE)
+  set(QT_MIN_VERSION    "4.4.0")
+else(USE_MARBLE)
+  set(QT_MIN_VERSION    "4.2.0")
+endif(USE_MARBLE)
+
 ## Specify the Qt libraries used
 include(FindQt4)
 find_package(Qt4 REQUIRED)
 set(QT_USE_QTNETWORK  true)
 set(QT_USE_QTXML      true)
+set(QT_USE_QTSVG      true)
 include(${QT_USE_FILE})
 include(${CMAKE_SOURCE_DIR}/cmake/VidaliaMacros.cmake)
 include(CheckIncludeFile)
 include(CheckIncludeFileCXX)
 include(CheckTypeSize)
-include(CPack)
 if (WIN32)
   include(${CMAKE_SOURCE_DIR}/cmake/FindWiX.cmake)
 endif(WIN32)
@@ -83,6 +91,11 @@
   option(USE_AUTOUPDATE "Enable automatic software update support." OFF)
 endif(WIN32)
 
+## Find the KDE Marble library
+if (USE_MARBLE)
+  include(${CMAKE_SOURCE_DIR}/cmake/FindMarble.cmake)
+endif(USE_MARBLE)
+
 ## Check for system header files
 check_include_file("limits.h" HAVE_LIMITS_H)
 check_include_file("sys/limits.h" HAVE_SYS_LIMITS_H)

Modified: vidalia/branches/alt-launcher/INSTALL
===================================================================
--- vidalia/branches/alt-launcher/INSTALL	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/INSTALL	2009-02-02 17:47:07 UTC (rev 3503)
@@ -198,6 +198,8 @@
 
   -DCMAKE_BUILD_TYPE=<buildtype>          Available build types include:
                                             "release", "debug", "minsizerel"
+  -DUSE_MARBLE=1                          Replace the flat map with a
+                                          3-D sphere using the Marble libraries.
 
 For example, to configure CMake to look for Qt in "/usr/local/Qt-4.3.2/bin",
 you would run:

Copied: vidalia/branches/alt-launcher/cmake/FindMarble.cmake (from rev 3502, vidalia/trunk/cmake/FindMarble.cmake)
===================================================================
--- vidalia/branches/alt-launcher/cmake/FindMarble.cmake	                        (rev 0)
+++ vidalia/branches/alt-launcher/cmake/FindMarble.cmake	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,111 @@
+##
+##  $Id$
+## 
+##  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.
+##
+##  This file incorporates work from the KDE Marble project, and is covered by 
+##  the following copyright and permission notice:
+##
+##  Redistribution and use in source and binary forms, with or without
+##  modification, are permitted provided that the following conditions are
+##  met:
+##
+##   * Redistributions of source code must retain the above copyright notice,
+##     this list of conditions and the following disclaimer.
+##
+##   * Redistributions in binary form must reproduce the above copyright 
+##     notice, this list of conditions and the following disclaimer in the 
+##     documentation and/or other materials provided with the distribution.
+##
+##   * Neither the names of the copyright owners nor the names of its
+##     contributors may be used to endorse or promote products derived from 
+##     this software without specific prior written permission.
+##
+##  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS 
+##  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
+##  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
+##  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 
+##  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+##  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
+##  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 
+##  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
+##  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
+##  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 
+##  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+
+message(STATUS "Looking for Marble header files")
+find_path(MARBLE_INCLUDE_DIR
+  NAMES MarbleWidget.h
+  PATH_SUFFIXES marble
+)
+if (MARBLE_INCLUDE_DIR)
+  message(STATUS "Looking for Marble header files - found")
+else(MARBLE_INCLUDE_DIR)
+  message(FATAL_ERROR "Could not find Marble header files. If Marble is installed, you can run CMake again and specify its location with -DMARBLE_INCLUDE_DIR=<path>")
+endif(MARBLE_INCLUDE_DIR)
+
+
+message(STATUS "Looking for Marble libraries")
+find_library(MARBLEWIDGET_LIBRARY
+  NAMES marblewidget
+  PATHS ${MARBLE_LIBRARY_DIR}
+)
+if (MARBLEWIDGET_LIBRARY)
+  message(STATUS "Looking for Marble libraries - found")
+  set(MARBLE_LIBRARIES ${MARBLEWIDGET_LIBRARY})
+  get_filename_component(MARBLE_LIBRARY_DIR ${MARBLEWIDGET_LIBRARY} PATH)
+else(MARBLEWIDGET_LIBRARY)
+  message(FATAL_ERROR "Could not find Marble libraries. If Marble is installed, you can run CMake again and specify its location with -DMARBLE_LIBRARY_DIR=<path>")
+endif(MARBLEWIDGET_LIBRARY)
+
+
+if (APPLE OR WIN32)
+  message(STATUS "Looking for Marble data files")
+  find_path(MARBLE_DATA_DIR
+    NAMES srtm.dgml
+    PATH_SUFFIXES maps/earth/srtm
+  )
+  if (MARBLE_DATA_DIR)
+    message(STATUS "Looking for Marble data files - ${MARBLE_DATA_DIR}")
+  else (MARBLE_DATA_DIR)
+    message(FATAL_ERROR "Could not find Marble libraries. If Marble is installed, you can run CMake again and specify its location with -DMARBLE_DATA_DIR=<path>")
+  endif(MARBLE_DATA_DIR)
+
+
+  message(STATUS "Looking for Marble plugin widgets")
+  find_library(MARBLE_OVERVIEWMAP_PLUGIN
+    NAMES MarbleOverviewMap
+    PATHS ${MARBLE_PLUGIN_DIR}
+    PATH_SUFFIXES render/overviewmap
+  )
+  if (MARBLE_OVERVIEWMAP_PLUGIN)
+    message(STATUS "Looking for Marble plugin widgets - found overview map plugin")
+    set(MARBLE_PLUGINS ${MARBLE_PLUGINS}
+      ${MARBLE_OVERVIEWMAP_PLUGIN}
+    )
+  endif(MARBLE_OVERVIEWMAP_PLUGIN)
+
+  find_library(MARBLE_STARS_PLUGIN
+    NAMES MarbleStarsPlugin
+    PATHS ${MARBLE_PLUGIN_DIR}
+    PATH_SUFFIXES render/stars
+  )
+  if (MARBLE_STARS_PLUGIN)
+    message(STATUS "Looking for Marble plugin widgets - found stars plugin")
+    set(MARBLE_PLUGINS ${MARBLE_PLUGINS}
+      ${MARBLE_STARS_PLUGIN}
+    )
+  endif(MARBLE_STARS_PLUGIN)
+
+  if (NOT MARBLE_PLUGINS)
+    message(STATUS "Looking for Marble plugin widgets - none found")
+  endif(NOT MARBLE_PLUGINS)
+endif(APPLE OR WIN32)
+

Modified: vidalia/branches/alt-launcher/config.h.in
===================================================================
--- vidalia/branches/alt-launcher/config.h.in	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/config.h.in	2009-02-02 17:47:07 UTC (rev 3503)
@@ -30,5 +30,7 @@
 
 #cmakedefine USE_AUTOUPDATE
 
+#cmakedefine USE_MARBLE
+
 #endif
 

Modified: vidalia/branches/alt-launcher/debian/changelog
===================================================================
--- vidalia/branches/alt-launcher/debian/changelog	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/debian/changelog	2009-02-02 17:47:07 UTC (rev 3503)
@@ -1,3 +1,19 @@
+vidalia (0.1.10-2) unstable; urgency=low
+
+  * DQT_LRELEASE_EXECUTABLE and QT_LUPDATE_EXECUTABLE pointing to qt4 libs
+     avoids building conflicts if alternatives are pointing to qt3 ones.
+  * Patch to default Tor Executable path to Debian Tor's package binary path.
+
+ -- Ulises Vitulli <uvitulli@xxxxxxxxx>  Wed, 14 Jan 2009 14:02:06 -0200
+
+vidalia (0.1.10-1) unstable; urgency=low
+
+  * New upstream release.
+  * Debconf translations:
+    - Swedish (Closes #508751).
+
+ -- Vern Sun <s5unty@xxxxxxxxx>  Mon, 05 Jan 2009 16:59:04 +0800
+
 vidalia (0.1.9-3) unstable; urgency=low
 
   * Fixing missing copyright holders.

Modified: vidalia/branches/alt-launcher/debian/control
===================================================================
--- vidalia/branches/alt-launcher/debian/control	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/debian/control	2009-02-02 17:47:07 UTC (rev 3503)
@@ -3,7 +3,7 @@
 Priority: extra
 Maintainer: Vern Sun <s5unty@xxxxxxxxx>
 Uploaders: Ulises Vitulli <uvitulli@xxxxxxxxx>
-Build-Depends: debhelper (>= 5), autotools-dev, libqt4-dev (>= 4.1.0), po-debconf (>= 1.0), cmake (>= 2.4.8), libssl-dev (>= 0.9.8g)
+Build-Depends: debhelper (>= 5), autotools-dev, libqt4-dev (>= 4.1.0), po-debconf (>= 1.0), cmake (>= 2.4.8), libssl-dev (>= 0.9.8g), quilt
 Standards-Version: 3.8.0
 Homepage: http://www.vidalia-project.net
 

Modified: vidalia/branches/alt-launcher/debian/docs
===================================================================
--- vidalia/branches/alt-launcher/debian/docs	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/debian/docs	2009-02-02 17:47:07 UTC (rev 3503)
@@ -1,3 +1,3 @@
 README
 CREDITS
-debian/FAQ
+debian/faq

Copied: vidalia/branches/alt-launcher/debian/faq (from rev 3502, vidalia/trunk/debian/faq)
===================================================================
--- vidalia/branches/alt-launcher/debian/faq	                        (rev 0)
+++ vidalia/branches/alt-launcher/debian/faq	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,116 @@
+Frequently Asked Questions
+==========================
+
+   1. General
+         1. What is Vidalia?
+         2. Does Vidalia run on my operating system?
+         3. How can I find out when new Vidalia releases are available?
+         4. Where can I get additional support for Vidalia?
+   2. Running
+         1. I installed Vidalia/Tor/Privoxy. Now what?
+         2. Can I run Vidalia from a USB drive?
+         3. Can Vidalia "attach" to an existing Tor process?
+         4. Why do I see connections to geoip.vidalia-project.net in my network map?
+         5. Can I run a relay without worrying about abuse complaints?
+   3. Common problems
+         1. When I try to start Tor I get an error message in Vidalia's message log ...
+
+
+1.General
+=========
+
+1.1 What is Vidalia?
+--------------------
+
+Vidalia is a GUI for Tor, making it easy for you to run, monitor, and configure your installation of Tor. It lets you start and stop Tor, as well as letting you know when things go wrong. Vidalia also lets you see how much bandwidth Tor is using and can even help you set up your own Tor server.
+
+
+1.2 Does Vidalia run on my operating system?
+-------------------------------------------
+
+Vidalia is a cross-platform GUI built using the Qt GUI toolkit. Vidalia should run on any platform supported by Qt, which includes (but is not necessarily limited to):
+
+    * Windows 95/98/Me, NT4, 2000, XP, and Vista
+    * Mac OS X Panther (10.3), Tiger (10.4), and Leopard (10.5)
+    * Linux or other Unix variants running the X Window system. 
+
+
+1.3 How can I find out when new Vidalia releases are available?
+---------------------------------------------------------------
+
+Vidalia is still under active development and we tend to put out a new release approximately every 1-2 months. You can subscribe to our Trac RSS feed to learn when we have put out a new release. We also announce new releases on our homepage and on our download page.
+
+
+1.4 Where can I get additional support for Vidalia?
+---------------------------------------------------
+
+First, read through this FAQ and also search the documentation on our wiki. If you prefer IRC, you can find us in #vidalia on irc.oftc.net. Otherwise, we have a vidalia-users mailing list set up for Vidalia users to help out and answer each others' questions.
+
+
+2 Running
+=========
+
+2.1 I installed Vidalia/Tor/Privoxy. Now what?
+----------------------------------------------
+
+Now you need to configure your applications to send their traffic through Tor. Scott Squires has created an extension for Firefox called Torbutton that lets you easily toggle your browser's use of Tor. You might also check out FoxTor for a similar Firefox extension.
+
+See the Torify How-To for information on configuring several other applications to use Tor. The Tor documentation for Windows, Mac OS X, or Linux/BSD/Unix might be useful for you, as well.
+
+
+2.2 Can I run Vidalia from a USB drive?
+---------------------------------------
+
+Yes! You can run Vidalia from a USB drive, perhaps for a portable Tor/Vidalia/Polipo or Tor/Vidalia/Privoxy combination, by using Vidalia's -datadir command-line argument. The -datadir argument tells Vidalia where you would like it to store all of its configuration and application data. For example, you might have a batch file on your USB drive that starts Vidalia as follows:
+
+vidalia -datadir "."
+
+The above line would tell Vidalia to use the current working directory as its data directory. You can also configure Vidalia to look for a Tor executable and configuration file (torrc) on your USB drive using Vidalia's Settings dialog or editing Vidalia's configuration file (vidalia.conf).
+
+If you want to run the Windows version of Vidalia from a USB drive, you may also need to copy mingwm10.dll from a Vidalia or MinGW package onto your USB drive in the same directory as vidalia.exe.
+
+
+2.3 Can Vidalia "attach" to an existing Tor process?
+----------------------------------------------------
+
+Yes. Before Vidalia starts its own Tor process, it always first checks to see if it can connect to the control port of an existing Tor process. All you need to do is enable a control port on the Tor you already have running, and Vidalia will connect to it instead of starting its own Tor process. You first need to open your `torrc` in a text editor. Then, add the following line on a line by itself anywhere in your torrc:
+
+  ControlPort 9051
+
+You will also likely want to set a password for your control port to limit what applications are allowed to connect to it. To do so, you first need to open up a terminal or command prompt and run the following command (you may need to cd to the location of your Tor executable):
+
+#  tor --hash-password mypassword
+
+Replace "mypassword" with whatever password you would like to use for your control port. The last line of output from the above command will contain a string that starts with "16:" and is followed by a long string letters and numbers. This string is a hash of the password you supplied as an argument to the --hash-password command above. Copy this entire string, and then add a HashedControlPassword line to your torrc similar to the following:
+
+  "HashedControlPassword 16:816172DEB125A9CA603A6A8A5C16D0642DA4556E4EC417E6B9AAC9AF0D"
+
+Save your torrc changes and either restart or "HUP" your Tor process to reload your configuration. Then you can click 'Start Tor' in Vidalia, which will connect to your Tor process and then prompt you to enter your original control password ("mypassword" in the example above).
+
+
+
+2.4 Why do I see connections to geoip.vidalia-project.net in my network map?
+----------------------------------------------------------------------------
+
+Vidalia 0.0.5 added a network map feature that lets you see where in the world your traffic is going. To be able to map Tor relay IP addresses to approximate geographic locations, we use the GeoLite City database from MaxMind. Unfortunately, the database is around 24MB and shipping it alongside the Vidalia binary would be unreasonable. Consequently, we host the database on our servers and created a small perl script interface to it, allowing Vidalia clients to query the database via standard HTTP GET or POST requests.
+
+All communication between Vidalia and our servers is done over Tor, so our servers do not know who is making the requests. Additionally, no identifying information is included in the requests. Of course, you can verify this by looking at the source code, such as geoipresolver.cpp and torsocket.cpp. We also have a specification for the format of our geographic information requests and responses.
+
+
+2.5 Can I run a relay without worrying about abuse complaints?
+--------------------------------------------------------------
+
+Tor relay operators can specify which services and/or ports clients are allowed to access from their relay. From Vidalia's Exit Policies tab, you can select what services you want to allow clients to access from your relay. Vidalia's help documentation explains what each exit policy option means. By default, Tor relays allow access to many popular services, but restricts some (such as port 25) due to the potential for abuse. Tor's FAQ has more information for relay operators on how to avoid abuse complaints.
+
+Rather than running a normal, public Tor relay, you might also consider running a bridge relay. Some Internet Service Providers (ISPs) attempt to prevent users from accessing the Tor network by blocking connections to known Tor relays. Bridge relays (or bridges for short) are relays that help these censored users access the Tor network. Unlike other Tor relays, bridges are not listed in the same public directories as normal relays. Since there is no complete public list of them, even if your ISP is filtering connections to all the known Tor relays, they probably won't be able to block all the bridges.
+
+
+3 Common problems
+=================
+
+3.1 When I try to start Tor I get an error message in Vidalia's message log that says, "Failed to parse/validate config: Failed to bind one of the listener ports." What's that mean?
+-----------------------
+
+This error message typically means you already have a Tor process running that does not have an open control port. When Vidalia tried to start its own Tor process, Vidalia's Tor process conflicted with your existing Tor process. On Windows, you can look in your Task Manager for a process called tor.exe, select it, and then click "End Process" to terminate your Tor process. On most other operating systems, the ps and kill commands can help you find and terminate your existing Tor process. Then you can simply click 'Start Tor' in Vidalia, and Vidalia will start a new Tor process with the necessary arguments that allow Vidalia to communicate with and control Tor.
+
+If you would like Vidalia to connect to your existing Tor instead of starting a new Tor process, see the FAQ entry above on configuring a control port and password for your existing Tor process. 

Copied: vidalia/branches/alt-launcher/debian/patches/debians-tor-binary-path.patch (from rev 3502, vidalia/trunk/debian/patches/debians-tor-binary-path.patch)
===================================================================
--- vidalia/branches/alt-launcher/debian/patches/debians-tor-binary-path.patch	                        (rev 0)
+++ vidalia/branches/alt-launcher/debian/patches/debians-tor-binary-path.patch	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,12 @@
+--- old/src/vidalia/config/torsettings.cpp	2009-01-14 13:56:54.000000000 -0200
++++ new/src/vidalia/config/torsettings.cpp	2009-01-14 14:42:46.000000000 -0200
+@@ -67,7 +67,8 @@
+   else
+     setDefault(SETTING_TOR_EXECUTABLE, programFiles + "\\Tor\\tor.exe");
+ #else
+-  setDefault(SETTING_TOR_EXECUTABLE, "tor");
++  /** Debian patch for proper tor binary path */
++  setDefault(SETTING_TOR_EXECUTABLE, "/usr/sbin/tor");
+ #endif
+ 
+   setDefault(SETTING_TORRC,         Vidalia::dataDirectory() + "/torrc");

Copied: vidalia/branches/alt-launcher/debian/patches/series (from rev 3502, vidalia/trunk/debian/patches/series)
===================================================================
--- vidalia/branches/alt-launcher/debian/patches/series	                        (rev 0)
+++ vidalia/branches/alt-launcher/debian/patches/series	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1 @@
+debians-tor-binary-path.patch

Copied: vidalia/branches/alt-launcher/debian/po/sv.po (from rev 3502, vidalia/trunk/debian/po/sv.po)
===================================================================
--- vidalia/branches/alt-launcher/debian/po/sv.po	                        (rev 0)
+++ vidalia/branches/alt-launcher/debian/po/sv.po	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,50 @@
+# translation of vidalia.po to swedish
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Martin Bagge <brother@xxxxxxxx>, 2008.
+msgid ""
+msgstr ""
+"Project-Id-Version: vidalia\n"
+"Report-Msgid-Bugs-To: vidalia@xxxxxxxxxxxxxxxxxxx\n"
+"POT-Creation-Date: 2008-09-18 15:32-0300\n"
+"PO-Revision-Date: 2008-12-09 04:46+0100\n"
+"Last-Translator: Martin Bagge <brother@xxxxxxxx>\n"
+"Language-Team: swedish <debian-l10n-swedish@xxxxxxxxxxxxxxxx>\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"X-Generator: KBabel 1.11.4\n"
+
+#. Type: boolean
+#. Description
+#: ../templates:1001
+msgid "Do you want to stop the existing Tor process and let Vidalia start Tor?"
+msgstr ""
+"Vill du stoppa den existerande Torprocessen för att låta Vidalia starta Tor?"
+
+#. Type: boolean
+#. Description
+#: ../templates:1001
+msgid ""
+"It looks like there is a Tor process already running. If you want to start "
+"Tor using Vidalia, you might have to stop the existing Tor process. "
+"Otherwise you will have to enable 'ControlPort' option into Tor as explained "
+"in the documentation  carried with this package ('/usr/share/doc/vidalia/"
+"README.Debian')."
+msgstr ""
+"Det verkar som om det finns en Torprocess igång på den här datorn. Om du "
+"vill starta Tor med Vidalia behöver den nuvarande Torprocessen först "
+"avslutas. I annat fall måste du aktivera alternativet 'ControlPort' i Tor "
+"vilket förklaras i dokumentationen till det här paketet ('/usr/share/doc/"
+"vidalia/README.Debian')."
+
+#. Type: boolean
+#. Description
+#: ../templates:1001
+msgid ""
+"Note that if you choose to let Vidalia start Tor, you will have to manually "
+"disable  Tor starting automatically on every reboot (See 'README.Debian')."
+msgstr ""
+"Kom ihåg att om du låter Vidalia starta Tor måste du avaktivera automatisk "
+"start av Tor vid uppstart av systemet. (Läs mer i 'README.Debian')."

Modified: vidalia/branches/alt-launcher/debian/rules
===================================================================
--- vidalia/branches/alt-launcher/debian/rules	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/debian/rules	2009-02-02 17:47:07 UTC (rev 3503)
@@ -8,8 +8,8 @@
 
 # Uncomment this to turn on verbose mode.
 #export DH_VERBOSE=1
+include /usr/share/quilt/quilt.make
 
-
 # These are used for cross-compiling and for saving the configure script
 # from having to guess our platform (since we know it already)
 DEB_HOST_GNU_TYPE   ?= $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE)
@@ -29,17 +29,19 @@
 	dh_testdir
 	touch configure-stamp
 	
-build: build-stamp
+build: build-stamp $(QUILT_STAMPFN)
 
 build-stamp:
 	dh_testdir
 	mkdir -p debian/build;
 	cd debian/build; \
-		cmake ../.. -DCMAKE_INSTALL_PREFIX=/usr; \
+		cmake -DCMAKE_INSTALL_PREFIX=/usr \
+			-DQT_LRELEASE_EXECUTABLE=/usr/bin/lrelease-qt4 \
+			-QT_LUPDATE_EXECUTABLE=/usr/bin/lupdate-qt4 ../.. ;\
 		make
 	touch $@
 
-clean:
+clean: unpatch
 	dh_testdir
 	dh_testroot
 	rm -f build-stamp CMakeCache.txt doc/Doxyfile \

Modified: vidalia/branches/alt-launcher/pkg/win32/vidalia.wxs.in
===================================================================
--- vidalia/branches/alt-launcher/pkg/win32/vidalia.wxs.in	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/pkg/win32/vidalia.wxs.in	2009-02-02 17:47:07 UTC (rev 3503)
@@ -19,62 +19,194 @@
            EmbedCab="yes" DiskPrompt="CD-ROM #1" />
     <Property Id="DiskPrompt" Value="Vidalia @VERSION@ Installation [1]" />
 
+    <!-- Define the target installation directory hierarchy -->
     <Directory Id="TARGETDIR" Name="SourceDir">
       <Directory Id="ProgramFilesFolder" Name="ProgramFilesDir">
         <Directory Id="INSTALLDIR" Name="Vidalia">
+          <Directory Id="MarblePluginsDir" Name="plugins" />
+          <Directory Id="MarbleDataDir" Name="data">
+            <Directory Id="MarbleMapsDir" Name="maps">
+              <Directory Id="MarbleEarthMapsDir" Name="earth">
+                <Directory Id="MarbleBlueMarbleDataDir" Name="bluemarble" />
+                <Directory Id="MarbleCityLightsDataDir" Name="citylights" />
+                <Directory Id="MarbleSrtmDataDir" Name="srtm" />
+              </Directory>
+            </Directory>
+            <Directory Id="MarbleMwdbiiDir" Name="mwdbii" />
+            <Directory Id="MarblePlacemarkDataDir" Name="placemarks" />
+            <Directory Id="MarbleStarsDataDir" Name="stars" />
+            <Directory Id="MarbleSvgDataDir" Name="svg" />
+          </Directory>
+        </Directory>
+      </Directory>
+    </Directory>
 
-          <!-- Main Vidalia application files -->
-          <Component Id="VidaliaExecutable" Guid="*">
-            <File Id="VidaliaExe" DiskId="1"
-                  Name="vidalia.exe" Source="@Vidalia_BINARY_DIR@\src\vidalia\vidalia.exe" />
-          </Component>
+    <DirectoryRef Id="INSTALLDIR">
+      <!-- Main Vidalia application files -->
+      <Component Id="VidaliaExecutable" Guid="*">
+        <File Id="VidaliaExe" DiskId="1"
+              Name="vidalia.exe" Source="@Vidalia_BINARY_DIR@\src\vidalia\vidalia.exe" />
+      </Component>
 
-          <!-- Vidalia-related documents -->
-          <Component Id="VidaliaDocuments" Guid="6A51C86C-A7D4-407f-9B84-7ADCE016E939">
-            <File Id="VidaliaReadme" DiskId="1"
-                  Name="README" Source="@Vidalia_SOURCE_DIR@\README" />
-            <File Id="VidaliaCredits" DiskId="1"
-                  Name="CREDITS" Source="@Vidalia_SOURCE_DIR@\CREDITS" />
-            <File Id="VidaliaChangeLog" DiskId="1"
-                  Name="CHANGELOG" Source="@Vidalia_SOURCE_DIR@\CHANGELOG" />
-            <File Id="VidaliaLicense" DiskId="1"
-                  Name="LICENSE" Source="@Vidalia_SOURCE_DIR@\LICENSE" />
-            <File Id="VidaliaLicenseGplV2" DiskId="1"
-                  Name="LICENSE-GPLV2" Source="@Vidalia_SOURCE_DIR@\LICENSE-GPLV2" />
-            <File Id="VidaliaLicenseGplV3" DiskId="1"
-                  Name="LICENSE-GPLV3" Source="@Vidalia_SOURCE_DIR@\LICENSE-GPLV3" />
-            <File Id="VidaliaLicenseLgplV3" DiskId="1"
-                  Name="LICENSE-LGPLV3" Source="@Vidalia_SOURCE_DIR@\LICENSE-LGPLV3" />
-            <File Id="VidaliaLicenseOpenSSL" DiskId="1"
-                  Name="LICENSE-OPENSSL" Source="@Vidalia_SOURCE_DIR@\LICENSE-OPENSSL" />
-          </Component>
+      <!-- Vidalia-related documents -->
+      <Component Id="VidaliaDocuments" Guid="6A51C86C-A7D4-407f-9B84-7ADCE016E939">
+        <File Id="VidaliaReadme" DiskId="1"
+              Name="README" Source="@Vidalia_SOURCE_DIR@\README" />
+        <File Id="VidaliaCredits" DiskId="1"
+              Name="CREDITS" Source="@Vidalia_SOURCE_DIR@\CREDITS" />
+        <File Id="VidaliaChangeLog" DiskId="1"
+              Name="CHANGELOG" Source="@Vidalia_SOURCE_DIR@\CHANGELOG" />
+        <File Id="VidaliaLicense" DiskId="1"
+              Name="LICENSE" Source="@Vidalia_SOURCE_DIR@\LICENSE" />
+        <File Id="VidaliaLicenseGplV2" DiskId="1"
+              Name="LICENSE-GPLV2" Source="@Vidalia_SOURCE_DIR@\LICENSE-GPLV2" />
+        <File Id="VidaliaLicenseGplV3" DiskId="1"
+              Name="LICENSE-GPLV3" Source="@Vidalia_SOURCE_DIR@\LICENSE-GPLV3" />
+        <File Id="VidaliaLicenseLgplV3" DiskId="1"
+              Name="LICENSE-LGPLV3" Source="@Vidalia_SOURCE_DIR@\LICENSE-LGPLV3" />
+        <File Id="VidaliaLicenseOpenSSL" DiskId="1"
+              Name="LICENSE-OPENSSL" Source="@Vidalia_SOURCE_DIR@\LICENSE-OPENSSL" />
+      </Component>
 
-          <!-- Qt-related library files -->
-          <Component Id="QtLibrary" Guid="00F354CB-B313-4100-8900-11293A66B385">
-            <File Id="QtCore4Dll" DiskId="1"
-                  Name="QtCore4.dll" Source="@QT_BINARY_DIR@\QtCore4.dll" />
-            <File Id="QtGui4Dll" DiskId="1"
-                  Name="QtGui4.dll" Source="@QT_BINARY_DIR@\QtGui4.dll" />
-            <File Id="QtNetwork4Dll" DiskId="1"
-                  Name="QtNetwork4.dll" Source="@QT_BINARY_DIR@\QtNetwork4.dll" />
-            <File Id="QtXml4Dll" DiskId="1"
-                  Name="QtXml4.dll" Source="@QT_BINARY_DIR@\QtXml4.dll" />
-          </Component>
+      <!-- Qt-related library files -->
+      <Component Id="QtLibrary" Guid="00F354CB-B313-4100-8900-11293A66B385">
+        <File Id="QtCore4Dll" DiskId="1"
+              Name="QtCore4.dll" Source="@QT_BINARY_DIR@\QtCore4.dll" />
+        <File Id="QtGui4Dll" DiskId="1"
+              Name="QtGui4.dll" Source="@QT_BINARY_DIR@\QtGui4.dll" />
+        <File Id="QtNetwork4Dll" DiskId="1"
+              Name="QtNetwork4.dll" Source="@QT_BINARY_DIR@\QtNetwork4.dll" />
+        <File Id="QtXml4Dll" DiskId="1"
+              Name="QtXml4.dll" Source="@QT_BINARY_DIR@\QtXml4.dll" />
+        <File Id="QtSvg4Dll" DiskId="1"
+              Name="QtSvg4.dll" Source="@QT_BINARY_DIR@\QtSvg4.dll" />
+      </Component>
 
-          <!-- MinGW-related library files -->
-          <Component Id="MinGWLibrary" Guid="2287E844-F9CD-4129-8BD0-50D071698194">
-            <File Id="MinGWDll" DiskId="1"
-                  Name="mingwm10.dll" Source="@MINGW_BINARY_DIR@\mingwm10.dll" />
-          </Component>
+      <!-- MinGW-related library files -->
+      <Component Id="MinGWLibrary" Guid="2287E844-F9CD-4129-8BD0-50D071698194">
+        <File Id="MinGWDll" DiskId="1"
+              Name="mingwm10.dll" Source="@MINGW_BINARY_DIR@\mingwm10.dll" />
+      </Component>
 
-          <!-- OpenSSL-related library files -->
-          <Component Id="OpenSSLLibrary" Guid="C3EDC2EC-D0B1-452a-83A6-85B0BC94735B">
-            <File Id="ssleay32dll" DiskId="1"
-                  Name="ssleay32.dll" Source="@OPENSSL_BINARY_DIR@\ssleay32.dll" />
-          </Component>
-        </Directory>
-      </Directory>
+      <!-- OpenSSL-related library files -->
+      <Component Id="OpenSSLLibrary" Guid="C3EDC2EC-D0B1-452a-83A6-85B0BC94735B">
+        <File Id="ssleay32dll" DiskId="1"
+              Name="ssleay32.dll" Source="@OPENSSL_BINARY_DIR@\ssleay32.dll" />
+      </Component>
+      
+      <!-- Marble-related library files -->
+      <Component Id="MarbleWidgetLibrary" Guid="A2968B8D-0E23-4649-B8F3-A988A04F823C">
+        <File Id="MarbleWidgetDll" DiskId="1"
+              Name="libmarblewidget.dll" Source="@MARBLEWIDGET_LIBRARY@" />
+      </Component>
+    </DirectoryRef>
+    
+    <!-- Marble-related plugin files -->
+    <DirectoryRef Id="MarblePluginsDir">
+      <Component Id="MarblePlugins" Guid="B4665EC1-3082-4fca-AA7E-60512ED62EF6">
+        <File Id="MarbleOverviewMapPlugin" DiskId="1"
+              Name="libMarbleOverviewMap.dll" Source="@MARBLE_OVERVIEWMAP_PLUGIN@" />
+        <File Id="MarbleStarsPlugin" DiskId="1"
+              Name="libMarbleStarsPlugin.dll" Source="@MARBLE_STARS_PLUGIN@" />
+      </Component>
+    </DirectoryRef>
+          
+    <!-- Marble-related data files -->
+    <DirectoryRef Id="MarbleDataDir">
+      <Component Id="MarbleLegendsData" Guid="FA6F733F-8249-4b2b-B978-2AA04E06F5D5">
+        <File Id="LandColorsLegend" DiskId="1"
+              Name="landcolors.leg" Source="@MARBLE_DATA_DIR@\landcolors.leg" />
+        <File Id="SeaColorsLegend" DiskId="1"
+              Name="seacolors.leg" Source="@MARBLE_DATA_DIR@\seacolors.leg" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleBlueMarbleDataDir">
+      <Component Id="MarbleBlueMarbleData" Guid="392FEE6B-374A-447a-AECC-0422915305DB">
+        <File Id="MarbleBlueMarbleDgml" DiskId="1"
+              Name="bluemarble.dgml" Source="@MARBLE_DATA_DIR@\maps\earth\bluemarble\bluemarble.dgml" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleCityLightsDataDir">
+      <Component Id="MarbleCityLightsData" Guid="DBF9FBE7-012D-4457-ABB4-9085F7E784F8">
+        <File Id="MarbleCityLightsDgml" DiskId="1"
+              Name="citylights.dgml" Source="@MARBLE_DATA_DIR@\maps\earth\citylights\citylights.dgml" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleSrtmDataDir">
+      <Component Id="MarbleSrtmData" Guid="2C3A9C67-92CB-4fc6-A2F6-AD9118AFD58C">
+        <File Id="MarbleSrtmDgml" DiskId="1"
+              Name="srtm.dgml" Source="@MARBLE_DATA_DIR@\maps\earth\srtm\srtm.dgml" />
+        <File Id="MarbleSrtmJpg" DiskId="1"
+              Name="srtm.jpg" Source="@MARBLE_DATA_DIR@\maps\earth\srtm\srtm.jpg" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleMwdbiiDir">
+      <Component Id="MarbleMwdbiiData" Guid="56ACE658-6892-408a-91E5-7B5BD23D8829">
+        <File Id="DatelinePnt" DiskId="1"
+              Name="DATELINE.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\DATELINE.PNT" />
+        <File Id="PAustPnt" DiskId="1"
+              Name="PAUST.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PAUST.PNT" />
+        <File Id="PBorderPnt" DiskId="1"
+              Name="PBORDER.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PBORDER.PNT" />
+        <File Id="PCanProvPnt" DiskId="1"
+              Name="PCANPROV.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PCANPROV.PNT" />
+        <File Id="PCoastPnt" DiskId="1"
+              Name="PCOAST.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PCOAST.PNT" />
+        <File Id="PDiffBorderPnt" DiskId="1"
+              Name="PDIFFBORDER.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PDIFFBORDER.PNT" />
+        <File Id="PGlacierPnt" DiskId="1"
+              Name="PGLACIER.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PGLACIER.PNT" />
+        <File Id="PIslandPnt" DiskId="1"
+              Name="PISLAND.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PISLAND.PNT" />
+        <File Id="PLakePnt" DiskId="1"
+              Name="PLAKE.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PLAKE.PNT" />
+        <File Id="PLakeIslandPnt" DiskId="1"
+              Name="PLAKEISLAND.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PLAKEISLAND.PNT" />
+        <File Id="PMexicoPnt" DiskId="1"
+              Name="PMEXICO.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PMEXICO.PNT" />
+        <File Id="PUsa48DiffPnt" DiskId="1"
+              Name="PUSA48.DIFF.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PUSA48.DIFF.PNT" />
+        <File Id="PUsa48Pnt" DiskId="1"
+              Name="PUSA48.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\PUSA48.PNT" />
+        <File Id="RiverPnt" DiskId="1"
+              Name="RIVER.PNT" Source="@MARBLE_DATA_DIR@\mwdbii\RIVER.PNT" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarblePlacemarkDataDir">
+      <Component Id="MarblePlacemarkData" Guid="27D54547-A819-435b-9A0C-13284169A9D9">
+        <File Id="BasePlacemarksCache" DiskId="1"
+              Name="baseplacemarks.cache" Source="@MARBLE_DATA_DIR@\placemarks\baseplacemarks.cache" />
+        <File Id="BoundaryPlacemarksCache" DiskId="1"
+              Name="boundaryplacemarks.cache" Source="@MARBLE_DATA_DIR@\placemarks\boundaryplacemarks.cache" />
+        <File Id="ElevPlacemarksCache" DiskId="1"
+              Name="elevplacemarks.cache" Source="@MARBLE_DATA_DIR@\placemarks\elevplacemarks.cache" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleStarsDataDir">
+      <Component Id="MarbleStarsData" Guid="8C5C3F32-67E6-4a4a-9B6C-6D67A6D44D67">
+        <File Id="StarsDat" DiskId="1"
+              Name="stars.dat" Source="@MARBLE_DATA_DIR@\stars\stars.dat" />
+      </Component>
+    </DirectoryRef>
+    <DirectoryRef Id="MarbleSvgDataDir">
+      <Component Id="MarbleSvgData" Guid="03E25BCA-4C58-4571-9F17-061D52877714">
+        <File Id="WorldMapSvg" DiskId="1"
+              Name="worldmap.svg" Source="@MARBLE_DATA_DIR@\svg\worldmap.svg" />
+      </Component>
+    </DirectoryRef>
+    <ComponentGroup Id="MarbleData">
+      <ComponentRef Id="MarbleLegendsData" />
+      <ComponentRef Id="MarbleBlueMarbleData" />
+      <ComponentRef Id="MarbleCityLightsData" />
+      <ComponentRef Id="MarbleSrtmData" />
+      <ComponentRef Id="MarbleMwdbiiData" />
+      <ComponentRef Id="MarblePlacemarkData" />
+      <ComponentRef Id="MarbleStarsData" />
+      <ComponentRef Id="MarbleSvgData" />
+    </ComponentGroup>
 
+    <!-- Application shortcuts and menu items -->
+    <DirectoryRef Id="TARGETDIR">
       <Directory Id="ProgramMenuFolder" Name="Programs">
         <Directory Id="ShortcutFolder" Name="Vidalia">
           <Component Id="AddVidaliaToStartMenu" Guid="0F2CEE2C-8730-432e-8A8F-E49AF78AF28C">
@@ -109,7 +241,7 @@
           <RegistryValue Name="Vidalia" Value='"[INSTALLDIR]vidalia.exe"' Type="string" />
         </RegistryKey>
       </Component>
-    </Directory>
+    </DirectoryRef>
 
     <!-- Build up the feature hierarchy -->
     <Feature Id="Complete" Title="Vidalia"
@@ -123,6 +255,9 @@
         <ComponentRef Id="QtLibrary" />
         <ComponentRef Id="MinGWLibrary" />
         <ComponentRef Id="OpenSSLLibrary" />
+        <ComponentRef Id="MarbleWidgetLibrary" />
+        <ComponentRef Id="MarblePlugins" />
+        <ComponentGroupRef Id="MarbleData"/>
       </Feature>
       <Feature Id="Shortcuts" Title="Shortcuts"
                AllowAdvertise="no" Absent="allow" Level="1"

Modified: vidalia/branches/alt-launcher/src/common/CMakeLists.txt
===================================================================
--- vidalia/branches/alt-launcher/src/common/CMakeLists.txt	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/common/CMakeLists.txt	2009-02-02 17:47:07 UTC (rev 3503)
@@ -12,6 +12,7 @@
 
 
 set(common_SRCS
+  countryinfo.cpp
   crypto.cpp
   file.cpp
   html.cpp
@@ -22,7 +23,10 @@
   torsocket.cpp
   zlibbytearray.cpp
 )
-qt4_wrap_cpp(common_SRCS torsocket.h)
+qt4_wrap_cpp(common_SRCS 
+  countryinfo.h
+  torsocket.h
+)
 
 
 if(USE_QSSLSOCKET)

Copied: vidalia/branches/alt-launcher/src/common/countryinfo.cpp (from rev 3502, vidalia/trunk/src/common/countryinfo.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/common/countryinfo.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/common/countryinfo.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,238 @@
+/*
+**  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 countryinfo.cpp
+** \version $Id$
+** \brief Provides a method to look up a localized country name given its
+** ISO 3166 2-letter country code.
+*/
+
+#include <QMap>
+
+#include "countryinfo.h"
+
+
+CountryInfo::CountryInfo(QObject *parent)
+  : QObject(parent)
+{
+}
+
+QString
+CountryInfo::countryName(const QString &countryCode)
+{
+  static QMap<QString,QString> db;
+  if (db.isEmpty()) {
+    db.insert("af", QT_TR_NOOP("Afghanistan"));
+    db.insert("al", QT_TR_NOOP("Albania "));
+    db.insert("dz", QT_TR_NOOP("Algeria "));
+    db.insert("ad", QT_TR_NOOP("Andorra"));
+    db.insert("ao", QT_TR_NOOP("Angola"));
+    db.insert("ag", QT_TR_NOOP("Antigua & Barbuda"));
+    db.insert("ar", QT_TR_NOOP("Argentina"));
+    db.insert("am", QT_TR_NOOP("Armenia"));
+    db.insert("au", QT_TR_NOOP("Australia"));
+    db.insert("at", QT_TR_NOOP("Austria "));
+    db.insert("az", QT_TR_NOOP("Azerbaijan"));
+    db.insert("bs", QT_TR_NOOP("Bahamas"));
+    db.insert("bh", QT_TR_NOOP("Bahrain "));
+    db.insert("bd", QT_TR_NOOP("Bangladesh"));
+    db.insert("bb", QT_TR_NOOP("Barbados"));
+    db.insert("by", QT_TR_NOOP("Belarus"));
+    db.insert("be", QT_TR_NOOP("Belgium"));
+    db.insert("bz", QT_TR_NOOP("Belize"));
+    db.insert("bj", QT_TR_NOOP("Benin "));
+    db.insert("bt", QT_TR_NOOP("Bhutan"));
+    db.insert("bo", QT_TR_NOOP("Bolivia"));
+    db.insert("ba", QT_TR_NOOP("Bosnia & Herzegovina"));
+    db.insert("bw", QT_TR_NOOP("Botswana"));
+    db.insert("br", QT_TR_NOOP("Brazil"));
+    db.insert("bn", QT_TR_NOOP("Brunei Darussalam"));
+    db.insert("bg", QT_TR_NOOP("Bulgaria"));
+    db.insert("bf", QT_TR_NOOP("Burkina Faso"));
+    db.insert("bi", QT_TR_NOOP("Burundi"));
+    db.insert("kh", QT_TR_NOOP("Cambodia"));
+    db.insert("cm", QT_TR_NOOP("Cameroon"));
+    db.insert("ca", QT_TR_NOOP("Canada"));
+    db.insert("cv", QT_TR_NOOP("Cape Verde"));
+    db.insert("cf", QT_TR_NOOP("Central African Republic"));
+    db.insert("td", QT_TR_NOOP("Chad"));
+    db.insert("cl", QT_TR_NOOP("Chile"));
+    db.insert("cn", QT_TR_NOOP("China"));
+    db.insert("co", QT_TR_NOOP("Colombia"));
+    db.insert("km", QT_TR_NOOP("Comoros"));
+    db.insert("cd", QT_TR_NOOP("Congo, The Democratic Republic of the"));
+    db.insert("cg", QT_TR_NOOP("Congo"));
+    db.insert("cr", QT_TR_NOOP("Costa Rica"));
+    db.insert("ci", QT_TR_NOOP("Cote d’Ivoire"));
+    db.insert("hr", QT_TR_NOOP("Croatia"));
+    db.insert("cu", QT_TR_NOOP("Cuba"));
+    db.insert("cy", QT_TR_NOOP("Cyprus"));
+    db.insert("cz", QT_TR_NOOP("Czech Republic"));
+    db.insert("dk", QT_TR_NOOP("Denmark"));
+    db.insert("dj", QT_TR_NOOP("Djibouti"));
+    db.insert("dm", QT_TR_NOOP("Dominica"));
+    db.insert("do", QT_TR_NOOP("Dominican Republic"));
+    db.insert("ec", QT_TR_NOOP("Ecuador"));
+    db.insert("eg", QT_TR_NOOP("Egypt"));
+    db.insert("sv", QT_TR_NOOP("El Salvador"));
+    db.insert("gq", QT_TR_NOOP("Equatorial Guinea"));
+    db.insert("er", QT_TR_NOOP("Eritrea"));
+    db.insert("ee", QT_TR_NOOP("Estonia"));
+    db.insert("et", QT_TR_NOOP("Ethiopia "));
+    db.insert("fj", QT_TR_NOOP("Fiji "));
+    db.insert("fi", QT_TR_NOOP("Finland "));
+    db.insert("fr", QT_TR_NOOP("France"));
+    db.insert("ga", QT_TR_NOOP("Gabon"));
+    db.insert("gm", QT_TR_NOOP("Gambia"));
+    db.insert("ge", QT_TR_NOOP("Georgia"));
+    db.insert("de", QT_TR_NOOP("Germany"));
+    db.insert("gh", QT_TR_NOOP("Ghana"));
+    db.insert("gr", QT_TR_NOOP("Greece "));
+    db.insert("gd", QT_TR_NOOP("Grenada"));
+    db.insert("gt", QT_TR_NOOP("Guatemala"));
+    db.insert("gu", QT_TR_NOOP("Guam "));
+    db.insert("gn", QT_TR_NOOP("Guinea"));
+    db.insert("gw", QT_TR_NOOP("Guinea-Bissau"));
+    db.insert("gy", QT_TR_NOOP("Guyana"));
+    db.insert("hk", QT_TR_NOOP("Hong Kong"));
+    db.insert("ht", QT_TR_NOOP("Haiti"));
+    db.insert("hn", QT_TR_NOOP("Honduras"));
+    db.insert("hu", QT_TR_NOOP("Hungary "));
+    db.insert("is", QT_TR_NOOP("Iceland "));
+    db.insert("in", QT_TR_NOOP("India "));
+    db.insert("id", QT_TR_NOOP("Indonesia "));
+    db.insert("ir", QT_TR_NOOP("Iran "));
+    db.insert("iq", QT_TR_NOOP("Iraq "));
+    db.insert("ie", QT_TR_NOOP("Ireland "));
+    db.insert("il", QT_TR_NOOP("Israel"));
+    db.insert("it", QT_TR_NOOP("Italy"));
+    db.insert("jm", QT_TR_NOOP("Jamaica"));
+    db.insert("jp", QT_TR_NOOP("Japan"));
+    db.insert("jo", QT_TR_NOOP("Jordan"));
+    db.insert("kz", QT_TR_NOOP("Kazakhstan"));
+    db.insert("ke", QT_TR_NOOP("Kenya"));
+    db.insert("ki", QT_TR_NOOP("Kiribati"));
+    db.insert("kp", QT_TR_NOOP("Korea, North "));
+    db.insert("kr", QT_TR_NOOP("Korea, South "));
+    db.insert("kw", QT_TR_NOOP("Kuwait"));
+    db.insert("kg", QT_TR_NOOP("Kyrgyzstan"));
+    db.insert("la", QT_TR_NOOP("Laos"));
+    db.insert("lv", QT_TR_NOOP("Latvia"));
+    db.insert("lb", QT_TR_NOOP("Lebanon"));
+    db.insert("ls", QT_TR_NOOP("Lesotho"));
+    db.insert("lr", QT_TR_NOOP("Liberia"));
+    db.insert("ly", QT_TR_NOOP("Libya "));
+    db.insert("li", QT_TR_NOOP("Liechtenstein"));
+    db.insert("lt", QT_TR_NOOP("Lithuania"));
+    db.insert("lu", QT_TR_NOOP("Luxembourg"));
+    db.insert("mk", QT_TR_NOOP("Macedonia"));
+    db.insert("mg", QT_TR_NOOP("Madagascar"));
+    db.insert("mw", QT_TR_NOOP("Malawi"));
+    db.insert("my", QT_TR_NOOP("Malaysia"));
+    db.insert("mv", QT_TR_NOOP("Maldives "));
+    db.insert("ml", QT_TR_NOOP("Mali"));
+    db.insert("mt", QT_TR_NOOP("Malta"));
+    db.insert("mh", QT_TR_NOOP("Marshall Islands"));
+    db.insert("mr", QT_TR_NOOP("Mauritania"));
+    db.insert("mu", QT_TR_NOOP("Mauritius"));
+    db.insert("mx", QT_TR_NOOP("Mexico "));
+    db.insert("fm", QT_TR_NOOP("Micronesia"));
+    db.insert("md", QT_TR_NOOP("Moldova"));
+    db.insert("mc", QT_TR_NOOP("Monaco"));
+    db.insert("mn", QT_TR_NOOP("Mongolia"));
+    db.insert("me", QT_TR_NOOP("Montenegro"));
+    db.insert("ma", QT_TR_NOOP("Morocco"));
+    db.insert("mz", QT_TR_NOOP("Mozambique"));
+    db.insert("mm", QT_TR_NOOP("Myanmar "));
+    db.insert("na", QT_TR_NOOP("Namibia"));
+    db.insert("nr", QT_TR_NOOP("Nauru"));
+    db.insert("np", QT_TR_NOOP("Nepal"));
+    db.insert("nl", QT_TR_NOOP("Netherlands"));
+    db.insert("nz", QT_TR_NOOP("New Zealand"));
+    db.insert("ni", QT_TR_NOOP("Nicaragua"));
+    db.insert("ne", QT_TR_NOOP("Niger"));
+    db.insert("ng", QT_TR_NOOP("Nigeria"));
+    db.insert("no", QT_TR_NOOP("Norway"));
+    db.insert("om", QT_TR_NOOP("Oman"));
+    db.insert("pk", QT_TR_NOOP("Pakistan"));
+    db.insert("pw", QT_TR_NOOP("Palau"));
+    db.insert("ps", QT_TR_NOOP("Palestine"));
+    db.insert("pa", QT_TR_NOOP("Panama"));
+    db.insert("pg", QT_TR_NOOP("Papua New Guinea"));
+    db.insert("py", QT_TR_NOOP("Paraguay"));
+    db.insert("pe", QT_TR_NOOP("Peru"));
+    db.insert("ph", QT_TR_NOOP("Philippines"));
+    db.insert("pl", QT_TR_NOOP("Poland"));
+    db.insert("pt", QT_TR_NOOP("Portugal"));
+    db.insert("qa", QT_TR_NOOP("Qatar"));
+    db.insert("ro", QT_TR_NOOP("Romania"));
+    db.insert("ru", QT_TR_NOOP("Russia"));
+    db.insert("rw", QT_TR_NOOP("Rwanda"));
+    db.insert("kn", QT_TR_NOOP("Saint Kitts & Nevis"));
+    db.insert("lc", QT_TR_NOOP("Saint Lucia"));
+    db.insert("vc", QT_TR_NOOP("Saint Vincent & the Grenadines"));
+    db.insert("ws", QT_TR_NOOP("Samoa"));
+    db.insert("sm", QT_TR_NOOP("San Marino"));
+    db.insert("st", QT_TR_NOOP("Sao Tome & Principe"));
+    db.insert("sa", QT_TR_NOOP("Saudi Arabia"));
+    db.insert("sn", QT_TR_NOOP("Senegal"));
+    db.insert("rs", QT_TR_NOOP("Serbia"));
+    db.insert("sc", QT_TR_NOOP("Seychelles"));
+    db.insert("sl", QT_TR_NOOP("Sierra Leone"));
+    db.insert("sg", QT_TR_NOOP("Singapore"));
+    db.insert("sk", QT_TR_NOOP("Slovakia"));
+    db.insert("si", QT_TR_NOOP("Slovenia"));
+    db.insert("sb", QT_TR_NOOP("Solomon Islands"));
+    db.insert("so", QT_TR_NOOP("Somalia"));
+    db.insert("za", QT_TR_NOOP("South Africa"));
+    db.insert("es", QT_TR_NOOP("Spain"));
+    db.insert("lk", QT_TR_NOOP("Sri Lanka"));
+    db.insert("sd", QT_TR_NOOP("Sudan"));
+    db.insert("sr", QT_TR_NOOP("Suriname"));
+    db.insert("sz", QT_TR_NOOP("Swaziland"));
+    db.insert("se", QT_TR_NOOP("Sweden"));
+    db.insert("ch", QT_TR_NOOP("Switzerland"));
+    db.insert("sy", QT_TR_NOOP("Syria"));
+    db.insert("tw", QT_TR_NOOP("Taiwan "));
+    db.insert("tj", QT_TR_NOOP("Tajikistan"));
+    db.insert("tz", QT_TR_NOOP("Tanzania"));
+    db.insert("th", QT_TR_NOOP("Thailand"));
+    db.insert("tl", QT_TR_NOOP("Timor-Leste (East Timor)"));
+    db.insert("tg", QT_TR_NOOP("Togo"));
+    db.insert("to", QT_TR_NOOP("Tonga"));
+    db.insert("tt", QT_TR_NOOP("Trinidad & Tobago"));
+    db.insert("tn", QT_TR_NOOP("Tunisia"));
+    db.insert("tr", QT_TR_NOOP("Turkey"));
+    db.insert("tm", QT_TR_NOOP("Turkmenistan"));
+    db.insert("tv", QT_TR_NOOP("Tuvalu"));
+    db.insert("ug", QT_TR_NOOP("Uganda"));
+    db.insert("ua", QT_TR_NOOP("Ukraine"));
+    db.insert("ae", QT_TR_NOOP("United Arab Emirates"));
+    db.insert("gb", QT_TR_NOOP("United Kingdom"));
+    db.insert("us", QT_TR_NOOP("United States"));
+    db.insert("uy", QT_TR_NOOP("Uruguay"));
+    db.insert("uz", QT_TR_NOOP("Uzbekistan"));
+    db.insert("vu", QT_TR_NOOP("Vanuatu"));
+    db.insert("va", QT_TR_NOOP("Vatican"));
+    db.insert("ve", QT_TR_NOOP("Venezuela"));
+    db.insert("vn", QT_TR_NOOP("Vietnam"));
+    db.insert("eh", QT_TR_NOOP("Western Sahara"));
+    db.insert("ye", QT_TR_NOOP("Yemen"));
+    db.insert("zm", QT_TR_NOOP("Zambia"));
+    db.insert("zw", QT_TR_NOOP("Zimbabwe"));
+  }
+
+  QString cc = countryCode.toLower();
+  if (db.contains(cc))
+    return  tr(db.value(cc).toLocal8Bit().data());
+  return QString();
+}
+

Copied: vidalia/branches/alt-launcher/src/common/countryinfo.h (from rev 3502, vidalia/trunk/src/common/countryinfo.h)
===================================================================
--- vidalia/branches/alt-launcher/src/common/countryinfo.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/common/countryinfo.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -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 countryinfo.h
+** \version $Id$
+** \brief Provides a method to look up a localized country name given its
+** ISO 3166-1 2-letter country code.
+*/
+
+#ifndef _COUNTRYINFO_H
+#define _COUNTRYINFO_H
+
+#include <QObject>
+#include <QString>
+
+
+class CountryInfo : public QObject
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor.
+   */
+  CountryInfo(QObject *parent);
+
+  /** Returns the name of the country represented by <b>countryCode</b>, where
+   * <b>countryCode</b> is a 2-letter ISO 3166-1 alpha-2 two-letter country
+   * code. The name will be returned translated to the current locale if an
+   * appropriate QTranslator is currently installed.
+   */
+  static QString countryName(const QString &countryCode);
+};
+
+#endif
+

Modified: vidalia/branches/alt-launcher/src/common/stringutil.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/common/stringutil.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/common/stringutil.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -14,6 +14,8 @@
 ** \brief Common string manipulation functions
 */
 
+#include <QCoreApplication>
+
 #include "stringutil.h"
 
 
@@ -305,3 +307,49 @@
   return true;
 }
 
+/** Returns a human-readable description of the time elapsed given by
+ * <b>seconds</b>, broken down into days, hours, minutes and seconds. */
+QString
+string_format_uptime(quint64 seconds)
+{
+  QString uptime;
+  int secs  = (seconds % 60);
+  int mins  = (seconds / 60 % 60);
+  int hours = (seconds / 3600 % 24);
+  int days  = (seconds / 86400);
+
+  if (days)
+    uptime += qApp->translate("stringutil.h", "%1 days ").arg(days);
+  if (hours)
+    uptime += qApp->translate("stringutil.h", "%1 hours ").arg(hours);
+  if (mins)
+    uptime += qApp->translate("stringutil.h", "%1 mins ").arg(mins);
+  if (secs)
+    uptime += qApp->translate("stringutil.h", "%1 secs").arg(secs);
+
+  return uptime;
+}
+
+/** Returns a string representation of <b>date</b> formatted according to
+ * "yyyy-MM-dd HH:mm:ss". */
+QString
+string_format_datetime(const QDateTime &date)
+{
+  return date.toString("yyyy-MM-dd HH:mm:ss");
+}
+
+/** Returns a string representation of <b>bytes</b> with the appropriate
+ * suffix of either "B/s", "KB/s", "MB/s" or "GB/s". */
+QString
+string_format_bandwidth(quint64 bytes)
+{
+  if (bytes < 1024)
+    return qApp->translate("stringutil.h", "%1 B/s").arg(bytes);
+  if (bytes < 1048576)
+    return qApp->translate("stringutil.h", "%1 KB/s").arg(bytes/1024.0, 0, 'f', 2);
+  if (bytes < 1073741824)
+    return qApp->translate("stringutil.h", "%1 MB/s").arg(bytes/1048576.0, 0, 'f', 2);
+
+  return qApp->translate("stringutil.h", "%1 GB/s").arg(bytes/1073741824.0, 0, 'f', 2);
+}
+

Modified: vidalia/branches/alt-launcher/src/common/stringutil.h
===================================================================
--- vidalia/branches/alt-launcher/src/common/stringutil.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/common/stringutil.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -19,6 +19,7 @@
 
 #include <QStringList>
 #include <QHash>
+#include <QDateTime>
 
 
 /** Creates a QStringList from the array of C strings. */
@@ -73,5 +74,17 @@
  * otherwise. */
 bool string_is_hex(const QString &str);
 
+/** Returns a human-readable description of the time elapsed given by
+ * <b>seconds</b>, broken down into days, hours, minutes and seconds. */
+QString string_format_uptime(quint64 seconds);
+
+/** Returns a string representation of <b>date</b> formatted according to
+ * "yyyy-MM-dd HH:mm:ss". */
+QString string_format_datetime(const QDateTime &date);
+
+/** Returns a string representation of <b>bytes</b> with the appropriate
+ * (localized) suffix of either "B/s", "KB/s", "MB/s" or "GB/s". */
+QString string_format_bandwidth(quint64 bytes);
+
 #endif
 

Modified: vidalia/branches/alt-launcher/src/torcontrol/CMakeLists.txt
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/CMakeLists.txt	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/CMakeLists.txt	2009-02-02 17:47:07 UTC (rev 3503)
@@ -20,6 +20,7 @@
   controlconnection.cpp
   controlreply.cpp
   controlsocket.cpp
+  dangerousportevent.cpp
   dangerousversionevent.cpp
   generalstatusevent.cpp
   logevent.cpp

Modified: vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -30,6 +30,8 @@
     return CircuitEstablished;
   if (!str.compare("CIRCUIT_NOT_ESTABLISHED", Qt::CaseInsensitive))
     return CircuitNotEstablished;
+  if (!str.compare("DANGEROUS_PORT", Qt::CaseInsensitive))
+    return DangerousPort;
   if (!str.compare("DANGEROUS_SOCKS", Qt::CaseInsensitive))
     return DangerousSocks;
   if (!str.compare("SOCKS_UNKNOWN_PROTOCOL", Qt::CaseInsensitive))

Modified: vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.h
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/clientstatusevent.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -31,6 +31,7 @@
     CircuitNotEstablished,
     NotEnoughDirectoryInfo,
     EnoughDirectoryInfo,
+    DangerousPort,
     DangerousSocks,
     UnknownSocksProtocol,
     SocksBadHostname

Copied: vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.cpp (from rev 3502, vidalia/trunk/src/torcontrol/dangerousportevent.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,38 @@
+/*
+**  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 dangerousportevent.h
+** \version $Id$
+** \brief Event sent when the client makes a connection to a port listed in
+** their WarnPlaintextPorts or RejectPlaintextPorts settings.
+*/
+
+#include "dangerousportevent.h"
+
+
+DangerousPortEvent::DangerousPortEvent(tc::Severity severity, quint16 port,
+                                       Result result)
+  : ClientStatusEvent(severity, ClientStatusEvent::DangerousPort),
+    _port(port),
+    _result(result)
+{
+}
+
+DangerousPortEvent::Result
+DangerousPortEvent::resultFromString(const QString &str)
+{
+  if (!str.compare("WARN", Qt::CaseInsensitive))
+    return DangerousPortEvent::Warn;
+  if (!str.compare("REJECT", Qt::CaseInsensitive))
+    return DangerousPortEvent::Reject;
+  return DangerousPortEvent::UnrecognizedResult;
+}
+

Copied: vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.h (from rev 3502, vidalia/trunk/src/torcontrol/dangerousportevent.h)
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/torcontrol/dangerousportevent.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,66 @@
+/*
+**  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 dangerousversionevent.h
+** \version $Id$
+** \brief Event sent when Tor realizes its version is not recommended
+*/
+
+#ifndef _DANGEROUSPORTEVENT_H
+#define _DANGEROUSPORTEVENT_H
+
+#include <QString>
+
+#include "clientstatusevent.h"
+
+
+class DangerousPortEvent : public ClientStatusEvent
+{
+
+public:
+  /** Possible actions that Tor takes in response to a client connection
+   * to a plaintext port.
+   */
+  enum Result {
+    UnrecognizedResult,
+    Reject,
+    Warn,
+  };
+  
+  /** Constructs a new DangerousPortEvent object, using <b>severity</b>
+   * as the event severity level. <b>port</b> and <b>result</b> describe
+   * the port on which a potential plaintext connection was attempted
+   * and the action Tor took in response, respectively.
+   */
+  DangerousPortEvent(tc::Severity severity, quint16 port, Result result);
+
+  /** Returns the DangerousPortEvent::Result enum value specified in this
+   * event's constructor.
+   */
+  Result result() const { return _result; }
+
+  /** Returns the port specified in this event's constructor.
+   */
+  quint16 port() const { return _port; }
+
+  /** Returns an DangerousPortEvent::Result enum value corresponding to the
+   * event result described in <b>str</b>, or UnrecognizedResult if <b>str</b>
+   * does not contain a valid Result type.
+   */
+  static Result resultFromString(const QString &str);
+
+private:
+  quint16 _port;
+  Result _result;
+};
+
+#endif
+

Modified: vidalia/branches/alt-launcher/src/torcontrol/torcontrol.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/torcontrol.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/torcontrol.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -27,20 +27,20 @@
    * it an object to use to handle asynchronous events. */
   _controlConn = new ControlConnection(&_torEvents);
   QObject::connect(_controlConn, SIGNAL(connected()),
-                   this, SLOT(onConnected()));
+                   this, SIGNAL(connected()));
   QObject::connect(_controlConn, SIGNAL(connectFailed(QString)),
-                   this, SLOT(onConnectFailed(QString)));
+                   this, SIGNAL(connectFailed(QString)));
   QObject::connect(_controlConn, SIGNAL(disconnected()),
                    this, SLOT(onDisconnected()));
 
   /* Create an object used to start and stop a Tor process. */
   _torProcess = new TorProcess(this);
   QObject::connect(_torProcess, SIGNAL(started()),
-                   this, SLOT(onStarted()));
+                   this, SIGNAL(started()));
   QObject::connect(_torProcess, SIGNAL(finished(int, QProcess::ExitStatus)),
                    this, SLOT(onStopped(int, QProcess::ExitStatus)));
   QObject::connect(_torProcess, SIGNAL(startFailed(QString)),
-                   this, SLOT(onStartFailed(QString)));
+                   this, SIGNAL(startFailed(QString)));
   QObject::connect(_torProcess, SIGNAL(log(QString, QString)),
                    this, SLOT(onLogStdout(QString, QString)));
 
@@ -90,21 +90,6 @@
   }
 }
 
-/** Emits a signal that the Tor process started */
-void
-TorControl::onStarted()
-{
-  emit started();
-}
-
-/** Emits a signal that the Tor process failed to start and includes an error
- * message (hopefully) indicating why. */
-void
-TorControl::onStartFailed(QString errmsg)
-{
-  emit startFailed(errmsg);
-}
-
 /** Stop the Tor process. */
 bool
 TorControl::stop(QString *errmsg)
@@ -160,22 +145,6 @@
   _controlConn->connect(address, port);
 }
 
-/** Emits a signal that the control socket successfully established a
- * connection to Tor. */
-void
-TorControl::onConnected()
-{
-  /* Let interested parties know that the control socket connected */
-  emit connected();
-}
-
-/** Emits a signal that the control connection to Tor failed. */
-void
-TorControl::onConnectFailed(QString errmsg)
-{
-  emit connectFailed(errmsg);
-}
-
 /** Disconnect from Tor's control port */
 void
 TorControl::disconnect()
@@ -879,14 +848,23 @@
   return resetConf(QStringList() << key, errmsg);
 }
 
+/** Returns an unparsed router descriptor for the router whose fingerprint
+ * matches <b>id</b>. The returned text can later be parsed by the
+ * RouterDescriptor class. If <b>id</b> is invalid, then an empty
+ * QStringList is returned. */
+QStringList
+TorControl::getRouterDescriptorText(const QString &id, QString *errmsg)
+{
+  return getInfo("desc/id/" + id, errmsg).toStringList();
+}
+
 /** Returns the descriptor for the router whose fingerprint matches
  * <b>id</b>. If <b>id</b> is invalid or the router's descriptor cannot
  * be parsed, then an invalid RouterDescriptor is returned. */
 RouterDescriptor
 TorControl::getRouterDescriptor(const QString &id, QString *errmsg)
 {
-  QStringList descriptor = getInfo("desc/id/" + id, errmsg).toStringList();
-  return RouterDescriptor(descriptor);
+  return RouterDescriptor(getRouterDescriptorText(id, errmsg));
 }
 
 /** Returns the status of the router whose fingerprint matches <b>id</b>. If

Modified: vidalia/branches/alt-launcher/src/torcontrol/torcontrol.h
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/torcontrol.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/torcontrol.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -165,6 +165,11 @@
   /** Tells Tor to reset a configuration key back to its default value. */
   bool resetConf(QString key, QString *errmsg = 0);
 
+  /** Returns an unparsed router descriptor for the router whose fingerprint
+   * matches <b>id</b>. The returned text can later be parsed by the
+   * RouterDescriptor class. If <b>id</b> is invalid, then an empty
+   * QStringList is returned. */
+  QStringList getRouterDescriptorText(const QString &id, QString *errmsg = 0);
   /** Returns the descriptor for the router whose fingerprint matches
    * <b>id</b>. If <b>id</b> is invalid or the router's descriptor cannot be
    * parsed, then an invalid RouterDescriptor is returned. */
@@ -248,11 +253,7 @@
 
 /* The slots below simply relay signals from the appropriate member objects */
 private slots:
-  void onStarted();
-  void onStartFailed(QString errmsg);
   void onStopped(int exitCode, QProcess::ExitStatus exitStatus);
-  void onConnected();
-  void onConnectFailed(QString errmsg);
   void onDisconnected();
   void onLogStdout(QString severity, QString message);
   void onAuthenticated();

Modified: vidalia/branches/alt-launcher/src/torcontrol/torevents.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/torcontrol/torevents.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/torcontrol/torevents.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -25,6 +25,7 @@
 #include "unrecognizedgeneralstatusevent.h"
 #include "circuitestablishedevent.h"
 #include "dangerousversionevent.h"
+#include "dangerousportevent.h"
 #include "bootstrapstatusevent.h"
 
 /** Format of expiry times in address map events. */
@@ -404,8 +405,14 @@
 
   switch (status) {
     case ClientStatusEvent::CircuitEstablished:
-      event = new CircuitEstablishedEvent(severity); break;
+      event = new CircuitEstablishedEvent(severity);
+      break;
     
+    case ClientStatusEvent::DangerousPort:
+      event = new DangerousPortEvent(severity, args.value("PORT").toUInt(),
+                    DangerousPortEvent::resultFromString(args.value("RESULT")));
+      break;
+ 
     case ClientStatusEvent::Bootstrap:
       event = new BootstrapStatusEvent(BootstrapStatus(severity,
                     BootstrapStatus::statusFromString(args.value("TAG")),

Modified: vidalia/branches/alt-launcher/src/vidalia/CMakeLists.txt
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/CMakeLists.txt	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/CMakeLists.txt	2009-02-02 17:47:07 UTC (rev 3503)
@@ -16,7 +16,25 @@
   ${CMAKE_CURRENT_SOURCE_DIR}
   ${CMAKE_CURRENT_SOURCE_DIR}/config
   ${CMAKE_CURRENT_SOURCE_DIR}/help/browser
+  ${MARBLE_INCLUDE_DIR}
 )
+if (APPLE)
+##
+## XXX: The Marble build system on OS X currently doesn't actually install the
+## required include files to /usr/local/include or similar. Instead, we have
+## to pluck them directly from the source tree. Ick.
+##
+  include_directories(
+    ${MARBLE_INCLUDE_DIR}/AbstractLayer
+    ${MARBLE_INCLUDE_DIR}/geodata
+    ${MARBLE_INCLUDE_DIR}/geodata/data
+    ${MARBLE_INCLUDE_DIR}/geodata/handlers
+    ${MARBLE_INCLUDE_DIR}/geodata/parser
+    ${MARBLE_INCLUDE_DIR}/geodata/scene
+    ${MARBLE_INCLUDE_DIR}/Projections
+  )
+endif(APPLE)
+
 configure_file(
   ${CMAKE_CURRENT_SOURCE_DIR}/res/vidalia_win.rc.in
   ${CMAKE_CURRENT_SOURCE_DIR}/res/vidalia_win.rc
@@ -54,6 +72,7 @@
   config/abstracttorsettings.cpp
   config/advancedpage.cpp
   config/appearancepage.cpp
+  config/bridgeusagedialog.cpp
   config/configdialog.cpp
   config/configpagestack.cpp
   config/domainvalidator.cpp
@@ -79,6 +98,7 @@
   config/abstracttorsettings.h
   config/advancedpage.h
   config/appearancepage.h
+  config/bridgeusagedialog.h
   config/configdialog.h
   config/configpage.h
   config/configpagestack.h
@@ -147,21 +167,40 @@
   network/geoipresponse.cpp
   network/netviewer.cpp
   network/routerdescriptorview.cpp
+  network/routerinfodialog.cpp
   network/routerlistitem.cpp
   network/routerlistwidget.cpp
   network/streamitem.cpp
-  network/tormapwidget.cpp
-  network/zimageview.cpp
 )
 qt4_wrap_cpp(vidalia_SRCS
   network/circuitlistwidget.h
   network/geoipresolver.h
   network/netviewer.h
   network/routerdescriptorview.h
+  network/routerinfodialog.h
   network/routerlistwidget.h
-  network/tormapwidget.h
-  network/zimageview.h
 )
+if (USE_MARBLE)
+  set(vidalia_SRCS ${vidalia_SRCS}
+    network/tormapwidget.cpp
+    network/tormapwidgetinputhandler.cpp
+    network/tormapwidgetpopupmenu.cpp
+  )
+  qt4_wrap_cpp(vidalia_SRCS
+    network/tormapwidget.h
+    network/tormapwidgetinputhandler.h
+    network/tormapwidgetpopupmenu.h
+  )
+else(USE_MARBLE)
+  set(vidalia_SRCS ${vidalia_SRCS}
+    network/tormapimageview.cpp
+    network/zimageview.cpp
+  )
+  qt4_wrap_cpp(vidalia_SRCS
+    network/tormapimageview.h
+    network/zimageview.h
+  )
+endif(USE_MARBLE)
 
 ## Choose the correct tray icon implementation for the current platform
 set(vidalia_SRCS ${vidalia_SRCS} tray/trayicon.cpp)
@@ -206,6 +245,7 @@
   bwgraph/bwgraph.ui
   config/advancedpage.ui
   config/appearancepage.ui
+  config/bridgeusagedialog.ui
   config/configdialog.ui
   config/generalpage.ui
   config/networkpage.ui
@@ -214,6 +254,7 @@
   help/browser/helpbrowser.ui
   log/messagelog.ui
   network/netviewer.ui
+  network/routerinfodialog.ui
 )
 
 if (USE_MINIUPNPC)
@@ -245,6 +286,35 @@
   ${CMAKE_CURRENT_BINARY_DIR}/i18n/vidalia_i18n.qrc
 )
 
+## 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
+)
+
 ## Set the appropriate executable target for the current platform
 if (APPLE)
   ## Set the output file name (make it uppercase on OS X)
@@ -271,14 +341,80 @@
       ARGS ${CMAKE_CURRENT_SOURCE_DIR}/res/icons/*.icns 
            ${CMAKE_CURRENT_BINARY_DIR}/Vidalia.app/Contents/Resources/
   )
+
+  ## Copy the Marble data into the bundle
+  if (USE_MARBLE)
+    foreach(it ${marble_DATA})
+      get_filename_component(outdir  ${it} PATH)
+      get_filename_component(outfile ${it} NAME)
+      set(outdir Vidalia.app/Contents/Resources/data/${outdir})
+
+      add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+        COMMAND ${CMAKE_COMMAND}
+          ARGS -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${outdir}
+        COMMAND ${CMAKE_COMMAND}
+          ARGS -E copy_if_different 
+                ${MARBLE_DATA_DIR}/${it} 
+                ${CMAKE_CURRENT_BINARY_DIR}/${outdir}/${outfile}
+      )
+    endforeach(it)
+
+    ## Create the Marble plugins directory and copy in any wanted plugins
+    if (MARBLE_PLUGINS)
+      add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+        COMMAND ${CMAKE_COMMAND}
+          ARGS -E make_directory 
+           ${CMAKE_CURRENT_BINARY_DIR}/Vidalia.app/Contents/Resources/plugins
+      )
+      foreach(it ${MARBLE_PLUGINS})
+        add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+          COMMAND ${CMAKE_COMMAND}
+            ARGS -E copy_if_different ${it}
+             ${CMAKE_CURRENT_BINARY_DIR}/Vidalia.app/Contents/Resources/plugins/
+        )
+      endforeach(it)
+    endif(MARBLE_PLUGINS)
+  endif(USE_MARBLE)
 else(APPLE)
   ## Set the output file name
   set(vidalia_BIN vidalia)
-  
+
   if (WIN32)
     ## Create a Windows binary
     win32_wrap_rc(vidalia_SRCS res/vidalia_win.rc)
     add_executable(${vidalia_BIN} WIN32 ${vidalia_SRCS})
+
+    ## Copy the Marble data into the data/ directory under the binary
+    if (USE_MARBLE)
+      foreach(it ${marble_DATA})
+        get_filename_component(outdir  ${it} PATH)
+        get_filename_component(outfile ${it} NAME)
+
+        add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+          COMMAND ${CMAKE_COMMAND}
+            ARGS -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/${outdir}
+          COMMAND ${CMAKE_COMMAND}
+            ARGS -E copy_if_different ${MARBLE_DATA_DIR}/${it} 
+                                      ${CMAKE_CURRENT_BINARY_DIR}/data/${it}
+        )
+      endforeach(it)
+
+      ## Create the Marble plugins directory and copy in any wanted plugins
+      if (MARBLE_PLUGINS)
+        add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+          COMMAND ${CMAKE_COMMAND}
+            ARGS -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/plugins
+        )
+        foreach(it ${MARBLE_PLUGINS})
+          add_custom_command(TARGET ${vidalia_BIN} POST_BUILD
+            COMMAND ${CMAKE_COMMAND}
+              ARGS -E copy_if_different ${it} 
+                    ${CMAKE_CURRENT_BINARY_DIR}/plugins/
+          )
+        endforeach(it)
+      endif(MARBLE_PLUGINS)
+    endif(USE_MARBLE)
+
   else (WIN32)
     ## Non-Windows, non-Mac
     add_executable(${vidalia_BIN} ${vidalia_SRCS})
@@ -290,12 +426,16 @@
 ## Link to the Qt libraries and other libraries built as a part of Vidalia
 target_link_libraries(${vidalia_BIN}
   ${QT_LIBRARIES}
+  ${MARBLE_LIBRARIES}
   common
   torcontrol
 )
 if (USE_MINIUPNPC)
   target_link_libraries(${vidalia_BIN} miniupnpc)
 endif(USE_MINIUPNPC)
+if (USE_MARBLE)
+  target_link_libraries(${vidalia_BIN} ${MARBLE_LIBRARIES})
+endif(USE_MARBLE)
 
 if (WIN32)
   target_link_libraries(${vidalia_BIN}
@@ -314,10 +454,17 @@
 install(TARGETS ${vidalia_BIN} DESTINATION bin)
 if(NOT WIN32 AND NOT APPLE)
   install(FILES vidalia.desktop DESTINATION share/applications)
-  install(FILES res/48x48/vidalia.png
+  install(FILES res/16x16/tor-logo.png RENAME vidalia.png
+          DESTINATION share/icons/hicolor/16x16/apps)
+  install(FILES res/22x22/tor-logo.png RENAME vidalia.png
+          DESTINATION share/icons/hicolor/22x22/apps)
+  install(FILES res/32x32/tor-logo.png RENAME vidalia.png
+          DESTINATION share/icons/hicolor/32x32/apps)
+  install(FILES res/48x48/tor-logo.png RENAME vidalia.png
           DESTINATION share/icons/hicolor/48x48/apps)
-  install(FILES res/22x22/vidalia.png
-          DESTINATION share/icons/hicolor/22x22/apps)
+  install(FILES res/64x64/tor-logo.png RENAME vidalia.png
+          DESTINATION share/icons/hicolor/64x64/apps)
+  install(FILES res/128x128/tor-logo.png RENAME vidalia.png
+          DESTINATION share/icons/hicolor/128x128/apps)
 endif(NOT WIN32 AND NOT APPLE)
 
-

Modified: vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -16,6 +16,7 @@
 
 #include <QFile>
 #include <QDialog>
+#include <QPushButton>
 #include <vidalia.h>
 
 #include "aboutdialog.h"
@@ -24,40 +25,27 @@
 
 /** Default Constructor. */
 AboutDialog::AboutDialog(QWidget *parent, Qt::WindowFlags flags)
-: QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint)
+  : QDialog(parent, Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint)
 {
   ui.setupUi(this);
 
+  /* Add a "License" button to the button box at the bottom */
+  QPushButton *licenseButton;
+  licenseButton = ui.buttonBox->addButton(tr("License"),
+                                          QDialogButtonBox::ActionRole);
+  
   /* Get Vidalia's version number */
-  ui.lblVidaliaVersion->setText(Vidalia::version());
+  ui.lblVidaliaVersion->setText(QString("Vidalia %1").arg(Vidalia::version()));
 
   /* Get Qt's version number */
-  ui.lblQtVersion->setText(QT_VERSION_STR);
+  ui.lblQtVersion->setText(QString("Qt %1").arg(QT_VERSION_STR));
 
   /* Display the license information dialog when the "License" button 
    * is clicked. */
-  connect(ui.btnShowLicense, SIGNAL(clicked()),
+  connect(licenseButton, SIGNAL(clicked()),
           new LicenseDialog(this), SLOT(exec()));
-}
 
-/** Displays the About dialog window **/
-void
-AboutDialog::setVisible(bool visible)
-{
-  if (visible) {
-    /* Access the TorControl object to retrieve version */
-    TorControl *tc = Vidalia::torControl();
-    if (tc->isRunning()) {
-      QString version = tc->getTorVersionString();
-      if (version.isEmpty()) {
-        version = tr("Unavailable");
-      }
-      ui.lblTorVersion->setText(version);
-    } else {
-      ui.lblTorVersion->setText(tr("Not Running"));
-    }
-  }
-  adjustSize();
-  QDialog::setVisible(visible);
+  /* Close this dialog when the "Close" button is clicked */
+  connect(ui.buttonBox, SIGNAL(rejected()), this, SLOT(reject()));
 }
 

Modified: vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -29,8 +29,6 @@
   /** Default constructor */
   AboutDialog(QWidget *parent = 0, Qt::WindowFlags flags = 0);
 
-  virtual void setVisible(bool visible);
-
 private:
   Ui::AboutDialog ui; /**< Qt Designer generated QObject **/
 };

Modified: vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.ui
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.ui	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/about/aboutdialog.ui	2009-02-02 17:47:07 UTC (rev 3503)
@@ -8,8 +8,8 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>408</width>
-    <height>156</height>
+    <width>192</width>
+    <height>220</height>
    </rect>
   </property>
   <property name="sizePolicy" >
@@ -30,8 +30,8 @@
   <property name="modal" >
    <bool>false</bool>
   </property>
-  <layout class="QGridLayout" name="gridLayout_2" >
-   <item row="0" column="0" >
+  <layout class="QVBoxLayout" name="verticalLayout" >
+   <item>
     <widget class="QLabel" name="lblVidaliaLogo" >
      <property name="minimumSize" >
       <size>
@@ -43,134 +43,52 @@
       <string/>
      </property>
      <property name="pixmap" >
-      <pixmap resource="../res/vidalia.qrc" >:/images/128x128/vidalia-logo.png</pixmap>
+      <pixmap resource="../res/vidalia.qrc" >:/images/128x128/tor-logo.png</pixmap>
      </property>
      <property name="alignment" >
       <set>Qt::AlignCenter</set>
      </property>
     </widget>
    </item>
-   <item row="0" column="1" >
-    <layout class="QGridLayout" name="gridLayout" >
-     <item row="1" column="0" >
-      <widget class="QLabel" name="lblVidalia" >
-       <property name="font" >
-        <font>
-         <weight>75</weight>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text" >
-        <string>Vidalia</string>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-      </widget>
-     </item>
-     <item row="1" column="1" >
-      <widget class="QLabel" name="lblVidaliaVersion" >
-       <property name="font" >
-        <font>
-         <weight>75</weight>
-         <italic>false</italic>
-         <bold>true</bold>
-        </font>
-       </property>
-       <property name="text" >
-        <string>0.2.0</string>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="0" >
-      <widget class="QLabel" name="lblTor" >
-       <property name="text" >
-        <string>Tor</string>
-       </property>
-       <property name="textFormat" >
-        <enum>Qt::PlainText</enum>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-      </widget>
-     </item>
-     <item row="2" column="1" >
-      <widget class="QLabel" name="lblTorVersion" >
-       <property name="font" >
-        <font>
-         <italic>false</italic>
-        </font>
-       </property>
-       <property name="text" >
-        <string>0.2.0.31-alpha-dev (r123456)</string>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="0" >
-      <widget class="QLabel" name="lblQt" >
-       <property name="text" >
-        <string>Qt</string>
-       </property>
-       <property name="textFormat" >
-        <enum>Qt::PlainText</enum>
-       </property>
-       <property name="alignment" >
-        <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
-       </property>
-      </widget>
-     </item>
-     <item row="3" column="1" >
-      <widget class="QLabel" name="lblQtVersion" >
-       <property name="font" >
-        <font>
-         <italic>false</italic>
-        </font>
-       </property>
-       <property name="text" >
-        <string>4.4.2</string>
-       </property>
-      </widget>
-     </item>
-     <item row="4" column="0" colspan="2" >
-      <layout class="QHBoxLayout" name="horizontalLayout" >
-       <item>
-        <widget class="QPushButton" name="btnShowLicense" >
-         <property name="text" >
-          <string>License</string>
-         </property>
-        </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>
-     <item row="0" column="0" >
-      <spacer name="verticalSpacer" >
-       <property name="orientation" >
-        <enum>Qt::Vertical</enum>
-       </property>
-       <property name="sizeHint" stdset="0" >
-        <size>
-         <width>20</width>
-         <height>5</height>
-        </size>
-       </property>
-      </spacer>
-     </item>
-    </layout>
+   <item>
+    <widget class="QLabel" name="lblVidaliaVersion" >
+     <property name="font" >
+      <font>
+       <weight>75</weight>
+       <italic>false</italic>
+       <bold>true</bold>
+      </font>
+     </property>
+     <property name="text" >
+      <string>Vidalia 0.2.0</string>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
    </item>
+   <item>
+    <widget class="QLabel" name="lblQtVersion" >
+     <property name="font" >
+      <font>
+       <italic>false</italic>
+      </font>
+     </property>
+     <property name="text" >
+      <string>Qt 4.4.2</string>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
   </layout>
  </widget>
  <resources>

Copied: vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.cpp (from rev 3502, vidalia/trunk/src/vidalia/config/bridgeusagedialog.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,81 @@
+/*
+**  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 bridgeusagedialog.cpp
+** \version $Id$
+** \brief Displays a summary of bridge usage information, including client
+** geographic location history.
+*/
+
+#include <QHeaderView>
+#include <QTreeWidgetItem>
+#include <QPixmap>
+#include <countryinfo.h>
+
+#include "bridgeusagedialog.h"
+
+
+BridgeUsageDialog::BridgeUsageDialog(QWidget *parent)
+  : QDialog(parent)
+{
+  ui.setupUi(this);
+  ui.treeClientSummary->setHeaderLabels(QStringList() << QString("")
+                                                      << tr("Country")
+                                                      << tr("# Clients"));
+}
+
+void
+BridgeUsageDialog::showEvent(QShowEvent *e)
+{
+  QHeaderView *header = ui.treeClientSummary->header();
+  header->setResizeMode(0, QHeaderView::ResizeToContents);
+  header->resizeSection(1, 220);
+  header->setResizeMode(2, QHeaderView::ResizeToContents);
+
+  QDialog::showEvent(e);
+}
+
+void
+BridgeUsageDialog::update(const QDateTime &timeStarted,
+                          const QHash<QString,int> &countrySummary)
+{
+  QTreeWidgetItem *item;
+  int minClients, maxClients;
+  QString countryName;
+  QPixmap flag;
+
+  /* Set the header with the TimeStarted value converted to local time */
+  ui.lblClientSummary->setText(tr("Clients from the following countries have "
+                                  "used your relay since %1")
+                                  .arg(timeStarted.toLocalTime().toString()));
+
+  /* Populate the table of client country statistics */
+  foreach (QString countryCode, countrySummary.keys()) {
+    maxClients = countrySummary.value(countryCode);
+    minClients = maxClients-7;
+
+    flag = QPixmap(":/images/flags/" + countryCode.toLower() + ".png");
+    if (flag.isNull())
+      flag = QPixmap(":/images/flags/unknown.png");
+
+    countryName = CountryInfo::countryName(countryCode);
+    if (countryName.isEmpty())
+      countryName = countryCode;
+
+    item = new QTreeWidgetItem();
+    item->setIcon(0, QIcon(flag));
+    item->setText(1, countryName);
+    item->setText(2, QString("%1-%2").arg(minClients).arg(maxClients));
+    ui.treeClientSummary->addTopLevelItem(item);
+  }
+  ui.treeClientSummary->sortItems(2, Qt::DescendingOrder);
+}
+

Copied: vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.h (from rev 3502, vidalia/trunk/src/vidalia/config/bridgeusagedialog.h)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,53 @@
+/*
+**  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 bridgeusagedialog.h
+** \version $Id$
+** \brief Displays a summary of bridge usage information, including client
+** geographic location history.
+*/
+
+#ifndef _BRIDGEUSAGEDIALOG_H
+#define _BRIDGEUSAGEDIALOG_H
+
+#include <QDialog>
+#include <QDateTime>
+#include <QHash>
+
+#include "ui_bridgeusagedialog.h"
+
+
+class BridgeUsageDialog : public QDialog
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor.
+   */
+  BridgeUsageDialog(QWidget *parent = 0);
+
+  /** Updates the dialog with current bridge usage information.
+   */
+  void update(const QDateTime &timeStarted,
+              const QHash<QString,int> &countrySummary);
+
+protected:
+  /** Called when the dialog is displayed. Adjusts the size of the column
+   * headers.
+   */
+  void showEvent(QShowEvent *e);
+
+private:
+  Ui::BridgeUsageDialog ui;
+};
+
+#endif
+

Copied: vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.ui (from rev 3502, vidalia/trunk/src/vidalia/config/bridgeusagedialog.ui)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.ui	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/config/bridgeusagedialog.ui	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,110 @@
+<ui version="4.0" >
+ <class>BridgeUsageDialog</class>
+ <widget class="QDialog" name="BridgeUsageDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>444</width>
+    <height>408</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Bridge Usage Summary</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout_2" >
+   <item>
+    <widget class="QGroupBox" name="groupBox" >
+     <property name="title" >
+      <string>Client Summary</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout" >
+      <item>
+       <widget class="QLabel" name="lblClientSummary" >
+        <property name="text" >
+         <string></string>
+        </property>
+        <property name="alignment" >
+         <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+        </property>
+        <property name="wordWrap" >
+         <bool>true</bool>
+        </property>
+       </widget>
+      </item>
+      <item>
+       <widget class="QTreeWidget" name="treeClientSummary" >
+        <property name="alternatingRowColors" >
+         <bool>false</bool>
+        </property>
+        <property name="sortingEnabled" >
+         <bool>true</bool>
+        </property>
+        <column>
+         <property name="text" >
+          <string></string>
+         </property>
+        </column>
+        <column>
+         <property name="text" >
+          <string>Country</string>
+         </property>
+        </column>
+        <column>
+         <property name="text" >
+          <string># Clients</string>
+         </property>
+        </column>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>BridgeUsageDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>BridgeUsageDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Modified: vidalia/branches/alt-launcher/src/vidalia/config/serverpage.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/serverpage.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/serverpage.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -15,10 +15,12 @@
 */
 
 #include <QClipboard>
+#include <QMessageBox>
 #include <vidalia.h>
 #include <vmessagebox.h>
 #include <html.h>
 #include <config.h>
+#include <stringutil.h>
 
 #include "configdialog.h"
 #include "serverpage.h"
@@ -26,6 +28,7 @@
 #include "portvalidator.h"
 #include "domainvalidator.h"
 #include "nicknamevalidator.h"
+#include "bridgeusagedialog.h"
 
 #if defined(USE_MINIUPNPC)
 #include "upnptestdialog.h"
@@ -95,6 +98,8 @@
                            this, SLOT(onDisconnected()));
   connect(ui.btnCopyBridgeIdentity, SIGNAL(clicked()),
                               this, SLOT(copyBridgeIdentity()));
+  connect(ui.lblBridgeUsage, SIGNAL(linkActivated(QString)),
+                       this, SLOT(linkActivated(QString)));
 
   /* Set validators for address, mask and various port number fields */
   ui.lineServerNickname->setValidator(new NicknameValidator(this));
@@ -200,6 +205,7 @@
   ui.lblYourBridgeRelayIs->setEnabled(!bridge.isEmpty());
   ui.lblBridgeIdentity->setEnabled(!bridge.isEmpty());
   ui.btnCopyBridgeIdentity->setEnabled(!bridge.isEmpty());
+  ui.lblBridgeUsage->setVisible(!bridge.isEmpty() && tc->isConnected());
 }
 
 /** Called when the user toggles any one of the server mode radio buttons
@@ -310,7 +316,7 @@
   ui.lineDirPort->setText(QString::number(_settings->getDirPort()));
   ui.lineServerContact->setText(_settings->getContactInfo());
   ui.chkMirrorDirectory->setChecked(_settings->isDirectoryMirror());
-  
+
   loadBandwidthLimits();
   loadExitPolicies();
   loadBridgeIdentity();
@@ -529,3 +535,69 @@
   emit helpRequested("server.upnp");
 }
 
+/** Called when the user clicks on a QLabel containing a hyperlink. */
+void
+ServerPage::linkActivated(const QString &url)
+{
+  if (!url.compare("#bridgeUsage"))
+    displayBridgeUsage();
+}
+
+/** Retrieves bridge usage history from Tor, parses and validates it, and
+ * then displays it in a new dialog. */
+void
+ServerPage::displayBridgeUsage()
+{
+  QString info;
+
+  info = Vidalia::torControl()->getInfo("status/clients-seen").toString();
+  if (info.isEmpty()) {
+    QMessageBox dlg(QMessageBox::Information, tr("No Recent Usage"),
+                    tr("No clients have used your relay recently."), 
+                    QMessageBox::Ok, this);
+    dlg.setInformativeText(tr("Leave your relay running so clients have "
+                              "a better chance of finding and using it."));
+    dlg.exec();
+  } else {
+    QDateTime timeStarted;
+    QHash<QString,int> countrySummary;
+    QHash<QString,QString> keyvals;
+    BridgeUsageDialog dlg(this);
+    bool ok;
+
+    keyvals = string_parse_keyvals(info, &ok);
+    if (!ok || !keyvals.contains("TimeStarted") 
+            || !keyvals.contains("CountrySummary"))
+      goto err;
+
+    timeStarted = QDateTime::fromString(keyvals.value("TimeStarted"), 
+                                        "yyyy-MM-dd HH:mm:ss");
+    if (!timeStarted.isValid())
+      goto err;
+
+    foreach (QString pair, keyvals.value("CountrySummary").split(",")) {
+      QStringList parts = pair.split("=");
+      if (parts.size() != 2)
+        goto err;
+
+      countrySummary.insert(parts.at(0).toUpper(), parts.at(1).toInt(&ok));
+      if (!ok)
+        goto err;
+    }
+
+    dlg.update(timeStarted, countrySummary);
+    dlg.exec();
+  }
+  return;
+
+err:
+  QMessageBox dlg(QMessageBox::Warning, tr("Bridge History"),
+                  tr("Vidalia was unable to retrieve your bridge's usage "
+                     "history."), QMessageBox::Ok, this);
+  dlg.setInformativeText(tr("Tor returned an improperly formatted "
+                            "response when Vidalia requested your "
+                            "bridge's usage history."));
+  dlg.setDetailedText(tr("The returned response was: %1").arg(info));
+  dlg.exec();
+}
+

Modified: vidalia/branches/alt-launcher/src/vidalia/config/serverpage.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/serverpage.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/serverpage.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -80,6 +80,8 @@
   void testUpnp();
   /** Called when the user clicks the UPnP test dialog's help button. */
   void upnpHelp();
+  /** Called when the user clicks on a QLabel containing a hyperlink. */
+  void linkActivated(const QString &url);
 
 private:
   /** Index values of rate values in the bandwidth limits dropdown box. */
@@ -109,6 +111,9 @@
    *  or "address:port fingerprint" will be displayed, depending on whether
    *  our GETCONF and GETINFO commands are successful. */
   void loadBridgeIdentity();
+  /** Retrieves bridge usage history from Tor, parses and validates it, and
+   * then displays it in a new dialog. */
+  void displayBridgeUsage();
 
   /** A ServerSettings object used to get and set information about how a
    * local Tor server is configured. */

Modified: vidalia/branches/alt-launcher/src/vidalia/config/serverpage.ui
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/serverpage.ui	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/serverpage.ui	2009-02-02 17:47:07 UTC (rev 3503)
@@ -5,20 +5,14 @@
    <rect>
     <x>0</x>
     <y>0</y>
-    <width>489</width>
-    <height>351</height>
+    <width>542</width>
+    <height>463</height>
    </rect>
   </property>
   <property name="contextMenuPolicy" >
    <enum>Qt::NoContextMenu</enum>
   </property>
   <layout class="QVBoxLayout" >
-   <property name="margin" >
-    <number>9</number>
-   </property>
-   <property name="spacing" >
-    <number>6</number>
-   </property>
    <item>
     <widget class="QRadioButton" name="rdoClientMode" >
      <property name="text" >
@@ -55,15 +49,10 @@
       <property name="margin" >
        <number>0</number>
       </property>
-      <property name="spacing" >
-       <number>6</number>
-      </property>
       <item>
        <widget class="QTabWidget" name="tabsMenu" >
         <property name="sizePolicy" >
-         <sizepolicy>
-          <hsizetype>7</hsizetype>
-          <vsizetype>7</vsizetype>
+         <sizepolicy vsizetype="Expanding" hsizetype="Expanding" >
           <horstretch>0</horstretch>
           <verstretch>0</verstretch>
          </sizepolicy>
@@ -76,12 +65,6 @@
           <string>Basic Settings</string>
          </attribute>
          <layout class="QGridLayout" >
-          <property name="margin" >
-           <number>9</number>
-          </property>
-          <property name="spacing" >
-           <number>6</number>
-          </property>
           <item row="2" column="0" >
            <widget class="QLabel" name="lblServerPort" >
             <property name="contextMenuPolicy" >
@@ -119,7 +102,7 @@
             <property name="orientation" >
              <enum>Qt::Horizontal</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>40</width>
               <height>20</height>
@@ -133,7 +116,7 @@
              <enum>Qt::NoContextMenu</enum>
             </property>
             <property name="toolTip" >
-             <string></string>
+             <string/>
             </property>
             <property name="text" >
              <string>Attempt to automatically configure port forwarding</string>
@@ -142,9 +125,6 @@
           </item>
           <item row="4" column="6" >
            <layout class="QHBoxLayout" >
-            <property name="margin" >
-             <number>0</number>
-            </property>
             <item>
              <widget class="QPushButton" name="btnTestUpnp" >
               <property name="contextMenuPolicy" >
@@ -167,7 +147,8 @@
                <string/>
               </property>
               <property name="icon" >
-               <iconset resource="../res/vidalia.qrc">:/images/22x22/system-help.png</iconset>
+               <iconset resource="../res/vidalia.qrc" >
+                <normaloff>:/images/22x22/system-help.png</normaloff>:/images/22x22/system-help.png</iconset>
               </property>
               <property name="iconSize" >
                <size>
@@ -176,13 +157,13 @@
                </size>
               </property>
              </widget>
-            </item> 
+            </item>
             <item>
              <spacer>
               <property name="orientation" >
                <enum>Qt::Horizontal</enum>
               </property>
-              <property name="sizeHint" >
+              <property name="sizeHint" stdset="0" >
                <size>
                 <width>40</width>
                 <height>20</height>
@@ -195,7 +176,7 @@
           <item row="1" column="1" colspan="7" >
            <widget class="QLineEdit" name="lineServerContact" >
             <property name="cursor" >
-             <cursor>4</cursor>
+             <cursorShape>IBeamCursor</cursorShape>
             </property>
             <property name="contextMenuPolicy" >
              <enum>Qt::NoContextMenu</enum>
@@ -208,21 +189,13 @@
           </item>
           <item row="3" column="3" colspan="3" >
            <layout class="QHBoxLayout" >
-            <property name="margin" >
-             <number>0</number>
-            </property>
-            <property name="spacing" >
-             <number>6</number>
-            </property>
             <item>
              <widget class="QLabel" name="lblDirPort" >
               <property name="enabled" >
                <bool>false</bool>
               </property>
               <property name="sizePolicy" >
-               <sizepolicy>
-                <hsizetype>0</hsizetype>
-                <vsizetype>0</vsizetype>
+               <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
                 <horstretch>0</horstretch>
                 <verstretch>0</verstretch>
                </sizepolicy>
@@ -244,9 +217,7 @@
                <bool>false</bool>
               </property>
               <property name="sizePolicy" >
-               <sizepolicy>
-                <hsizetype>0</hsizetype>
-                <vsizetype>0</vsizetype>
+               <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
                 <horstretch>0</horstretch>
                 <verstretch>0</verstretch>
                </sizepolicy>
@@ -258,7 +229,7 @@
                </size>
               </property>
               <property name="cursor" >
-               <cursor>4</cursor>
+               <cursorShape>IBeamCursor</cursorShape>
               </property>
               <property name="contextMenuPolicy" >
                <enum>Qt::NoContextMenu</enum>
@@ -291,7 +262,7 @@
             <property name="orientation" >
              <enum>Qt::Horizontal</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>321</width>
               <height>20</height>
@@ -304,7 +275,7 @@
             <property name="orientation" >
              <enum>Qt::Vertical</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>20</width>
               <height>40</height>
@@ -317,7 +288,7 @@
             <property name="orientation" >
              <enum>Qt::Horizontal</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>41</width>
               <height>20</height>
@@ -328,7 +299,7 @@
           <item row="0" column="1" colspan="7" >
            <widget class="QLineEdit" name="lineServerNickname" >
             <property name="cursor" >
-             <cursor>4</cursor>
+             <cursorShape>IBeamCursor</cursorShape>
             </property>
             <property name="contextMenuPolicy" >
              <enum>Qt::NoContextMenu</enum>
@@ -347,9 +318,7 @@
           <item row="2" column="1" >
            <widget class="QLineEdit" name="lineServerPort" >
             <property name="sizePolicy" >
-             <sizepolicy>
-              <hsizetype>0</hsizetype>
-              <vsizetype>0</vsizetype>
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
@@ -361,7 +330,7 @@
              </size>
             </property>
             <property name="cursor" >
-             <cursor>4</cursor>
+             <cursorShape>IBeamCursor</cursorShape>
             </property>
             <property name="contextMenuPolicy" >
              <enum>Qt::NoContextMenu</enum>
@@ -400,18 +369,10 @@
           <string>Bandwidth Limits</string>
          </attribute>
          <layout class="QVBoxLayout" >
-          <property name="margin" >
-           <number>9</number>
-          </property>
-          <property name="spacing" >
-           <number>6</number>
-          </property>
           <item>
            <widget class="QLabel" name="label" >
             <property name="sizePolicy" >
-             <sizepolicy>
-              <hsizetype>5</hsizetype>
-              <vsizetype>5</vsizetype>
+             <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
@@ -441,12 +402,6 @@
           </item>
           <item>
            <layout class="QHBoxLayout" >
-            <property name="margin" >
-             <number>0</number>
-            </property>
-            <property name="spacing" >
-             <number>6</number>
-            </property>
             <item>
              <widget class="QComboBox" name="cmboRate" >
               <property name="contextMenuPolicy" >
@@ -505,7 +460,8 @@
                <string/>
               </property>
               <property name="icon" >
-               <iconset resource="../res/vidalia.qrc">:/images/22x22/system-help.png</iconset>
+               <iconset resource="../res/vidalia.qrc" >
+                <normaloff>:/images/22x22/system-help.png</normaloff>:/images/22x22/system-help.png</iconset>
               </property>
               <property name="iconSize" >
                <size>
@@ -520,7 +476,7 @@
               <property name="orientation" >
                <enum>Qt::Horizontal</enum>
               </property>
-              <property name="sizeHint" >
+              <property name="sizeHint" stdset="0" >
                <size>
                 <width>40</width>
                 <height>20</height>
@@ -542,18 +498,12 @@
              <enum>QFrame::Plain</enum>
             </property>
             <layout class="QGridLayout" >
-             <property name="margin" >
-              <number>9</number>
-             </property>
-             <property name="spacing" >
-              <number>6</number>
-             </property>
              <item row="4" column="0" >
               <spacer>
                <property name="orientation" >
                 <enum>Qt::Vertical</enum>
                </property>
-               <property name="sizeHint" >
+               <property name="sizeHint" stdset="0" >
                 <size>
                  <width>20</width>
                  <height>40</height>
@@ -563,26 +513,12 @@
              </item>
              <item row="1" column="0" >
               <layout class="QHBoxLayout" >
-               <property name="margin" >
-                <number>0</number>
-               </property>
-               <property name="spacing" >
-                <number>6</number>
-               </property>
                <item>
                 <layout class="QVBoxLayout" >
-                 <property name="margin" >
-                  <number>0</number>
-                 </property>
-                 <property name="spacing" >
-                  <number>6</number>
-                 </property>
                  <item>
                   <widget class="QLabel" name="label_2" >
                    <property name="sizePolicy" >
-                    <sizepolicy>
-                     <hsizetype>1</hsizetype>
-                     <vsizetype>5</vsizetype>
+                    <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
                      <horstretch>0</horstretch>
                      <verstretch>0</verstretch>
                     </sizepolicy>
@@ -594,18 +530,10 @@
                  </item>
                  <item>
                   <layout class="QHBoxLayout" >
-                   <property name="margin" >
-                    <number>0</number>
-                   </property>
-                   <property name="spacing" >
-                    <number>6</number>
-                   </property>
                    <item>
                     <widget class="QLineEdit" name="lineAvgRateLimit" >
                      <property name="sizePolicy" >
-                      <sizepolicy>
-                       <hsizetype>1</hsizetype>
-                       <vsizetype>0</vsizetype>
+                      <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
                        <horstretch>0</horstretch>
                        <verstretch>0</verstretch>
                       </sizepolicy>
@@ -640,18 +568,10 @@
                </item>
                <item>
                 <layout class="QVBoxLayout" >
-                 <property name="margin" >
-                  <number>0</number>
-                 </property>
-                 <property name="spacing" >
-                  <number>6</number>
-                 </property>
                  <item>
                   <widget class="QLabel" name="label_5" >
                    <property name="sizePolicy" >
-                    <sizepolicy>
-                     <hsizetype>1</hsizetype>
-                     <vsizetype>5</vsizetype>
+                    <sizepolicy vsizetype="Preferred" hsizetype="Minimum" >
                      <horstretch>0</horstretch>
                      <verstretch>0</verstretch>
                     </sizepolicy>
@@ -669,18 +589,10 @@
                  </item>
                  <item>
                   <layout class="QHBoxLayout" >
-                   <property name="margin" >
-                    <number>0</number>
-                   </property>
-                   <property name="spacing" >
-                    <number>6</number>
-                   </property>
                    <item>
                     <widget class="QLineEdit" name="lineMaxRateLimit" >
                      <property name="sizePolicy" >
-                      <sizepolicy>
-                       <hsizetype>1</hsizetype>
-                       <vsizetype>0</vsizetype>
+                      <sizepolicy vsizetype="Fixed" hsizetype="Minimum" >
                        <horstretch>0</horstretch>
                        <verstretch>0</verstretch>
                       </sizepolicy>
@@ -717,7 +629,7 @@
                      <property name="sizeType" >
                       <enum>QSizePolicy::Expanding</enum>
                      </property>
-                     <property name="sizeHint" >
+                     <property name="sizeHint" stdset="0" >
                       <size>
                        <width>71</width>
                        <height>20</height>
@@ -749,7 +661,7 @@
             <property name="orientation" >
              <enum>Qt::Vertical</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>20</width>
               <height>40</height>
@@ -764,12 +676,6 @@
           <string>Exit Policies</string>
          </attribute>
          <layout class="QGridLayout" >
-          <property name="margin" >
-           <number>9</number>
-          </property>
-          <property name="spacing" >
-           <number>6</number>
-          </property>
           <item row="1" column="0" >
            <widget class="QFrame" name="frmPolicies" >
             <property name="frameShape" >
@@ -779,20 +685,8 @@
              <enum>QFrame::Plain</enum>
             </property>
             <layout class="QHBoxLayout" >
-             <property name="margin" >
-              <number>9</number>
-             </property>
-             <property name="spacing" >
-              <number>6</number>
-             </property>
              <item>
               <layout class="QGridLayout" >
-               <property name="margin" >
-                <number>0</number>
-               </property>
-               <property name="spacing" >
-                <number>6</number>
-               </property>
                <item row="1" column="1" >
                 <widget class="QCheckBox" name="chkIRC" >
                  <property name="contextMenuPolicy" >
@@ -875,12 +769,6 @@
              </item>
              <item>
               <layout class="QVBoxLayout" >
-               <property name="margin" >
-                <number>0</number>
-               </property>
-               <property name="spacing" >
-                <number>6</number>
-               </property>
                <item>
                 <widget class="QToolButton" name="btnExitHelp" >
                  <property name="minimumSize" >
@@ -899,7 +787,8 @@
                   <string/>
                  </property>
                  <property name="icon" >
-                  <iconset resource="../res/vidalia.qrc">:/images/22x22/system-help.png</iconset>
+                  <iconset resource="../res/vidalia.qrc" >
+                   <normaloff>:/images/22x22/system-help.png</normaloff>:/images/22x22/system-help.png</iconset>
                  </property>
                  <property name="iconSize" >
                   <size>
@@ -914,7 +803,7 @@
                  <property name="orientation" >
                   <enum>Qt::Vertical</enum>
                  </property>
-                 <property name="sizeHint" >
+                 <property name="sizeHint" stdset="0" >
                   <size>
                    <width>20</width>
                    <height>42</height>
@@ -929,7 +818,7 @@
                <property name="orientation" >
                 <enum>Qt::Horizontal</enum>
                </property>
-               <property name="sizeHint" >
+               <property name="sizeHint" stdset="0" >
                 <size>
                  <width>40</width>
                  <height>20</height>
@@ -943,9 +832,7 @@
           <item row="0" column="0" >
            <widget class="QLabel" name="label_3" >
             <property name="sizePolicy" >
-             <sizepolicy>
-              <hsizetype>0</hsizetype>
-              <vsizetype>0</vsizetype>
+             <sizepolicy vsizetype="Fixed" hsizetype="Fixed" >
               <horstretch>0</horstretch>
               <verstretch>0</verstretch>
              </sizepolicy>
@@ -988,7 +875,7 @@
             <property name="orientation" >
              <enum>Qt::Vertical</enum>
             </property>
-            <property name="sizeHint" >
+            <property name="sizeHint" stdset="0" >
              <size>
               <width>20</width>
               <height>40</height>
@@ -1006,7 +893,7 @@
    <item>
     <widget class="QLabel" name="lblYourBridgeRelayIs" >
      <property name="cursor" >
-      <cursor>0</cursor>
+      <cursorShape>ArrowCursor</cursorShape>
      </property>
      <property name="frameShape" >
       <enum>QFrame::NoFrame</enum>
@@ -1018,22 +905,16 @@
       <bool>true</bool>
      </property>
      <property name="textInteractionFlags" >
-      <enum>Qt::TextSelectableByMouse</enum>
+      <set>Qt::TextSelectableByMouse</set>
      </property>
     </widget>
    </item>
    <item>
     <layout class="QHBoxLayout" >
-     <property name="margin" >
-      <number>0</number>
-     </property>
-     <property name="spacing" >
-      <number>6</number>
-     </property>
      <item>
       <widget class="QLabel" name="lblBridgeIdentity" >
        <property name="cursor" >
-        <cursor>4</cursor>
+        <cursorShape>IBeamCursor</cursorShape>
        </property>
        <property name="toolTip" >
         <string>This is the identity of your bridge relay that you can give to other people</string>
@@ -1048,7 +929,7 @@
         <string/>
        </property>
        <property name="textInteractionFlags" >
-        <enum>Qt::TextSelectableByMouse</enum>
+        <set>Qt::TextSelectableByMouse</set>
        </property>
       </widget>
      </item>
@@ -1064,18 +945,29 @@
         <string/>
        </property>
        <property name="icon" >
-        <iconset resource="../res/vidalia.qrc" >:/images/22x22/edit-copy.png</iconset>
+        <iconset resource="../res/vidalia.qrc" >
+         <normaloff>:/images/22x22/edit-copy.png</normaloff>:/images/22x22/edit-copy.png</iconset>
        </property>
       </widget>
      </item>
     </layout>
    </item>
    <item>
+    <widget class="QLabel" name="lblBridgeUsage" >
+     <property name="text" >
+      <string>&lt;a href="#bridgeUsage">Who has used my bridge?&lt;/a></string>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
+     </property>
+    </widget>
+   </item>
+   <item>
     <spacer>
      <property name="orientation" >
       <enum>Qt::Vertical</enum>
      </property>
-     <property name="sizeHint" >
+     <property name="sizeHint" stdset="0" >
       <size>
        <width>420</width>
        <height>16</height>

Modified: vidalia/branches/alt-launcher/src/vidalia/config/servicepage.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/servicepage.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/servicepage.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -28,13 +28,6 @@
 {
   /* Invoke the Qt Designer generated object setup routine */
   ui.setupUi(this);
-  /* Keep a pointer to the TorControl object used to talk to Tor */
-  _torControl = Vidalia::torControl();
-  /* Create Tor settings objects */
-  _torSettings = new TorSettings;
-  /* Keep a pointer to the ServiceSettings object used to store
-   * the configuration */
-  _serviceSettings = new ServiceSettings(_torControl);
   /* A QMap, mapping from the row number to the Entity for
    * all services */
   _services = new QMap<int, Service>();
@@ -66,7 +59,8 @@
 /** Destructor */
 ServicePage::~ServicePage()
 {
-  delete _serviceSettings;
+  delete _services;
+  delete _torServices;
 }
 
 /** Called when the user changes the UI translation. */
@@ -80,9 +74,11 @@
 bool
 ServicePage::save(QString &errmsg)
 {
+  ServiceSettings serviceSettings(Vidalia::torControl());
   QList<Service> serviceList;
   QList<Service> publishedServices;
   int index = 0;
+
   while(index < ui.serviceWidget->rowCount()) {
     QString address = ui.serviceWidget->item(index,0)->text();
     QString virtualPort = ui.serviceWidget->item(index,1)->text();
@@ -109,13 +105,13 @@
       _services = new QMap<int, Service>();
       sList.setServices(_services->values());
     }
-    _serviceSettings->setServices(sList);
+    serviceSettings.setServices(sList);
     if(publishedServices.size() > 0) {
       startServicesInTor(publishedServices);
     } else {
       QString errmsg1 = tr("Error while trying to unpublish all services");
       QString &errmsg = errmsg1;
-      _serviceSettings->unpublishAllServices(&errmsg);
+      serviceSettings.unpublishAllServices(&errmsg);
     }
     return true;
   } else {
@@ -144,6 +140,7 @@
 void
 ServicePage::startServicesInTor(QList<Service> services)
 {
+  ServiceSettings serviceSettings(Vidalia::torControl());
   QString serviceConfString;
   QString errmsg = "Error while trying to publish services.";
   QListIterator<Service> it(services);
@@ -158,26 +155,28 @@
       temp.physicalAddressPort())));
     serviceConfString.append(" " + temp.additionalServiceOptions());
   }
-  _serviceSettings->applyServices(serviceConfString, &errmsg);
+  serviceSettings.applyServices(serviceConfString, &errmsg);
 }
 
 /** Loads previously saved settings */
 void
 ServicePage::load()
 {
+  ServiceSettings serviceSettings(Vidalia::torControl());
+  QList<Service> torServiceList;
+
   ui.removeButton->setEnabled(false);
   ui.copyButton->setEnabled(false);
   ui.browseButton->setEnabled(false);
   // get all services
-  _services = new QMap<int, Service>();
-  _torServices = new QMap<QString, Service>();
-  QList<Service> torServiceList;
+  _services->clear();
+  _torServices->clear();
 
-  QString torConfigurationString = _serviceSettings->getHiddenServiceDirectories();
+  QString torConfigurationString = serviceSettings.getHiddenServiceDirectories();
   torServiceList = extractSingleServices(torConfigurationString);
   QList<Service> completeList = torServiceList;
   // the services stored with vidalia
-  ServiceList serviceList = _serviceSettings->getServices();
+  ServiceList serviceList = serviceSettings.getServices();
   QList<Service> serviceSettingsList = serviceList.services();
   QListIterator<Service> it(serviceSettingsList);
   // check whether a service is already in the list because he is published
@@ -313,7 +312,7 @@
 /** this method creates/displays the values for each service
  *  shown in the service listing */
 void
-ServicePage::initServiceTable(QMap<int, Service>* _services)
+ServicePage::initServiceTable(QMap<int, Service>* services)
 {
   // clean the widget
   int rows = ui.serviceWidget->rowCount();
@@ -322,8 +321,8 @@
   }
   //for each service
   int index = 0;
-  while(index < _services->size()) {
-    Service tempService = _services->value(index);
+  while(index < services->size()) {
+    Service tempService = services->value(index);
     ui.serviceWidget->insertRow(index);
     QTableWidgetItem *cboxitem = new QTableWidgetItem();
     cboxitem->setFlags(Qt::ItemIsSelectable);

Modified: vidalia/branches/alt-launcher/src/vidalia/config/servicepage.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/servicepage.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/servicepage.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -65,16 +65,11 @@
   void valueChanged();
 
 private:
-  /** A TorControl object used to talk to Tor. */
-  TorControl* _torControl;
-  /** A TorSettings object used for saving/loading the Tor settings */
-  TorSettings *_torSettings;
-  /** A ServiceSettings object used to load/save the services. */
-  ServiceSettings* _serviceSettings;
   /** A QMap, mapping from the row number in the table to the service Entity */
   QMap<int, Service>* _services;
   /** A QList, consisting of all running services before vidalia starts */
   QMap<QString, Service>* _torServices;
+
   /** Qt Designer generated object */
   Ui::ServicePage ui;
 };

Modified: vidalia/branches/alt-launcher/src/vidalia/config/torsettings.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/torsettings.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/torsettings.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -38,6 +38,8 @@
 #define SETTING_AUTH_METHOD         "AuthenticationMethod"
 #define SETTING_CONTROL_PASSWORD    "ControlPassword"
 #define SETTING_USE_RANDOM_PASSWORD "UseRandomPassword"
+#define SETTING_WARN_PLAINTEXT_PORTS    "WarnPlaintextPorts"
+#define SETTING_REJECT_PLAINTEXT_PORTS  "RejectPlaintextPorts"
 
 /** Default to using hashed password authentication */
 #define DEFAULT_AUTH_METHOD     PasswordAuth
@@ -75,6 +77,9 @@
   setDefault(SETTING_DATA_DIRECTORY, "");
   setDefault(SETTING_CONTROL_PASSWORD, "");
   setDefault(SETTING_USE_RANDOM_PASSWORD, true);
+  setDefault(SETTING_WARN_PLAINTEXT_PORTS, QList<QVariant>() << 23 << 109 
+                                                             << 110 << 143);
+  setDefault(SETTING_REJECT_PLAINTEXT_PORTS, QList<QVariant>());
 }
 
 /** Applies any changes to Tor's control port or authentication settings. */
@@ -256,6 +261,60 @@
   setValue(SETTING_AUTH_METHOD, toString(method));
 }
 
+/** Returns the current list of ports that will cause Tor to issue a warning
+ * when the user tries to connect to one of them. */
+QList<quint16>
+TorSettings::getWarnPlaintextPorts() const
+{
+  QList<quint16> out;
+  QList<QVariant> ports;
+
+  ports = value(SETTING_WARN_PLAINTEXT_PORTS).toList();
+  foreach (QVariant port, ports) {
+    out << port.toUInt();
+  }
+  return out;
+}
+
+/** Sets the list of ports that will cause Tor to issue a warning when the
+ * user tries to connect to one of them. */
+void
+TorSettings::setWarnPlaintextPorts(const QList<quint16> &ports)
+{
+  QList<QVariant> warnList;
+  foreach (quint16 port, ports) {
+    warnList << QVariant(port);
+  }
+  setValue(SETTING_WARN_PLAINTEXT_PORTS, warnList);
+}
+
+/** Returns the current list of ports that will cause Tor to reject the
+ * connection when the user tries to connect to one of them. */
+QList<quint16>
+TorSettings::getRejectPlaintextPorts() const
+{
+  QList<quint16> out;
+  QList<QVariant> ports;
+
+  ports = value(SETTING_REJECT_PLAINTEXT_PORTS).toList();
+  foreach (QVariant port, ports) {
+    out << port.toUInt();
+  }
+  return out;
+}
+
+/** Sets the list of ports that will cause Tor to reject the connection
+ * when the user tries to connect to one of them. */
+void
+TorSettings::setRejectPlaintextPorts(const QList<quint16> &ports)
+{
+  QList<QVariant> rejectList;
+  foreach (quint16 port, ports) {
+    rejectList << QVariant(port);
+  }
+  setValue(SETTING_REJECT_PLAINTEXT_PORTS, rejectList);
+}
+
 /** Returns the string description of the authentication method specified by
  * <b>method</b>. The authentication method string is stored in Vidalia's
  * configuration file. */

Modified: vidalia/branches/alt-launcher/src/vidalia/config/torsettings.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/config/torsettings.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/config/torsettings.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -86,6 +86,20 @@
   /** Sets the authentication method used when starting Tor to <b>method</b>.*/
   void setAuthenticationMethod(AuthenticationMethod method);
 
+  /** Returns the current list of ports that will cause Tor to issue a warning
+   * when the user tries to connect to one of them. */
+  QList<quint16> getWarnPlaintextPorts() const;
+  /** Sets the list of ports that will cause Tor to issue a warning when the
+   * user tries to connect to one of them. */
+  void setWarnPlaintextPorts(const QList<quint16> &ports);
+
+  /** Returns the current list of ports that will cause Tor to reject the
+   * connection when the user tries to connect to one of them. */
+  QList<quint16> getRejectPlaintextPorts() const;
+  /** Sets the list of ports that will cause Tor to reject the connection
+   * when the user tries to connect to one of them. */
+  void setRejectPlaintextPorts(const QList<quint16> &ports);
+
   /** Generates a random control password consisting of PASSWORD_LEN
    * characters. */
   static QString randomPassword();

Modified: vidalia/branches/alt-launcher/src/vidalia/controlpasswordinputdialog.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/controlpasswordinputdialog.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/controlpasswordinputdialog.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -50,7 +50,6 @@
   } else {
     ui.buttonBox->setStandardButtons(ui.buttonBox->standardButtons()
                                       & ~QDialogButtonBox::Reset);
-    
   }
 }
 

Modified: vidalia/branches/alt-launcher/src/vidalia/helperprocess.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/helperprocess.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/helperprocess.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -39,7 +39,10 @@
 */
 
 #include <QString>
-  
+#include <QFileInfo>
+#include <stringutil.h>
+#include <vidalia.h>
+
 #include "helperprocess.h"
 
 
@@ -50,12 +53,46 @@
   // Call error handling routine on errors
   QObject::connect(this, SIGNAL(error(QProcess::ProcessError)),
                    this, SLOT(onError(QProcess::ProcessError)));
+
+  // Call output handling routines on process output
+  QObject::connect(this, SIGNAL(readyReadStandardError()),
+                   this, SLOT(onReadyReadStandardError()));
+  QObject::connect(this, SIGNAL(readyReadStandardOutput()),
+                   this, SLOT(onReadyReadStandardOutput()));
 }
 
+/** Invoked when output is written to the process's stderr. */
+void
+HelperProcess::onReadyReadStandardError()
+{
+  QString output = QString(readAllStandardError());
+  foreach (QString line, output.split("\n")) {
+    vInfo("(%1:stderr): %2").arg(_processName).arg(line);
+  }
+}
+
+/** Invoked when output is written to the process's stdout. */
+void
+HelperProcess::onReadyReadStandardOutput()
+{
+  QString output = QString(readAllStandardOutput());
+  foreach (QString line, output.split("\n")) {
+    vInfo("(%1:stdout): %2").arg(_processName).arg(line);
+  }
+}
+
 /** Start the specified application. */
 void
 HelperProcess::start(const QString &app, const QStringList &args) 
 {
+  // Remember the executable name of the process
+  QFileInfo fi(app);
+  _processName = fi.fileName();
+
+  // Log the process name and arguments
+  vNotice("Launching helper process '%1' with arguments '%2'").arg(app)
+                                     .arg(string_format_arguments(args));
+
   // Start the specified application
   QProcess::start(app, args, QIODevice::ReadOnly | QIODevice::Text);
 }
@@ -66,6 +103,8 @@
 {
   // Pass up error messages on startup, but ignore the rest
   if (error == QProcess::FailedToStart) {
+    vWarn("Helper process '%1' failed to start: %2").arg(_processName)
+                                                    .arg(errorString());
     emit startFailed(errorString());
   }
 }

Modified: vidalia/branches/alt-launcher/src/vidalia/helperprocess.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/helperprocess.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/helperprocess.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -56,13 +56,20 @@
   /** Returns true iff process is not running. */
   bool isDone() const;
 
+signals:
+  /** Invoked when start() fails. */
+  void startFailed(const QString &errorMessage);
+    
 private slots:
   /** Invoked when underlying QProcess fails. */
   void onError(QProcess::ProcessError error);
+  /** Invoked when output is written to the process's stderr. */
+  void onReadyReadStandardError();
+  /** Invoked when output is written to the process's stdout. */
+  void onReadyReadStandardOutput();
 
-signals:
-  /** Invoked when start() fails. */
-  void startFailed(const QString &errorMessage);
+private:
+  QString _processName;
 };
 
 #endif

Modified: vidalia/branches/alt-launcher/src/vidalia/i18n/es/qt_es.po
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/i18n/es/qt_es.po	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/i18n/es/qt_es.po	2009-02-02 17:47:07 UTC (rev 3503)
@@ -3,14 +3,14 @@
 "Project-Id-Version: Vidalia\n"
 "Report-Msgid-Bugs-To: translations@xxxxxxxxxxxxxxxxxxx\n"
 "POT-Creation-Date: 2008-08-20 04:58+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: \n"
+"PO-Revision-Date: 2008-09-16 09:57+0000\n"
+"Last-Translator: Susan Neni Meiro <y57ctq_translation@xxxxxxxxxxxxx>\n"
 "Language-Team: translations@xxxxxxxxxxxxxxxxxxx\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-"X-Generator: Vidalia ts2po 0.2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.1.0\n"
 
 #: qaccessibleobject.cpp:348
 msgctxt "QApplication"
@@ -200,17 +200,15 @@
 msgctxt "QFileDialog"
 msgid "%1 already exists."
 "Do you want to replace it?"
-msgstr "El fichero %1 ya existe."
-"¿Desea reemplazarlo?"
+msgstr "El fichero %1 ya existe. ¿Desea reemplazarlo?"
 
 #: qfiledialog.cpp:1702
 msgctxt "QFileDialog"
 msgid "%1"
 "File not found."
 "Please verify the correct file name was given."
-msgstr "%1"
-"Fichero no encontrado."
-"Verifique que el nombre del fichero es correcto."
+msgstr ""
+"%1Fichero no encontrado. Verifique que el nombre del fichero es correcto."
 
 #: qdirmodel.cpp:835
 msgctxt "QFileDialog"
@@ -275,9 +273,9 @@
 msgid "%1"
 "Directory not found."
 "Please verify the correct directory name was given."
-msgstr "%1"
-"Directorio no encontrado."
-"Verique que el nombre del directorio es correcto."
+msgstr ""
+"%1Directorio no encontrado. Verifique que el nombre del directorio es "
+"correcto."
 
 #: qfiledialog.cpp:2296
 msgctxt "QFileDialog"
@@ -444,4 +442,3 @@
 msgctxt "QFileSystemModel"
 msgid "Type"
 msgstr "Tipo"
-

Modified: vidalia/branches/alt-launcher/src/vidalia/i18n/sv/qt_sv.po
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/i18n/sv/qt_sv.po	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/i18n/sv/qt_sv.po	2009-02-02 17:47:07 UTC (rev 3503)
@@ -3,14 +3,14 @@
 "Project-Id-Version: Vidalia\n"
 "Report-Msgid-Bugs-To: translations@xxxxxxxxxxxxxxxxxxx\n"
 "POT-Creation-Date: 2008-08-20 05:04+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: \n"
+"PO-Revision-Date: 2009-01-23 19:27+0000\n"
+"Last-Translator: Robin <redyey@xxxxxxxxx>\n"
 "Language-Team: translations@xxxxxxxxxxxxxxxxxxx\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-"X-Generator: Vidalia ts2po 0.2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.1.0\n"
 
 #: qaccessibleobject.cpp:348
 msgctxt "QApplication"
@@ -20,7 +20,7 @@
 #: qmessagebox.h:319
 msgctxt "QApplication"
 msgid "Executable '%1' requires Qt %2, found Qt %3."
-msgstr "Binären \\"%1\\" kräver Qt %2, hittade Qt %3."
+msgstr "Binären \\"" kräver Qt %2, hittade Qt %3."
 
 #: qmessagebox.h:321
 msgctxt "QApplication"
@@ -135,7 +135,7 @@
 #: qdialogbuttonbox.cpp:552
 msgctxt "QDialogButtonBox"
 msgid "Close without Saving"
-msgstr ""
+msgstr "Stäng utan att spara"
 
 #: qdialogbuttonbox.cpp:525
 msgctxt "QDialogButtonBox"
@@ -211,7 +211,7 @@
 #: qdirmodel.cpp:833
 msgctxt "QFileDialog"
 msgid "My Computer"
-msgstr "Min dator"
+msgstr "Den här datorn"
 
 #: qfiledialog.cpp:462
 msgctxt "QFileDialog"
@@ -280,13 +280,13 @@
 msgctxt "QFileDialog"
 msgid "'%1' is write protected."
 "Do you want to delete it anyway?"
-msgstr "\\"%1\\" är skrivskyddad. "
+msgstr "\\"" är skrivskyddad. "
 "Vill du ta bort den ändå?"
 
 #: qfiledialog.cpp:2286
 msgctxt "QFileDialog"
 msgid "Are sure you want to delete '%1'?"
-msgstr "Är du säker på att du vill ta bort \\"%1\\"?"
+msgstr "Är du säker på att du vill ta bort \\""?"
 
 #: qfiledialog.cpp:2299
 msgctxt "QFileDialog"
@@ -326,7 +326,7 @@
 #: qfiledialog.cpp:458
 msgctxt "QFileDialog"
 msgid "Show "
-msgstr ""
+msgstr "Visa"
 
 #: ui_qfiledialog.h:269
 msgctxt "QFileDialog"
@@ -341,17 +341,17 @@
 #: qfiledialog.cpp:465
 msgctxt "QFileDialog"
 msgid "&New Folder"
-msgstr ""
+msgstr "&Ny mapp"
 
 #: qfiledialog.cpp:917
 msgctxt "QFileDialog"
 msgid "&Choose"
-msgstr ""
+msgstr "&Välj"
 
 #: qsidebar.cpp:388
 msgctxt "QFileDialog"
 msgid "Remove"
-msgstr ""
+msgstr "Ta bort"
 
 #: qfiledialog.cpp:886
 msgctxt "QFileDialog"
@@ -361,7 +361,7 @@
 #: ui_qfiledialog.h:261
 msgctxt "QFileDialog"
 msgid "Look in:"
-msgstr ""
+msgstr "Kolla i:"
 
 #: ui_qfiledialog.h:279
 msgctxt "QFileDialog"
@@ -371,37 +371,39 @@
 #: qfilesystemmodel.cpp:677
 msgctxt "QFileSystemModel"
 msgid "%1 TB"
-msgstr ""
+msgstr "%1 TB"
 
 #: qfilesystemmodel.cpp:679
 msgctxt "QFileSystemModel"
 msgid "%1 GB"
-msgstr ""
+msgstr "%1 GB"
 
 #: qfilesystemmodel.cpp:681
 msgctxt "QFileSystemModel"
 msgid "%1 MB"
-msgstr ""
+msgstr "%1 MB"
 
 #: qfilesystemmodel.cpp:683
 msgctxt "QFileSystemModel"
 msgid "%1 KB"
-msgstr ""
+msgstr "%1 KB"
 
 #: qfilesystemmodel.cpp:684
 msgctxt "QFileSystemModel"
 msgid "%1 bytes"
-msgstr ""
+msgstr "%1 bytes"
 
 #: qfilesystemmodel.cpp:761
 msgctxt "QFileSystemModel"
 msgid "Invalid filename"
-msgstr ""
+msgstr "Ogiltigt filnamn"
 
 #: qfilesystemmodel.cpp:763
 msgctxt "QFileSystemModel"
 msgid "<b>The name \"%1\" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks."
 msgstr ""
+"<b>Namnet \"%1\" kan inte användas.</b><p>Försök använda ett nytt namn, med "
+"färre tecken eller inga skiljetecken."
 
 #: qfilesystemmodel.cpp:832
 msgctxt "QFileSystemModel"
@@ -431,10 +433,9 @@
 #: qfilesystemmodel_p.h:198
 msgctxt "QFileSystemModel"
 msgid "My Computer"
-msgstr "Min dator"
+msgstr "Den här datorn"
 
 #: qfilesystemmodel_p.h:200
 msgctxt "QFileSystemModel"
 msgid "Computer"
-msgstr ""
-
+msgstr "Dator"

Modified: vidalia/branches/alt-launcher/src/vidalia/i18n/sv/vidalia_sv.po
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/i18n/sv/vidalia_sv.po	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/i18n/sv/vidalia_sv.po	2009-02-02 17:47:07 UTC (rev 3503)
@@ -3,14 +3,14 @@
 "Project-Id-Version: Vidalia\n"
 "Report-Msgid-Bugs-To: translations@xxxxxxxxxxxxxxxxxxx\n"
 "POT-Creation-Date: 2008-11-24 15:59+0000\n"
-"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
-"Last-Translator: \n"
+"PO-Revision-Date: 2009-01-23 21:27+0000\n"
+"Last-Translator: Robin <redyey@xxxxxxxxx>\n"
 "Language-Team: translations@xxxxxxxxxxxxxxxxxxx\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
-"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
-"X-Generator: Vidalia ts2po 0.2\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+"X-Generator: Pootle 1.1.0\n"
 
 #: aboutdialog.ui:16
 msgctxt "AboutDialog"
@@ -35,12 +35,12 @@
 #: aboutdialog.cpp:53
 msgctxt "AboutDialog"
 msgid "Unavailable"
-msgstr ""
+msgstr "Otillgänglig"
 
 #: aboutdialog.cpp:57
 msgctxt "AboutDialog"
 msgid "Not Running"
-msgstr ""
+msgstr "Körs ej"
 
 #: aboutdialog.ui:81
 msgctxt "AboutDialog"
@@ -50,7 +50,7 @@
 #: aboutdialog.ui:106
 msgctxt "AboutDialog"
 msgid "0.2.0.31-alpha-dev (r123456)"
-msgstr ""
+msgstr "0.2.0.31-alpha-dev (r123456)"
 
 #: aboutdialog.ui:131
 msgctxt "AboutDialog"
@@ -60,12 +60,12 @@
 #: aboutdialog.ui:107
 msgctxt "AboutDialog"
 msgid "License"
-msgstr ""
+msgstr "Licens"
 
 #: aboutdialog.ui:163
 msgctxt "AboutDialog"
 msgid "version"
-msgstr ""
+msgstr "version"
 
 #: advancedpage.ui:28
 msgctxt "AdvancedPage"
@@ -169,7 +169,7 @@
 #: advancedpage.ui:111
 msgctxt "AdvancedPage"
 msgid "Randomly Generate"
-msgstr ""
+msgstr "Slumpvist generera"
 
 #: advancedpage.ui:86
 msgctxt "AdvancedPage"
@@ -229,7 +229,7 @@
 #: appearancepage.cpp:67
 msgctxt "AppearancePage"
 msgid "Vidalia was unable to load the selected language translation."
-msgstr ""
+msgstr "Vidalia kunde ej ladda den valda språköversättningen"
 
 #: bwgraph.ui:16
 msgctxt "BandwidthGraph"
@@ -359,7 +359,7 @@
 #: circuitlistwidget.cpp:110
 msgctxt "CircuitListWidget"
 msgid "Close Stream (Del)"
-msgstr ""
+msgstr "Avsluta strömmen (Del)"
 
 #: configdialog.cpp:77
 msgctxt "ConfigDialog"
@@ -434,17 +434,19 @@
 #: controlpasswordinputdialog.ui:28
 msgctxt "ControlPasswordInputDialog"
 msgid "Password Required"
-msgstr ""
+msgstr "Lösenord krävs"
 
 #: controlpasswordinputdialog.ui:80
 msgctxt "ControlPasswordInputDialog"
 msgid "Vidalia has connected to a running Tor process that requires a password. Please enter your control password: "
 msgstr ""
+"Vidalia har anslutit till en pågående Tor process som kräver ett lösenord. "
+"Skriv ditt kontroll lösenord."
 
 #: controlpasswordinputdialog.ui:99
 msgctxt "ControlPasswordInputDialog"
 msgid "Remember my password"
-msgstr ""
+msgstr "Kom ihåg mitt lösenord"
 
 #: controlsocket.cpp:80
 msgctxt "ControlSocket"
@@ -494,7 +496,7 @@
 #: generalpage.cpp:106
 msgctxt "GeneralPage"
 msgid "The proxy arguments specified are not properly formatted."
-msgstr ""
+msgstr "Proxy argumenten specificerade är inte rätt formaterade."
 
 #: generalpage.ui:28
 msgctxt "GeneralPage"
@@ -514,17 +516,17 @@
 #: generalpage.ui:93
 msgctxt "GeneralPage"
 msgid "Proxy Application (optional)"
-msgstr ""
+msgstr "Proxy Program (valfritt)"
 
 #: generalpage.ui:99
 msgctxt "GeneralPage"
 msgid "Start a proxy application when Tor starts"
-msgstr ""
+msgstr "Starta ett proxy program när Tor startar"
 
 #: generalpage.ui:135
 msgctxt "GeneralPage"
 msgid "Proxy Application Arguments:"
-msgstr ""
+msgstr "Proxy Program Argument:"
 
 #: graphframe.cpp:238
 msgctxt "GraphFrame"
@@ -724,12 +726,15 @@
 #: helptextbrowser.cpp:72
 msgctxt "HelpTextBrowser"
 msgid "Opening External Link"
-msgstr ""
+msgstr "Öppnar extern länk"
 
 #: helptextbrowser.cpp:76
 msgctxt "HelpTextBrowser"
 msgid "Vidalia can open the link you selected in your default Web browser. If your browser is not currently configured to use Tor then the request will not be anonymous."
 msgstr ""
+"Vidalia kan öppna länken du valde i din uppsprungliga webbrowser. Om din "
+"browser inte är konfigurerar att använda Tor så kommer inte begäran vara "
+"annonym."
 
 #: helptextbrowser.cpp:78
 msgctxt "HelpTextBrowser"
@@ -745,21 +750,23 @@
 msgctxt "HelpTextBrowser"
 msgid "Vidalia was unable to open the selected link in your Web browser. You can still copy the URL and paste it into your browser."
 msgstr ""
+"Vidalia kunde inte öppna den valda länken i din webbrowser. Du kan "
+"fortfarande kopiera länken och klistra in det i din browser."
 
 #: licensedialog.ui:13
 msgctxt "LicenseDialog"
 msgid "License Information"
-msgstr ""
+msgstr "Licens information"
 
 #: licensedialog.ui:43
 msgctxt "LicenseDialog"
 msgid "License"
-msgstr ""
+msgstr "Licens"
 
 #: licensedialog.ui:76
 msgctxt "LicenseDialog"
 msgid "Credits"
-msgstr ""
+msgstr "Credits"
 
 #: logevent.cpp:57
 msgctxt "LogEvent"
@@ -994,7 +1001,7 @@
 #: mainwindow.cpp:1141
 msgctxt "MainWindow"
 msgid "Error Registering for Events"
-msgstr ""
+msgstr "Ett fel uppstod vid eventsregistrering"
 
 #: mainwindow.cpp:1226
 msgctxt "MainWindow"
@@ -1025,6 +1032,8 @@
 msgctxt "MainWindow"
 msgid "The currently installed version of Tor is out of date or no longer recommended. Please visit the Tor website to download the latest version."
 msgstr ""
+"Den nuvarande versionen av Tor är ut daterad eller inte längre "
+"rekommenderad. Besök Tor hemsidan för att ladda ner den senaste versionen"
 
 #: mainwindow.cpp:1333
 msgctxt "MainWindow"
@@ -1045,7 +1054,7 @@
 msgctxt "MainWindow"
 msgid "Your relay is shutting down."
 "Click 'Stop' again to stop your relay now."
-msgstr ""
+msgstr "Din nod stängs ner. Klicka på 'Stop' igen för att stoppa din nod nu."
 
 #: mainwindow.cpp:906
 msgctxt "MainWindow"
@@ -1058,6 +1067,9 @@
 ""
 "Would you like to shutdown gracefully and give clients time to find a new relay?"
 msgstr ""
+"Du kör för tillfället en nod. Om du stänger av din nod kommer samtliga "
+"öppnade förbindelser mellan klienterna att störas. Vill du göra en lugn "
+"avstängning som ger klienterna tid att hitta en ny nod?"
 
 #: mainwindow.cpp:965
 msgctxt "MainWindow"
@@ -1072,7 +1084,7 @@
 #: mainwindow.cpp:997
 msgctxt "MainWindow"
 msgid "Unexpected Error"
-msgstr ""
+msgstr "Oväntat fel"
 
 #: mainwindow.cpp:1001
 msgctxt "MainWindow"
@@ -1080,11 +1092,15 @@
 ""
 "Please check the message log for recent warning or error messages."
 msgstr ""
+"Vidalia upptäckte att Tor programvaran plötsligt stängdes av. Kolla i "
+"medelandeloggen för varningar eller felmedelande."
 
 #: mainwindow.cpp:1078
 msgctxt "MainWindow"
 msgid "The Tor software requires Vidalia to send the contents of an authentication cookie, but Vidalia was unable to find one."
 msgstr ""
+"Tor programvaran kräver att Vidalia skickar innehållet i en verifierad "
+"cookie men Vidalia kunde ej finna någon."
 
 #: mainwindow.cpp:1087
 msgctxt "MainWindow"
@@ -1100,6 +1116,8 @@
 msgctxt "MainWindow"
 msgid "Vidalia was unable to register for some events. Many of Vidalia's features may be unavailable."
 msgstr ""
+"Vidalia kunde ej registrera för vissa händelser. Många av Vidalias "
+"egenskaper kan vara otillgängliga."
 
 #: mainwindow.cpp:1222
 msgctxt "MainWindow"
@@ -1114,12 +1132,12 @@
 #: mainwindow.cpp:1458
 msgctxt "MainWindow"
 msgid "Port Forwarding Failed"
-msgstr ""
+msgstr "Port-Omdirigeringen misslyckades"
 
 #: mainwindow.cpp:1459
 msgctxt "MainWindow"
 msgid "Vidalia was unable to configure automatic port forwarding."
-msgstr ""
+msgstr "Vidalia kunde ej konfigurera automatisk port-omdirigering."
 
 #: mainwindow.ui:49
 msgctxt "MainWindow"
@@ -1129,7 +1147,7 @@
 #: mainwindow.ui:246
 msgctxt "MainWindow"
 msgid "Set up a relay and help the network grow"
-msgstr ""
+msgstr "Sätt upp en nod och hjälp nätverket växa"
 
 #: mainwindow.ui:307
 msgctxt "MainWindow"
@@ -1154,27 +1172,27 @@
 #: mainwindow.cpp:540
 msgctxt "MainWindow"
 msgid "Error starting IM client"
-msgstr ""
+msgstr "Fel när IM klienten startades"
 
 #: mainwindow.cpp:541
 msgctxt "MainWindow"
 msgid "Vidalia was unable to start the configured IM client"
-msgstr ""
+msgstr "Vidalia kunde ej öppna den konfigurerade IM klienten"
 
 #: mainwindow.cpp:579
 msgctxt "MainWindow"
 msgid "Connecting to a relay directory"
-msgstr ""
+msgstr "Ansluter till en nod katalog"
 
 #: mainwindow.cpp:583
 msgctxt "MainWindow"
 msgid "Establishing an encrypted directory connection"
-msgstr ""
+msgstr "Etablerar en krypterad katalog anslutning"
 
 #: mainwindow.cpp:586
 msgctxt "MainWindow"
 msgid "Retrieving network status"
-msgstr ""
+msgstr "Hämtar nätverksstatusen"
 
 #: mainwindow.cpp:589
 msgctxt "MainWindow"
@@ -1184,12 +1202,12 @@
 #: mainwindow.cpp:592
 msgctxt "MainWindow"
 msgid "Loading authority certificates"
-msgstr ""
+msgstr "Laddar auktoritära certifikat "
 
 #: mainwindow.cpp:595
 msgctxt "MainWindow"
 msgid "Requesting relay information"
-msgstr ""
+msgstr "Begär nod information"
 
 #: mainwindow.cpp:598
 msgctxt "MainWindow"
@@ -1204,7 +1222,7 @@
 #: mainwindow.cpp:605
 msgctxt "MainWindow"
 msgid "Establishing a Tor circuit"
-msgstr ""
+msgstr "Etablerar en Tor krets "
 
 #: mainwindow.cpp:1297
 msgctxt "MainWindow"
@@ -1214,17 +1232,17 @@
 #: mainwindow.cpp:612
 msgctxt "MainWindow"
 msgid "Unrecognized startup status"
-msgstr ""
+msgstr "Oidentifierbart uppstartnings status"
 
 #: mainwindow.cpp:619
 msgctxt "MainWindow"
 msgid "miscellaneous"
-msgstr ""
+msgstr "blandat"
 
 #: mainwindow.cpp:622
 msgctxt "MainWindow"
 msgid "identity mismatch"
-msgstr ""
+msgstr "Felmatchade identiteter "
 
 #: mainwindow.cpp:625
 msgctxt "MainWindow"
@@ -1234,27 +1252,27 @@
 #: mainwindow.cpp:628
 msgctxt "MainWindow"
 msgid "connection refused"
-msgstr ""
+msgstr "anslutningen vägrades"
 
 #: mainwindow.cpp:631
 msgctxt "MainWindow"
 msgid "connection timeout"
-msgstr ""
+msgstr "anslutningen gjorde timeout"
 
 #: mainwindow.cpp:634
 msgctxt "MainWindow"
 msgid "read/write error"
-msgstr ""
+msgstr "läs/skriv fel"
 
 #: mainwindow.cpp:637
 msgctxt "MainWindow"
 msgid "no route to host"
-msgstr ""
+msgstr "ingen resväg till värden"
 
 #: mainwindow.cpp:640
 msgctxt "MainWindow"
 msgid "insufficient resources"
-msgstr ""
+msgstr "Otillräckliga resurser"
 
 #: mainwindow.cpp:643
 msgctxt "MainWindow"
@@ -1294,17 +1312,20 @@
 #: mainwindow.cpp:1055
 msgctxt "MainWindow"
 msgid "Authenticating to Tor"
-msgstr ""
+msgstr "Verifierar till Tor"
 
 #: mainwindow.cpp:1210
 msgctxt "MainWindow"
 msgid "Password Reset Failed"
-msgstr ""
+msgstr "Lösenordsreset misslyckades"
 
 #: mainwindow.cpp:1213
 msgctxt "MainWindow"
 msgid "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."
 msgstr ""
+"Vidalia försökte ställa om Tor's kontroll lösenord, men kunde inte starta om "
+"Tor mjukvaran. Kolla i aktivitetshanteraren och säkerställ att ingen annan "
+"Tor process körs. "
 
 #: messagelog.ui:19
 msgctxt "MessageLog"
@@ -1887,16 +1908,21 @@
 msgctxt "NetworkPage"
 msgid "Check if your local network requires a proxy to access the Internet"
 msgstr ""
+"Se ifall ditt lokala nätverk kräver en proxy för att komma åt Internet. "
 
 #: networkpage.ui:176
 msgctxt "NetworkPage"
 msgid "Check to only connect to relays using ports allowed by your firewall"
 msgstr ""
+"Kryssa för om du endast vill använda noder som har portar som är tillåtna av "
+"din brandvägg"
 
 #: networkpage.ui:235
 msgctxt "NetworkPage"
 msgid "Check to encrypt directory requests and, optionally, use bridge relays to access the Tor network"
 msgstr ""
+"Kryssa för om du vill kryptera katalog förfrågningar, alternativt, använda "
+"nod bryggor för att komma åt Tor nätverket"
 
 #: networkpage.ui:262
 msgctxt "NetworkPage"
@@ -1907,6 +1933,8 @@
 msgctxt "NetworkPage"
 msgid "The Tor software you are currently running does not support bridges. <br>Directory connections will still be encrypted."
 msgstr ""
+"Tor programvaran du för tillfället använder stödjer inte bryggor. "
+"<br>Katalog anslutningar kommer fortfarande vara krypterade."
 
 #: policy.cpp:167
 msgctxt "Policy"
@@ -2026,12 +2054,12 @@
 #: routerlistwidget.cpp:68
 msgctxt "RouterListWidget"
 msgid "Nickname"
-msgstr ""
+msgstr "Smeknamn"
 
 #: routerlistwidget.cpp:71
 msgctxt "RouterListWidget"
 msgid "Fingerprint"
-msgstr ""
+msgstr "Fingeravtryck"
 
 #: serverpage.ui:32
 msgctxt "ServerPage"
@@ -2238,6 +2266,8 @@
 msgid "Email address at which you may be reached if there is a"
 "problem with your relay. You might also include your PGP or GPG fingerprint."
 msgstr ""
+"Email adress där du kan nås ifall det blir något problem med ditt relä. Då "
+"kan också inkludera ditt PGP eller GPG fingeravtryck."
 
 #: serverpage.ui:113
 msgctxt "ServerPage"
@@ -2287,17 +2317,17 @@
 #: serverpage.ui:25
 msgctxt "ServerPage"
 msgid "Run as a client only"
-msgstr ""
+msgstr "Kör endast som klient"
 
 #: serverpage.ui:110
 msgctxt "ServerPage"
 msgid "Enable to mirror the relay directory"
-msgstr ""
+msgstr "Aktivera för att avspegla nodens katalog"
 
 #: serverpage.ui:139
 msgctxt "ServerPage"
 msgid "Attempt to automatically configure port forwarding"
-msgstr ""
+msgstr "Försökt att automatiskt konfigurera port-omdirigeringen"
 
 #: serverpage.ui:154
 msgctxt "ServerPage"
@@ -2313,17 +2343,19 @@
 #: serverpage.ui:164
 msgctxt "ServerPage"
 msgid "Show help topic on port forwarding"
-msgstr ""
+msgstr "Visa hjälp avsnitt om port-omdirigering. "
 
 #: serverpage.ui:979
 msgctxt "ServerPage"
 msgid "Tor will still block some outgoing mail and file sharing applications by default to reduce spam and other abuse."
 msgstr ""
+"Tor kommer fortfarande stoppa utgående post- och fildelningsapplikationer "
+"som standard för att förhindra skräppost och missbruk"
 
 #: servicepage.cpp:116
 msgctxt "ServicePage"
 msgid "Error while trying to unpublish all services"
-msgstr ""
+msgstr "Fel när aktiviteterna av publicerades "
 
 #: servicepage.cpp:597
 msgctxt "ServicePage"
@@ -2343,27 +2375,27 @@
 #: servicepage.cpp:547
 msgctxt "ServicePage"
 msgid "Virtual Port may only contain valid port numbers [1..65535]."
-msgstr ""
+msgstr "Virtuella portar får bara innehålla tillåtna port nummer [1..65535]. "
 
 #: servicepage.cpp:578
 msgctxt "ServicePage"
 msgid "Target may only contain address:port, address, or port."
-msgstr ""
+msgstr "Målet för enbart innehålla adressen:porten, adressen, eller porten"
 
 #: servicepage.cpp:598
 msgctxt "ServicePage"
 msgid "Directory already in use by another service."
-msgstr ""
+msgstr "Katalogen används redan av en annan aktivitet."
 
 #: servicepage.ui:19
 msgctxt "ServicePage"
 msgid "Form"
-msgstr ""
+msgstr "Formulär"
 
 #: servicepage.ui:31
 msgctxt "ServicePage"
 msgid "Provided Hidden Services"
-msgstr ""
+msgstr "Erhållna gömda aktiviteter"
 
 #: servicepage.ui:56
 msgctxt "ServicePage"
@@ -2378,7 +2410,7 @@
 #: servicepage.ui:66
 msgctxt "ServicePage"
 msgid "Target"
-msgstr ""
+msgstr "Mål"
 
 #: servicepage.ui:71
 msgctxt "ServicePage"
@@ -2409,16 +2441,20 @@
 msgctxt "ServicePage"
 msgid "Browse in local file system and choose directory for selected service"
 msgstr ""
+"Bläddra i det lokala filsystemet och välj katalog för den valda aktiviteten. "
+""
 
 #: servicepage.cpp:123
 msgctxt "ServicePage"
 msgid "Please configure at least a service directory and a virtual port for each service you want to save. Remove the other ones."
 msgstr ""
+"Konfigurera åtminstone en aktivitets katalog och en virtuell port för varje "
+"aktivitet du vill spara. Ta bort de andra. "
 
 #: servicepage.cpp:384
 msgctxt "ServicePage"
 msgid "Created by Tor"
-msgstr ""
+msgstr "Skapad av Tor"
 
 #: stream.cpp:131
 msgctxt "Stream"
@@ -2463,7 +2499,7 @@
 #: stream.cpp:139
 msgctxt "Stream"
 msgid "Remapped"
-msgstr ""
+msgstr "Om-mappad"
 
 #: torprocess.cpp:107
 msgctxt "TorProcess"
@@ -2483,42 +2519,42 @@
 #: torsettings.cpp:103
 msgctxt "TorSettings"
 msgid "Failed to hash the control password."
-msgstr ""
+msgstr "Misslyckades att göra kontroll lösenordet till ett hashvärde"
 
 #: upnpcontrol.cpp:139
 msgctxt "UPNPControl"
 msgid "Success"
-msgstr ""
+msgstr "Framgång"
 
 #: upnpcontrol.cpp:141
 msgctxt "UPNPControl"
 msgid "No UPnP-enabled devices found"
-msgstr ""
+msgstr "Inga UPnP-aktiverade apparater hittades.  "
 
 #: upnpcontrol.cpp:143
 msgctxt "UPNPControl"
 msgid "No valid UPnP-enabled Internet gateway devices found"
-msgstr ""
+msgstr "Ingen giltig UPnP-aktiverad Internet gateway kunde hittas."
 
 #: upnpcontrol.cpp:145
 msgctxt "UPNPControl"
 msgid "WSAStartup failed"
-msgstr ""
+msgstr "WSAStartup misslyckades"
 
 #: upnpcontrol.cpp:147
 msgctxt "UPNPControl"
 msgid "Failed to add a port mapping"
-msgstr ""
+msgstr "Misslyckades att lägga till en port mapping "
 
 #: upnpcontrol.cpp:149
 msgctxt "UPNPControl"
 msgid "Failed to retrieve a port mapping"
-msgstr ""
+msgstr "Misslyckades att ta emot en port mapping"
 
 #: upnpcontrol.cpp:151
 msgctxt "UPNPControl"
 msgid "Failed to remove a port mapping"
-msgstr ""
+msgstr "Misslyckades att ta bort en port mapping"
 
 #: upnpcontrol.cpp:153
 msgctxt "UPNPControl"
@@ -2528,32 +2564,32 @@
 #: upnptestdialog.cpp:112
 msgctxt "UPNPTestDialog"
 msgid "Discovering UPnP-enabled devices"
-msgstr ""
+msgstr "Letar efter UPnP-aktiverade apparater"
 
 #: upnptestdialog.cpp:117
 msgctxt "UPNPTestDialog"
 msgid "Updating directory port mapping"
-msgstr ""
+msgstr "Uppdaterar katalog port mapping"
 
 #: upnptestdialog.cpp:122
 msgctxt "UPNPTestDialog"
 msgid "Updating relay port mapping"
-msgstr ""
+msgstr "Uppdaterar nod port mapping"
 
 #: upnptestdialog.cpp:127
 msgctxt "UPNPTestDialog"
 msgid "Test completed successfully!"
-msgstr ""
+msgstr "Testet avslutades med goda resultat!"
 
 #: upnptestdialog.ui:13
 msgctxt "UPNPTestDialog"
 msgid "Testing UPnP Support"
-msgstr ""
+msgstr "Testar UPnP Support"
 
 #: upnptestdialog.ui:92
 msgctxt "UPNPTestDialog"
 msgid "Testing Universal Plug & Play Support"
-msgstr ""
+msgstr "Testar Universell Plug & Play Support"
 
 #: vmessagebox.cpp:77
 msgctxt "VMessageBox"
@@ -2693,4 +2729,3 @@
 msgctxt "Vidalia"
 msgid "Unable to open log file '%1': %2"
 msgstr "Kunde ej öppna loggfilen '%1': %2"
-

Modified: vidalia/branches/alt-launcher/src/vidalia/mainwindow.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/mainwindow.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/mainwindow.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -28,6 +28,7 @@
 #include <net.h>
 #include <clientstatusevent.h>
 #include <dangerousversionevent.h>
+#include <dangerousportevent.h>
 #include <vmessagebox.h>
 #include <procutil.h>
 
@@ -54,31 +55,31 @@
 #define IMG_STOP_TOR_16      ":/images/16x16/media-playback-stop.png"
 #define IMG_START_TOR_48     ":/images/48x48/media-playback-start.png"
 #define IMG_STOP_TOR_48      ":/images/48x48/media-playback-stop.png"
-#define IMG_TOR_STOPPED_48   ":/images/48x48/status-red.png"
-#define IMG_TOR_RUNNING_48   ":/images/48x48/status-green.png"
-#define IMG_TOR_STARTING_48  ":/images/48x48/status-orange.png"
-#define IMG_TOR_STOPPING_48  ":/images/48x48/status-orange.png"
+#define IMG_TOR_STOPPED_48   ":/images/48x48/tor-off.png"
+#define IMG_TOR_RUNNING_48   ":/images/48x48/tor-on.png"
+#define IMG_TOR_STARTING_48  ":/images/48x48/tor-starting.png"
+#define IMG_TOR_STOPPING_48  ":/images/48x48/tor-stopping.png"
 
 /* Decide which of our four sets of tray icons to use. */
 #if defined(Q_WS_WIN)
 /* QSystemTrayIcon on Windows wants 16x16 .png files */
-#define IMG_TOR_STOPPED  ":/images/16x16/status-red.png"
-#define IMG_TOR_RUNNING  ":/images/16x16/status-green.png"
-#define IMG_TOR_STARTING ":/images/16x16/status-orange.png"
-#define IMG_TOR_STOPPING ":/images/16x16/status-orange.png"
+#define IMG_TOR_STOPPED  ":/images/16x16/tor-off.png"
+#define IMG_TOR_RUNNING  ":/images/16x16/tor-on.png"
+#define IMG_TOR_STARTING ":/images/16x16/tor-starting.png"
+#define IMG_TOR_STOPPING ":/images/16x16/tor-stopping.png"
 #elif defined(Q_WS_MAC)
 /* On Mac, we always go straight to Carbon to load our dock images 
  * from .icns files */
-#define IMG_TOR_STOPPED    "status-red"
-#define IMG_TOR_RUNNING    "status-green"
-#define IMG_TOR_STARTING   "status-orange"
-#define IMG_TOR_STOPPING   "status-orange"
+#define IMG_TOR_STOPPED    "tor-off"
+#define IMG_TOR_RUNNING    "tor-on"
+#define IMG_TOR_STARTING   "tor-starting"
+#define IMG_TOR_STOPPING   "tor-stopping"
 #else
 /* On X11, we just use always the 22x22 .png files */
-#define IMG_TOR_STOPPED    ":/images/22x22/status-red.png"
-#define IMG_TOR_RUNNING    ":/images/22x22/status-green.png"
-#define IMG_TOR_STARTING   ":/images/22x22/status-orange.png"
-#define IMG_TOR_STOPPING   ":/images/22x22/status-orange.png"
+#define IMG_TOR_STOPPED    ":/images/22x22/tor-off.png"
+#define IMG_TOR_RUNNING    ":/images/22x22/tor-on.png"
+#define IMG_TOR_STARTING   ":/images/22x22/tor-starting.png"
+#define IMG_TOR_STOPPING   ":/images/22x22/tor-stopping.png"
 #endif
 
 /** Only allow 'New Identity' to be clicked once every 10 seconds. */
@@ -263,6 +264,13 @@
       if (bse)
         bootstrapStatusChanged(bse->status());
       cse->accept();
+    } else if (cse->status() == ClientStatusEvent::DangerousPort) {
+      DangerousPortEvent *dpe = dynamic_cast<DangerousPortEvent *>(cse);
+      if (dpe) {
+        bool rejected = (dpe->result() == DangerousPortEvent::Reject);
+        warnDangerousPort(dpe->port(), rejected);
+      }
+      cse->accept();
     }
   } else if (event->type() == CustomEventType::GeneralStatusEvent) {
     GeneralStatusEvent *gse = dynamic_cast<GeneralStatusEvent *>(event);
@@ -1530,6 +1538,66 @@
   }
 }
 
+/** 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>. */
+void
+MainWindow::warnDangerousPort(quint16 port, bool rejected)
+{
+  QString warning, application;
+  QMessageBox dlg(QMessageBox::Warning,
+                  tr("Potentially Unsafe Connection"), QString(),
+                  QMessageBox::Ok | QMessageBox::Ignore);
+
+  switch (port) {
+    case  23:
+     application = tr(", probably Telnet, ");
+     break;
+
+    case 109:
+    case 110:
+    case 143:
+      application = tr(", probably an email client, "); 
+      break;
+
+    default:
+      application = " ";
+  }
+
+  warning = p(tr("One of your applications%1appears to be making a "
+                 "potentially unencrypted and unsafe connection to port %2. "
+                 "Anything sent over this connection could be monitored. "
+                 "Please check your application's configuration and use "
+                 "only encrypted protocols, such as SSL, if possible.")
+                 .arg(application).arg(port));
+  if (rejected) {
+    warning.append(p(tr("Tor has automatically closed your connection in "
+                        "order to protect your anonymity.")));
+  }
+  dlg.setText(warning);
+
+  int ret = dlg.exec();
+  if (ret == QMessageBox::Ignore) {
+    TorSettings settings;
+    QList<quint16> ports;
+    int idx;
+
+    ports = settings.getWarnPlaintextPorts();
+    idx   = ports.indexOf(port);
+    if (idx >= 0) {
+      ports.removeAt(idx);
+      settings.setWarnPlaintextPorts(ports);
+    }
+
+    ports = settings.getRejectPlaintextPorts();
+    idx   = ports.indexOf(port);
+    if (idx >= 0) {
+      ports.removeAt(idx);
+      settings.setRejectPlaintextPorts(ports);
+    }
+  }
+}
+
 /** Creates and displays Vidalia's About dialog. */
 void
 MainWindow::showAboutDialog()

Modified: vidalia/branches/alt-launcher/src/vidalia/mainwindow.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/mainwindow.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/mainwindow.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -195,6 +195,10 @@
   /** Called when Tor thinks its version is old or unrecommended, and displays
    * a message notifying the user. */
   void dangerousTorVersion();
+  /** 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>. */
+  void warnDangerousPort(quint16 port, bool rejected);
   /** Called when Tor's bootstrapping status changes. <b>bse</b> represents
    * Tor's current estimate of its bootstrapping progress. */
   void bootstrapStatusChanged(const BootstrapStatus &bs);

Modified: vidalia/branches/alt-launcher/src/vidalia/mainwindow.ui
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/mainwindow.ui	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/mainwindow.ui	2009-02-02 17:47:07 UTC (rev 3503)
@@ -19,7 +19,7 @@
    <string>Vidalia Control Panel</string>
   </property>
   <property name="windowIcon" >
-   <iconset resource="res/vidalia.qrc" >:/images/48x48/vidalia.png</iconset>
+   <iconset resource="res/vidalia.qrc" >:/images/32x32/tor-logo.png</iconset>
   </property>
   <widget class="QWidget" name="centralwidget" >
    <layout class="QVBoxLayout" >

Modified: vidalia/branches/alt-launcher/src/vidalia/network/circuitlistwidget.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/circuitlistwidget.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/circuitlistwidget.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -18,6 +18,7 @@
 #include <QTimer>
 #include <vidalia.h>
 
+#include "config.h"
 #include "circuitlistwidget.h"
 
 #define IMG_CLOSE   ":/images/22x22/edit-delete.png"
@@ -87,9 +88,11 @@
                                     tr("Zoom to Circuit"), this);
     QAction *closeAct = new QAction(QIcon(IMG_CLOSE),
                                     tr("Close Circuit (Del)"), this);
+#if defined(USE_MARBLE)
     zoomAct->setEnabled(circuitItem->circuit().status() == Circuit::Built);
     menu.addAction(zoomAct);
     menu.addSeparator();
+#endif
     menu.addAction(closeAct);
       
     /* Display the context menu and find out which (if any) action was

Modified: vidalia/branches/alt-launcher/src/vidalia/network/netviewer.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/netviewer.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/netviewer.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -17,8 +17,10 @@
 #include <QMessageBox>
 #include <QHeaderView>
 #include <vidalia.h>
+#include <vmessagebox.h>
 
 #include "netviewer.h"
+#include "routerinfodialog.h"
 
 #define IMG_MOVE    ":/images/22x22/move-map.png"
 #define IMG_ZOOMIN  ":/images/22x22/zoom-in.png"
@@ -65,12 +67,19 @@
     resizeSection(CircuitListWidget::ConnectionColumn, 235);
 
   /* Create the TorMapWidget and add it to the dialog */
+#if defined(USE_MARBLE)
   _map = new TorMapWidget();
+  connect(_map, SIGNAL(displayRouterInfo(QString)),
+          this, SLOT(displayRouterInfo(QString)));
+#else
+  _map = new TorMapImageView();
+#endif
   ui.gridLayout->addWidget(_map);
 
-  /* Connect zoom buttons to ZImageView zoom slots */
-  connect(ui.actionZoomIn, SIGNAL(triggered()), _map, SLOT(zoomIn()));
-  connect(ui.actionZoomOut, SIGNAL(triggered()), _map, SLOT(zoomOut()));
+
+  /* Connect zoom buttons to TorMapWidget zoom slots */
+  connect(ui.actionZoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
+  connect(ui.actionZoomOut, SIGNAL(triggered()), this, SLOT(zoomOut()));
   connect(ui.actionZoomToFit, SIGNAL(triggered()), _map, SLOT(zoomToFit()));
 
   /* Create the timer that will be used to update the router list once every
@@ -470,7 +479,7 @@
         /* Save the location information in the descriptor */
         router->setLocation(geoip);
         /* Plot the router on the map */
-        _map->addRouter(router->id(), geoip.latitude(), geoip.longitude());
+        _map->addRouter(router->descriptor(), geoip);
       }
     }
   }
@@ -484,3 +493,64 @@
   _map->update();
 }
 
+/** Called when the user selects a router on the network map. Displays a 
+ * dialog with detailed information for the router specified by
+ * <b>id</b>.*/
+void
+NetViewer::displayRouterInfo(const QString &id)
+{
+  RouterInfoDialog dlg(this);
+
+  /* Fetch the specified router's descriptor */
+  QStringList rd = _torControl->getRouterDescriptorText(id);
+  if (rd.isEmpty()) {
+    VMessageBox::warning(this, tr("Relay Not Found"),
+                         tr("No details on the selected relay are available."),
+                         VMessageBox::Ok);
+    return;
+  }
+
+  /* Fetch the router's network status information */
+  RouterStatus rs = _torControl->getRouterStatus(id);
+
+  dlg.setRouterInfo(rd, rs);
+
+  /* Populate the UI with information learned from a previous GeoIP request */
+  RouterListItem *item = ui.treeRouterList->findRouterById(id);
+  if (item)
+    dlg.setLocation(item->location());
+  else
+    dlg.setLocation(tr("Unknown"));
+
+  dlg.exec();
+}
+
+/* XXX: The following zoomIn() and zoomOut() slots are a hack. MarbleWidget
+ *      does have zoomIn() and zoomOut() slots to which we could connect the
+ *      buttons, but these slots currently don't force a repaint. So to see
+ *      the zoom effect, the user has to click on the map after clicking one
+ *      of the zoom buttons. Instead, we use the zoomViewBy() method, which
+ *      DOES force a repaint.
+ */
+/** Called when the user clicks the "Zoom In" button. */
+void
+NetViewer::zoomIn()
+{
+#if defined(USE_MARBLE)
+  _map->zoomViewBy(40);
+#else
+  _map->zoomIn();
+#endif
+}
+
+/** Called when the user clicks the "Zoom Out" button. */
+void
+NetViewer::zoomOut()
+{
+#if defined(USE_MARBLE)
+  _map->zoomViewBy(-40);
+#else
+  _map->zoomOut();
+#endif
+}
+

Modified: vidalia/branches/alt-launcher/src/vidalia/network/netviewer.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/netviewer.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/netviewer.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -26,9 +26,13 @@
 #include <vidaliawindow.h>
 
 #include "geoipresolver.h"
-#include "tormapwidget.h"
 #include "ui_netviewer.h"
 
+#if defined(USE_MARBLE)
+#include "tormapwidget.h"
+#else
+#include "tormapimageview.h"
+#endif
 
 class NetViewer : public VidaliaWindow
 {
@@ -74,7 +78,15 @@
   void onDisconnected();
   /** Resolves IP addresses in the resolve queue to geographic information. */
   void resolve();
-  
+  /** Called when the user selects a router on the network map. Displays a 
+   * dialog with detailed information for the router specified by
+   * <b>id</b>.*/
+  void displayRouterInfo(const QString &id);
+  /** Called when the user clicks the "Zoom In" button. */
+  void zoomIn();
+  /** Called when the user clicks the "Zoom Out" button. */
+  void zoomOut();
+
 private:
   /** Adds an IP address to the resolve queue and updates the queue timers. */
   void addToResolveQueue(const QHostAddress &ip, const QString &id);
@@ -95,8 +107,6 @@
   TorControl* _torControl;
   /** Timer that fires once an hour to update the router list. */
   QTimer _refreshTimer;
-  /** TorMapWidget that displays the map. */
-  TorMapWidget* _map;
   /** GeoIpResolver used to geolocate routers by IP address. */
   GeoIpResolver _geoip;
   /** Queue for IPs pending resolution to geographic information. */
@@ -112,7 +122,14 @@
    * MAX_RESOLVE_QUEUE_DELAY milliseconds after inserting the first item 
    * into the queue. */
   QTimer _maxResolveQueueTimer;
-  
+ 
+  /** Widget that displays the Tor network map. */
+#if defined(USE_MARBLE)
+  TorMapWidget* _map;
+#else
+  TorMapImageView* _map;
+#endif
+
   /** Qt Designer generated object **/
   Ui::NetViewer ui;
 };

Modified: vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -22,9 +22,10 @@
 #include <QTextDocumentFragment>
 #include <html.h>
 #include <vidalia.h>
+#include <stringutil.h>
+
 #include "routerdescriptorview.h"
 
-#define DATE_FORMAT   "yyyy-MM-dd HH:mm:ss"
 #define IMG_COPY      ":/images/22x22/edit-copy.png"
 
 
@@ -66,13 +67,6 @@
   vApp->clipboard()->setText(selectedText);
 }
 
-/** Format the date the descriptor was published. */
-QString
-RouterDescriptorView::formatPublished(QDateTime date)
-{
-  return date.toString(DATE_FORMAT) + " GMT";
-}
-
 /** Adjusts the displayed uptime to include time since the router's descriptor
  * was last published. */
 quint64
@@ -86,38 +80,6 @@
   return (uptime + (now.toTime_t() - published.toTime_t()));
 }
 
-/** Format the uptime for this router in a readable format. */
-QString
-RouterDescriptorView::formatUptime(quint64 seconds)
-{
-  QString uptime;
-  int secs  = (seconds % 60);
-  int mins  = (seconds / 60 % 60);
-  int hours = (seconds / 3600 % 24);
-  int days  = (seconds / 86400);
-
-  if (days) {
-    uptime += tr("%1 days ").arg(days);
-  }
-  if (hours) {
-    uptime += tr("%1 hours ").arg(hours);
-  }
-  if (mins) {
-    uptime += tr("%1 mins ").arg(mins);
-  }
-  if (secs) {
-    uptime += tr("%1 secs").arg(secs);
-  }
-  return uptime;
-}
-
-/** Format the bandwidth into KB/s. */
-QString
-RouterDescriptorView::formatBandwidth(quint64 bandwidth)
-{
-  return QString::number(bandwidth/1024);
-}
-
 /** Displays all router descriptors in the given list. */
 void
 RouterDescriptorView::display(QList<RouterDescriptor> rdlist)
@@ -146,18 +108,18 @@
     /* If the router is online, then show the uptime and bandwidth stats. */
     if (!rd.offline()) {
       html.append(trow(tcol(b(tr("Bandwidth:")))  + 
-                       tcol(formatBandwidth(rd.observedBandwidth()) + " KB/s")));
+                       tcol(string_format_bandwidth(rd.observedBandwidth()))));
       html.append(trow(tcol(b(tr("Uptime:")))   + 
-                       tcol(formatUptime(
+                       tcol(string_format_uptime(
                               adjustUptime(rd.uptime(), rd.published())))));
     }
-    
+
     /* Date the router was published */
     html.append(trow(tcol(b(tr("Last Updated:")))  +
-                     tcol(formatPublished(rd.published()))));
-    
+                     tcol(string_format_datetime(rd.published()) + " GMT")));
+
     html.append("</table>");
-    
+
     /* If there are multiple descriptors, and this isn't is the last one 
      * then separate them with a short horizontal line. */
     if (r+1 != rdlist.size()) {

Modified: vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerdescriptorview.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -50,12 +50,6 @@
   /** Adjusts the displayed uptime to include time since the
    * router's descriptor was last published. */
   quint64 adjustUptime(quint64 uptime, QDateTime published);
-  /** Formats the descriptor's published date. */
-  QString formatPublished(QDateTime date);
-  /** Formats the router's uptime. */
-  QString formatUptime(quint64 seconds);
-  /** Formats the observed bandwidth into KB/s. */
-  QString formatBandwidth(quint64 bandwidth);
 };
 
 #endif

Copied: vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.cpp (from rev 3502, vidalia/trunk/src/vidalia/network/routerinfodialog.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,79 @@
+/*
+**  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 routerinfodialog.cpp
+** \version $Id$
+** \brief Displays detailed information about a particular router
+*/
+
+#include <stringutil.h>
+
+#include "routerinfodialog.h"
+
+
+RouterInfoDialog::RouterInfoDialog(QWidget *parent)
+  : QDialog(parent)
+{
+  ui.setupUi(this);
+}
+
+quint64
+RouterInfoDialog::adjustUptime(quint64 uptime, const QDateTime &published)
+{
+  QDateTime now = QDateTime::currentDateTime().toUTC();
+
+  if (now < published)
+    return uptime;
+
+  return (uptime + (now.toTime_t() - published.toTime_t()));
+}
+
+void
+RouterInfoDialog::setRouterInfo(const QStringList &desc,
+                                const RouterStatus &status)
+{
+  RouterDescriptor rd(desc);
+
+  ui.lblName->setText(rd.name());
+  ui.lblIPAddress->setText(rd.ip().toString());
+  ui.lblPlatform->setText(rd.platform());
+  ui.lblBandwidth->setText(string_format_bandwidth(rd.observedBandwidth()));
+  ui.lblLastUpdated->setText(string_format_datetime(rd.published()) + " GMT");
+  ui.lblUptime->setText(string_format_uptime(adjustUptime(rd.uptime(),
+                                                          rd.published())));
+
+  if (rd.hibernating()) {
+    ui.lblStatus->setText(tr("Hibernating"));
+  } else if (status.isValid()) {
+    if (status.flags() & RouterStatus::Running)
+      ui.lblStatus->setText(tr("Online"));
+    else
+      ui.lblStatus->setText(tr("Offline"));
+  } else {
+    ui.lblStatus->setText(tr("Unknown"));
+  }
+
+  if (! rd.contact().isEmpty()) {
+    ui.lblContact->setText(rd.contact());
+  } else {
+    ui.lblContact->setVisible(false);
+    ui.lblContactLabel->setVisible(false);
+  }
+
+  ui.textDescriptor->setPlainText(desc.join("\n"));
+}
+
+void
+RouterInfoDialog::setLocation(const QString &location)
+{
+  ui.lblLocation->setText(location);
+}
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.h (from rev 3502, vidalia/trunk/src/vidalia/network/routerinfodialog.h)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,58 @@
+/*
+**  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 routerinfodialog.h
+** \version $Id$
+** \brief Displays detailed information about a particular router
+*/
+
+
+#ifndef _ROUTERINFODIALOG_H
+#define _ROUTERINFODIALOG_H
+
+#include <QDialog>
+#include <routerdescriptor.h>
+#include <routerstatus.h>
+
+#include "ui_routerinfodialog.h"
+
+
+class RouterInfoDialog : public QDialog
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor.
+   */
+  RouterInfoDialog(QWidget *parent = 0);
+
+  /** Populates the dialog's UI with information parsed from the router
+   * descriptor <b>desc</b> and the router status information in
+   * <b>status</b>.
+   */
+  void setRouterInfo(const QStringList &desc, const RouterStatus &status);
+
+  /** Sets the geographic location information displayed in the dialog to
+   * <b>location</b>.
+   */
+  void setLocation(const QString &location);
+
+private:
+  /** Adjusts <b>uptime</b> to be the greater of either <b>published</b> or
+   * <b>uptime</b> plus the number of seconds elapsed since <b>published</b>.
+   */
+  quint64 adjustUptime(quint64 uptime, const QDateTime &published);
+
+  Ui::RouterInfoDialog ui;
+};
+
+#endif
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.ui (from rev 3502, vidalia/trunk/src/vidalia/network/routerinfodialog.ui)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.ui	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerinfodialog.ui	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,449 @@
+<ui version="4.0" >
+ <class>RouterInfoDialog</class>
+ <widget class="QDialog" name="RouterInfoDialog" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>427</width>
+    <height>382</height>
+   </rect>
+  </property>
+  <property name="windowTitle" >
+   <string>Relay Details</string>
+  </property>
+  <layout class="QVBoxLayout" name="verticalLayout" >
+   <item>
+    <widget class="QTabWidget" name="tabWidget" >
+     <property name="tabShape" >
+      <enum>QTabWidget::Rounded</enum>
+     </property>
+     <property name="currentIndex" >
+      <number>0</number>
+     </property>
+     <property name="usesScrollButtons" >
+      <bool>false</bool>
+     </property>
+     <widget class="QWidget" name="tabSummary" >
+      <attribute name="title" >
+       <string>Summary</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout_2" >
+       <item row="0" column="0" >
+        <widget class="QLabel" name="lblNameLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Name:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="0" column="1" >
+        <widget class="QLabel" name="lblName" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="0" >
+        <widget class="QLabel" name="lblStatusLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Status:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="1" column="1" >
+        <widget class="QLabel" name="lblStatus" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="0" >
+        <widget class="QLabel" name="lblLocationLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Location:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="2" column="1" >
+        <widget class="QLabel" name="lblLocation" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="0" >
+        <widget class="QLabel" name="lblIPAddressLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>IP Address:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="3" column="1" >
+        <widget class="QLabel" name="lblIPAddress" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="0" >
+        <widget class="QLabel" name="lblPlatformLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Platform:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="4" column="1" >
+        <widget class="QLabel" name="lblPlatform" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="minimumSize" >
+          <size>
+           <width>0</width>
+           <height>0</height>
+          </size>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+         <property name="wordWrap" >
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="0" >
+        <widget class="QLabel" name="lblBandwidthLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Bandwidth:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="5" column="1" >
+        <widget class="QLabel" name="lblBandwidth" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="6" column="0" >
+        <widget class="QLabel" name="lblUptimeLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Uptime:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="6" column="1" >
+        <widget class="QLabel" name="lblUptime" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item row="8" column="0" >
+        <widget class="QLabel" name="lblContactLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Contact:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="8" column="1" >
+        <widget class="QLabel" name="lblContact" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+         <property name="wordWrap" >
+          <bool>true</bool>
+         </property>
+        </widget>
+       </item>
+       <item row="10" column="0" >
+        <spacer name="verticalSpacer" >
+         <property name="orientation" >
+          <enum>Qt::Vertical</enum>
+         </property>
+         <property name="sizeHint" stdset="0" >
+          <size>
+           <width>20</width>
+           <height>40</height>
+          </size>
+         </property>
+        </spacer>
+       </item>
+       <item row="9" column="0" >
+        <widget class="QLabel" name="lblLastUpdatedLabel" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="font" >
+          <font>
+           <weight>75</weight>
+           <bold>true</bold>
+          </font>
+         </property>
+         <property name="text" >
+          <string>Last Updated:</string>
+         </property>
+         <property name="alignment" >
+          <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+         </property>
+        </widget>
+       </item>
+       <item row="9" column="1" >
+        <widget class="QLabel" name="lblLastUpdated" >
+         <property name="sizePolicy" >
+          <sizepolicy vsizetype="Preferred" hsizetype="MinimumExpanding" >
+           <horstretch>0</horstretch>
+           <verstretch>0</verstretch>
+          </sizepolicy>
+         </property>
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+     <widget class="QWidget" name="tabDescriptor" >
+      <attribute name="title" >
+       <string>Descriptor</string>
+      </attribute>
+      <layout class="QGridLayout" name="gridLayout" >
+       <item row="0" column="0" >
+        <widget class="QTextEdit" name="textDescriptor" >
+         <property name="font" >
+          <font>
+           <family>Courier New</family>
+           <pointsize>10</pointsize>
+          </font>
+         </property>
+         <property name="lineWrapMode" >
+          <enum>QTextEdit::NoWrap</enum>
+         </property>
+         <property name="acceptRichText" >
+          <bool>false</bool>
+         </property>
+         <property name="textInteractionFlags" >
+          <set>Qt::TextSelectableByKeyboard|Qt::TextSelectableByMouse</set>
+         </property>
+        </widget>
+       </item>
+      </layout>
+     </widget>
+    </widget>
+   </item>
+   <item>
+    <widget class="QDialogButtonBox" name="buttonBox" >
+     <property name="orientation" >
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons" >
+      <set>QDialogButtonBox::Close</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>RouterInfoDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>RouterInfoDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel" >
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel" >
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>

Modified: vidalia/branches/alt-launcher/src/vidalia/network/routerlistitem.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/routerlistitem.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/routerlistitem.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -48,6 +48,8 @@
   RouterDescriptor descriptor() const { return *_rd; }
   /** Sets the location information for this router item. */
   void setLocation(const GeoIp &geoip);
+  /** Returns the location information set for this router item. */
+  QString location() const { return _rd->location(); }
 
   /** Overload the comparison operator. */
   virtual bool operator<(const QTreeWidgetItem &other) const;

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.cpp (from rev 3502, vidalia/trunk/src/vidalia/network/tormapimageview.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,326 @@
+/*
+**  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 tormapimageview.cpp
+** \version $Id$
+** \brief Displays Tor servers and circuits on a map of the world
+*/
+
+#include <QStringList>
+#include <cmath>
+#include "tormapimageview.h"
+
+#define IMG_WORLD_MAP   ":/images/map/world-map.png"
+
+/** QPens to use for drawing different map elements */
+#define PEN_ROUTER        QPen(QColor("#ff030d"), 1.0)
+#define PEN_CIRCUIT       QPen(Qt::yellow, 0.5)
+#define PEN_SELECTED      QPen(Qt::green, 2.0)
+
+/** Size of the map image */
+#define IMG_WIDTH       1000
+#define IMG_HEIGHT      507
+
+/** Border between the edge of the image and the actual map */
+#define MAP_TOP         2
+#define MAP_BOTTOM      2
+#define MAP_RIGHT       5
+#define MAP_LEFT        5
+#define MAP_WIDTH       (IMG_WIDTH-MAP_LEFT-MAP_RIGHT)
+#define MAP_HEIGHT      (IMG_HEIGHT-MAP_TOP-MAP_BOTTOM)
+
+/** Map offset from zero longitude */
+#define MAP_ORIGIN       -10
+
+/** Minimum allowable size for this widget */
+#define MIN_SIZE        QSize(512,256)
+
+/** Robinson projection table */
+/** Length of the parallel of latitude */
+static float  plen[] = {
+    1.0000, 0.9986, 0.9954, 0.9900,
+    0.9822, 0.9730, 0.9600, 0.9427,
+    0.9216, 0.8962, 0.8679, 0.8350,
+    0.7986, 0.7597, 0.7186, 0.6732,
+    0.6213, 0.5722, 0.5322
+  };
+
+/** Distance of corresponding parallel from equator */ 
+static float  pdfe[] = {
+    0.0000, 0.0620, 0.1240, 0.1860,
+    0.2480, 0.3100, 0.3720, 0.4340,
+    0.4958, 0.5571, 0.6176, 0.6769,
+    0.7346, 0.7903, 0.8435, 0.8936,
+    0.9394, 0.9761, 1.0000
+  };
+
+/** Default constructor */
+TorMapImageView::TorMapImageView(QWidget *parent)
+: ZImageView(parent)
+{
+  QImage map(IMG_WORLD_MAP);
+  setImage(map);
+}
+
+/** Destructor */
+TorMapImageView::~TorMapImageView()
+{
+  clear();
+}
+
+/** Adds a router to the map. */
+void
+TorMapImageView::addRouter(const RouterDescriptor &desc, const GeoIp &geoip)
+{
+  QString id = desc.id();
+  QPointF routerCoord = toMapSpace(geoip.latitude(), geoip.longitude());
+  
+  /* Add data the hash of known routers, and plot the point on the map */
+  if (_routers.contains(id))
+    _routers.value(id)->first = routerCoord;
+  else
+    _routers.insert(id, new QPair<QPointF,bool>(routerCoord, false));
+}
+
+/** Adds a circuit to the map using the given ordered list of router IDs. */
+void
+TorMapImageView::addCircuit(const CircuitId &circid, const QStringList &path)
+{
+  QPainterPath *circPainterPath = new QPainterPath;
+  
+  /* Build the new circuit */
+  for (int i = 0; i < path.size()-1; i++) {
+    QString fromNode = path.at(i);
+    QString toNode = path.at(i+1);
+   
+    /* Add the coordinates of the hops to the circuit */
+    if (_routers.contains(fromNode) && _routers.contains(toNode)) {
+      /* Find the two endpoints for this path segment */
+      QPointF fromPos = _routers.value(fromNode)->first;
+      QPointF endPos = _routers.value(toNode)->first;
+      
+      /* Draw the path segment */ 
+      circPainterPath->moveTo(fromPos);
+      circPainterPath->lineTo(endPos);
+      circPainterPath->moveTo(endPos);
+    }
+  }
+  
+  /** Add the data to the hash of known circuits and plot the circuit on the map */
+  if (_circuits.contains(circid)) {
+    /* This circuit is being updated, so just update the path, making sure we
+     * free the memory allocated to the old one. */
+    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
+    delete circuitPair->first;
+    circuitPair->first = circPainterPath;
+  } else {
+    /* This is a new path, so just add it to our list */
+    _circuits.insert(circid, new QPair<QPainterPath*,bool>(circPainterPath,false));
+  }
+}
+
+/** Removes a circuit from the map. */
+void
+TorMapImageView::removeCircuit(const CircuitId &circid)
+{
+  QPair<QPainterPath*,bool> *circ = _circuits.take(circid);
+  QPainterPath *circpath = circ->first;
+  if (circpath) {
+    delete circpath;
+  }
+  delete circ;
+}
+
+/** Selects and highlights the router on the map. */
+void
+TorMapImageView::selectRouter(const QString &id)
+{
+  if (_routers.contains(id)) {
+    QPair<QPointF, bool> *routerPair = _routers.value(id);
+    routerPair->second = true;
+  }
+  repaint();
+}
+
+/** Selects and highlights the circuit with the id <b>circid</b> 
+ * on the map. */
+void
+TorMapImageView::selectCircuit(const CircuitId &circid)
+{
+  if (_circuits.contains(circid)) {
+    QPair<QPainterPath*, bool> *circuitPair = _circuits.value(circid);
+    circuitPair->second = true;
+  }
+  repaint();
+}
+
+/** Deselects any highlighted routers or circuits */
+void
+TorMapImageView::deselectAll()
+{
+  /* Deselect all router points */
+  foreach (QString router, _routers.keys()) {
+    QPair<QPointF,bool> *routerPair = _routers.value(router);
+    routerPair->second = false;
+  }
+  /* Deselect all circuit paths */
+  foreach (CircuitId circid, _circuits.keys()) {
+    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
+    circuitPair->second = false;
+  }
+}
+
+/** Clears the list of routers and removes all the data on the map */
+void
+TorMapImageView::clear()
+{
+  /* Clear out all the router points and free their memory */
+  foreach (QString router, _routers.keys()) {
+    delete _routers.take(router);
+  }
+  /* Clear out all the circuit paths and free their memory */
+  foreach (CircuitId circid, _circuits.keys()) {
+    QPair<QPainterPath*,bool> *circuitPair = _circuits.take(circid);
+    delete circuitPair->first;
+    delete circuitPair;
+  }
+}
+  
+/** Draws the routers and paths onto the map image. */
+void
+TorMapImageView::paintImage(QPainter *painter)
+{
+  painter->setRenderHint(QPainter::Antialiasing);
+  
+  /* Draw the router points */
+  foreach(QString router, _routers.keys()) {
+    QPair<QPointF,bool> *routerPair = _routers.value(router);
+    painter->setPen((routerPair->second ? PEN_SELECTED : PEN_ROUTER)); 
+    painter->drawPoint(routerPair->first);
+  }
+  /* Draw the circuit paths */
+  foreach(CircuitId circid, _circuits.keys()) {
+    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
+    painter->setPen((circuitPair->second ? PEN_SELECTED : PEN_CIRCUIT));
+    painter->drawPath(*(circuitPair->first));
+  }
+}
+
+/** Converts world space coordinates into map space coordinates */
+QPointF
+TorMapImageView::toMapSpace(float latitude, float longitude)
+{
+  float width  = MAP_WIDTH;
+  float height = MAP_HEIGHT;
+  float deg = width / 360.0;
+  longitude += MAP_ORIGIN;
+
+  float lat;
+  float lon;
+  
+  lat = floor(longitude * (deg * lerp(abs(int(latitude)), plen))
+	      + width/2 + MAP_LEFT);
+  
+  if (latitude < 0) {
+    lon = floor((height/2) + (lerp(abs(int(latitude)), pdfe) * (height/2))
+		+ MAP_TOP);
+  } else {
+    lon = floor((height/2) - (lerp(abs(int(latitude)), pdfe) * (height/2))
+		+ MAP_TOP);
+  }
+
+  return QPointF(lat, lon);
+}
+  
+/** Linearly interpolates using the values in the Robinson projection table */
+float
+TorMapImageView::lerp(float input, float *table)
+{
+  int x = int(floor(input / 5));
+
+  return ((table[x+1] - table[x]) / 
+	  (((x+1)*5) - (x*5))) * (input - x*5) + table[x];
+}
+
+/** Returns the minimum size of the widget */
+QSize
+TorMapImageView::minimumSizeHint() const
+{
+  return MIN_SIZE;
+}
+
+/** Zooms to fit all currently displayed circuits on the map. If there are no
+ * circuits on the map, the viewport will be returned to its default position
+ * (zoomed all the way out and centered). */
+void
+TorMapImageView::zoomToFit()
+{
+  QRectF rect = circuitBoundingBox();
+  
+  if (rect.isNull()) {
+    /* If there are no circuits, zoom all the way out */
+    resetZoomPoint();
+    zoom(0.0);
+  } else {
+    /* Zoom in on the displayed circuits */
+    float zoomLevel = 1.0 - qMax(rect.height()/float(MAP_HEIGHT),
+                                 rect.width()/float(MAP_WIDTH));
+    
+    zoom(rect.center().toPoint(), zoomLevel+0.2);
+  }
+}
+
+/** Zoom to the circuit on the map with the given <b>circid</b>. */
+void
+TorMapImageView::zoomToCircuit(const CircuitId &circid)
+{
+  if (_circuits.contains(circid)) {
+    QPair<QPainterPath*,bool> *pair = _circuits.value(circid);
+    QRectF rect = ((QPainterPath *)pair->first)->boundingRect();
+    if (!rect.isNull()) {
+      float zoomLevel = 1.0 - qMax(rect.height()/float(MAP_HEIGHT),
+                                   rect.width()/float(MAP_WIDTH));
+
+      zoom(rect.center().toPoint(), zoomLevel+0.2);
+    }
+  }
+}
+
+/** Zooms in on the router with the given <b>id</b>. */
+void
+TorMapImageView::zoomToRouter(const QString &id)
+{
+  QPair<QPointF,bool> *routerPair;
+  
+  if (_routers.contains(id)) {
+    deselectAll();
+    routerPair = _routers.value(id);
+    routerPair->second = true;  /* Set the router point to "selected" */
+    zoom(routerPair->first.toPoint(), 1.0); 
+  }
+}
+
+/** Computes a bounding box around all currently displayed circuit paths on
+ * the map. */
+QRectF
+TorMapImageView::circuitBoundingBox()
+{
+  QRectF rect;
+
+  /* Compute the union of bounding rectangles for all circuit paths */
+  foreach (CircuitId circid, _circuits.keys()) {
+    QPair<QPainterPath*,bool> *pair = _circuits.value(circid);
+    QPainterPath *circuit = pair->first;
+    rect = rect.unite(circuit->boundingRect());
+  }
+  return rect;
+}
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.h (from rev 3502, vidalia/trunk/src/vidalia/network/tormapimageview.h)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapimageview.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,86 @@
+/*
+**  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 tormapimageview.h
+** \version $Id$
+** \brief Displays Tor servers and circuits on a map of the world
+*/
+
+#ifndef _TORMAPIMAGEVIEW_H
+#define _TORMAPIMAGEVIEW_H
+
+#include <QHash>
+#include <QPair>
+#include <QPainter>
+#include <QPainterPath>
+#include <circuit.h>
+#include <routerdescriptor.h>
+#include <network/geoip.h>
+
+#include "zimageview.h"
+
+
+class TorMapImageView : public ZImageView
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor. */
+  TorMapImageView(QWidget *parent = 0);
+  /** Destructor. */
+  ~TorMapImageView();
+
+  /** Plots the given router on the map using the given coordinates. */
+  void addRouter(const RouterDescriptor &desc, const GeoIp &geoip);
+  /** Plots the given circuit on the map. */
+  void addCircuit(const CircuitId &circid, const QStringList &path);
+  /** Selects and hightlights a router on the map. */
+  void selectRouter(const QString &id);
+  /** Selects and highlights a circuit on the map. */
+  void selectCircuit(const CircuitId &circid);
+  /** Returns the minimum size of the widget */
+  QSize minimumSizeHint() const;
+
+public slots:
+  /** Removes a circuit from the map. */
+  void removeCircuit(const CircuitId &circid);
+  /** Deselects all the highlighted circuits and routers */
+  void deselectAll();
+  /** Clears the known routers and removes all the data from the map */
+  void clear();
+  /** Zooms to fit all currently displayed circuits on the map. */
+  void zoomToFit();
+  /** Zoom to a particular router on the map. */
+  void zoomToRouter(const QString &id);
+  /** Zoom to the circuit on the map with the given <b>circid</b>. */
+  void zoomToCircuit(const CircuitId &circid);
+
+protected:
+  /** Paints the current circuits and streams on the image. */
+  virtual void paintImage(QPainter *painter);
+
+private:
+  /** Converts world space coordinates into map space coordinates */
+  QPointF toMapSpace(float latitude, float longitude);
+  /** Linearly interpolates using the values in the projection table */
+  float lerp(float input, float *table);
+  /** Computes a bounding box around all currently displayed circuit paths on
+   * the map. */
+  QRectF circuitBoundingBox();
+  
+  /** Stores map locations for tor routers */
+  QHash<QString, QPair<QPointF,bool>* > _routers;
+  /** Stores circuit information */
+  QHash<CircuitId, QPair<QPainterPath *,bool>* > _circuits;
+};
+
+#endif
+

Modified: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -15,59 +15,45 @@
 */
 
 #include <QStringList>
-#include <cmath>
+#include <vidalia.h>
+
+#include "tormapwidgetinputhandler.h"
+#include "tormapwidgetpopupmenu.h"
 #include "tormapwidget.h"
 
-#define IMG_WORLD_MAP   ":/images/map/world-map.png"
+using namespace Marble;
 
 /** QPens to use for drawing different map elements */
-#define PEN_ROUTER        QPen(QColor("#ff030d"), 1.0)
-#define PEN_CIRCUIT       QPen(Qt::yellow, 0.5)
-#define PEN_SELECTED      QPen(Qt::green, 2.0)
+#define CIRCUIT_NORMAL_PEN      QPen(Qt::green,  2.0)
+#define CIRCUIT_SELECTED_PEN    QPen(Qt::yellow, 3.0)
 
-/** Size of the map image */
-#define IMG_WIDTH       1000
-#define IMG_HEIGHT      507
 
-/** Border between the edge of the image and the actual map */
-#define MAP_TOP         2
-#define MAP_BOTTOM      2
-#define MAP_RIGHT       5
-#define MAP_LEFT        5
-#define MAP_WIDTH       (IMG_WIDTH-MAP_LEFT-MAP_RIGHT)
-#define MAP_HEIGHT      (IMG_HEIGHT-MAP_TOP-MAP_BOTTOM)
+/** Default constructor */
+TorMapWidget::TorMapWidget(QWidget *parent)
+  : MarbleWidget(parent)
+{
+  setMapThemeId("earth/srtm/srtm.dgml");
+  setShowScaleBar(false);
+  setShowCrosshairs(false);
+  setAnimationsEnabled(true);
+  setCursor(Qt::OpenHandCursor);
 
-/** Map offset from zero longitude */
-#define MAP_ORIGIN       -10
+  TorMapWidgetInputHandler *handler = new TorMapWidgetInputHandler();
+  TorMapWidgetPopupMenu *popupMenu  = new TorMapWidgetPopupMenu(this);
 
-/** Minimum allowable size for this widget */
-#define MIN_SIZE        QSize(512,256)
+  connect(handler, SIGNAL(featureClicked(QPoint,Qt::MouseButton)),
+          popupMenu, SLOT(featureClicked(QPoint,Qt::MouseButton)));
+  connect(popupMenu, SIGNAL(displayRouterInfo(QString)),
+          this, SIGNAL(displayRouterInfo(QString)));
 
-/** Robinson projection table */
-/** Length of the parallel of latitude */
-static float  plen[] = {
-    1.0000, 0.9986, 0.9954, 0.9900,
-    0.9822, 0.9730, 0.9600, 0.9427,
-    0.9216, 0.8962, 0.8679, 0.8350,
-    0.7986, 0.7597, 0.7186, 0.6732,
-    0.6213, 0.5722, 0.5322
-  };
+  /* We can't call setInputHandler() until MarbleWidget has called its
+   * internal _q_initGui() method, which doesn't happen until a
+   * QTimer::singleShot(0, this, SLOT(_q_initGui())) timer set in its
+   * constructor times out. So force that event to process now. */ 
+  vApp->processEvents(QEventLoop::ExcludeUserInputEvents
+                        | QEventLoop::ExcludeSocketNotifiers);
 
-/** Distance of corresponding parallel from equator */ 
-static float  pdfe[] = {
-    0.0000, 0.0620, 0.1240, 0.1860,
-    0.2480, 0.3100, 0.3720, 0.4340,
-    0.4958, 0.5571, 0.6176, 0.6769,
-    0.7346, 0.7903, 0.8435, 0.8936,
-    0.9394, 0.9761, 1.0000
-  };
-
-/** Default constructor */
-TorMapWidget::TorMapWidget(QWidget *parent)
-: ZImageView(parent)
-{
-  QImage map(IMG_WORLD_MAP);
-  setImage(map);
+  setInputHandler(handler);
 }
 
 /** Destructor */
@@ -78,75 +64,109 @@
 
 /** Adds a router to the map. */
 void
-TorMapWidget::addRouter(const QString &id, float latitude, float longitude)
+TorMapWidget::addRouter(const RouterDescriptor &desc, const GeoIp &geoip)
 {
-  QPointF routerCoord = toMapSpace(latitude, longitude);
+  QString kml;
+  qreal lon = geoip.longitude();
+  qreal lat = geoip.latitude();
+  quint64 bw;
   
-  /* Add data the hash of known routers, and plot the point on the map */
-  if (_routers.contains(id))
-    _routers.value(id)->first = routerCoord;
-  else
-    _routers.insert(id, new QPair<QPointF,bool>(routerCoord, false));
+  bw = qMin(desc.averageBandwidth(), desc.burstBandwidth());
+  bw = qMin(bw, desc.observedBandwidth());
+
+  kml.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
+             "<kml xmlns=\"http://earth.google.com/kml/2.0\";>"
+             "<Document>"
+             "  <Style id=\"normalPlacemark\">"
+             "    <IconStyle><Icon><href>:/images/icons/placemark-relay.png</href></Icon></IconStyle>"
+             "  </Style>"
+             );
+
+  kml.append("<Placemark>");
+  kml.append("<styleUrl>#normalPlacemark</styleUrl>");
+  kml.append(QString("<name>%1</name>").arg(desc.name()));
+  kml.append(QString("<description>%1</description>").arg(desc.id()));
+  kml.append(QString("<role>1</role>"));
+  kml.append(QString("<address>%1</address>").arg(geoip.toString()));
+  kml.append(QString("<CountryNameCode>%1</CountryNameCode>").arg(geoip.country()));
+  kml.append(QString("<pop>%1</pop>").arg(10 * bw));
+  kml.append(QString("<Point>"
+                     "  <coordinates>%1,%2</coordinates>"
+                     "</Point>").arg(lon).arg(lat));
+  kml.append("</Placemark>");
+  kml.append("</Document></kml>");
+
+  QString id = desc.id();
+  addPlaceMarkData(kml, id);
+  _routers.insert(id, GeoDataCoordinates(lon, lat, 0.0,
+                                         GeoDataCoordinates::Degree));
 }
 
 /** Adds a circuit to the map using the given ordered list of router IDs. */
 void
 TorMapWidget::addCircuit(const CircuitId &circid, const QStringList &path)
 {
-  QPainterPath *circPainterPath = new QPainterPath;
-  
-  /* Build the new circuit */
-  for (int i = 0; i < path.size()-1; i++) {
-    QString fromNode = path.at(i);
-    QString toNode = path.at(i+1);
-   
-    /* Add the coordinates of the hops to the circuit */
-    if (_routers.contains(fromNode) && _routers.contains(toNode)) {
-      /* Find the two endpoints for this path segment */
-      QPointF fromPos = _routers.value(fromNode)->first;
-      QPointF endPos = _routers.value(toNode)->first;
-      
-      /* Draw the path segment */ 
-      circPainterPath->moveTo(fromPos);
-      circPainterPath->lineTo(endPos);
-      circPainterPath->moveTo(endPos);
-    }
-  }
-  
-  /** Add the data to the hash of known circuits and plot the circuit on the map */
+  /* XXX: Is it better to do KML LineString-based circuit drawing here,
+   *      instead of going with a QPainter-based approach? I gave it a brief
+   *      try once but failed. It might be worth looking into harder if we
+   *      want to make circuits selectable on the map too.
+   */
+
+  /* It doesn't make sense to draw a path of length less than two */
+  if (path.size() < 2)
+    return;
+
   if (_circuits.contains(circid)) {
-    /* This circuit is being updated, so just update the path, making sure we
-     * free the memory allocated to the old one. */
-    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
-    delete circuitPair->first;
-    circuitPair->first = circPainterPath;
+    /* Extend an existing path */
+    CircuitGeoPath *geoPath = _circuits.value(circid);
+
+    QString router = path.at(path.size()-1);
+    if (_routers.contains(router)) {
+      GeoDataCoordinates coords = _routers.value(router);
+      geoPath->first.append(new GeoDataCoordinates(coords));
+    }
   } else {
-    /* This is a new path, so just add it to our list */
-    _circuits.insert(circid, new QPair<QPainterPath*,bool>(circPainterPath,false));
+    /* Construct a new path */
+    CircuitGeoPath *geoPath = new CircuitGeoPath();
+    geoPath->second = false; /* initially unselected */
+
+    foreach (QString router, path) {
+      if (_routers.contains(router)) {
+        GeoDataCoordinates coords = _routers.value(router);
+        geoPath->first.append(new GeoDataCoordinates(coords));
+      }      
+    }
+    _circuits.insert(circid, geoPath);
   }
+
+  repaint();
 }
 
 /** Removes a circuit from the map. */
 void
 TorMapWidget::removeCircuit(const CircuitId &circid)
 {
-  QPair<QPainterPath*,bool> *circ = _circuits.take(circid);
-  QPainterPath *circpath = circ->first;
-  if (circpath) {
-    delete circpath;
+  CircuitGeoPath *path = _circuits.take(circid);
+  if (path) {
+    GeoDataLineString coords = path->first;
+    qDeleteAll(coords.begin(), coords.end());
+    delete path;
   }
-  delete circ;
+
+  repaint();
 }
 
 /** Selects and highlights the router on the map. */
 void
 TorMapWidget::selectRouter(const QString &id)
 {
+#if 0
   if (_routers.contains(id)) {
     QPair<QPointF, bool> *routerPair = _routers.value(id);
     routerPair->second = true;
   }
   repaint();
+#endif
 }
 
 /** Selects and highlights the circuit with the id <b>circid</b> 
@@ -155,9 +175,10 @@
 TorMapWidget::selectCircuit(const CircuitId &circid)
 {
   if (_circuits.contains(circid)) {
-    QPair<QPainterPath*, bool> *circuitPair = _circuits.value(circid);
-    circuitPair->second = true;
+    CircuitGeoPath *path = _circuits.value(circid);
+    path->second = true;
   }
+
   repaint();
 }
 
@@ -165,122 +186,59 @@
 void
 TorMapWidget::deselectAll()
 {
+#if 0
   /* Deselect all router points */
   foreach (QString router, _routers.keys()) {
     QPair<QPointF,bool> *routerPair = _routers.value(router);
     routerPair->second = false;
   }
+#endif
   /* Deselect all circuit paths */
-  foreach (CircuitId circid, _circuits.keys()) {
-    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
-    circuitPair->second = false;
+  foreach (CircuitGeoPath *path, _circuits.values()) {
+    path->second = false;
   }
+
+  repaint();
 }
 
 /** Clears the list of routers and removes all the data on the map */
 void
 TorMapWidget::clear()
 {
-  /* Clear out all the router points and free their memory */
-  foreach (QString router, _routers.keys()) {
-    delete _routers.take(router);
+  foreach (QString id, _routers.keys()) {
+    removePlaceMarkKey(id);
   }
-  /* Clear out all the circuit paths and free their memory */
+
   foreach (CircuitId circid, _circuits.keys()) {
-    QPair<QPainterPath*,bool> *circuitPair = _circuits.take(circid);
-    delete circuitPair->first;
-    delete circuitPair;
+    CircuitGeoPath *path = _circuits.take(circid);
+    GeoDataLineString coords = path->first;
+    qDeleteAll(coords.begin(), coords.end());
+    delete path;
   }
+
+  repaint();
 }
-  
-/** Draws the routers and paths onto the map image. */
+ 
+/** Zooms the map to fit entirely within the constraints of the current
+ * viewport size. */
 void
-TorMapWidget::paintImage(QPainter *painter)
+TorMapWidget::zoomToFit()
 {
-  painter->setRenderHint(QPainter::Antialiasing);
-  
-  /* Draw the router points */
-  foreach(QString router, _routers.keys()) {
-    QPair<QPointF,bool> *routerPair = _routers.value(router);
-    painter->setPen((routerPair->second ? PEN_SELECTED : PEN_ROUTER)); 
-    painter->drawPoint(routerPair->first);
-  }
-  /* Draw the circuit paths */
-  foreach(CircuitId circid, _circuits.keys()) {
-    QPair<QPainterPath*,bool> *circuitPair = _circuits.value(circid);
-    painter->setPen((circuitPair->second ? PEN_SELECTED : PEN_CIRCUIT));
-    painter->drawPath(*(circuitPair->first));
-  }
-}
+  int width  = size().width();
+  int height = size().height();
 
-/** Converts world space coordinates into map space coordinates */
-QPointF
-TorMapWidget::toMapSpace(float latitude, float longitude)
-{
-  float width  = MAP_WIDTH;
-  float height = MAP_HEIGHT;
-  float deg = width / 360.0;
-  longitude += MAP_ORIGIN;
+  setRadius(qMin(width, height) / 2);
 
-  float lat;
-  float lon;
-  
-  lat = floor(longitude * (deg * lerp(abs(int(latitude)), plen))
-	      + width/2 + MAP_LEFT);
-  
-  if (latitude < 0) {
-    lon = floor((height/2) + (lerp(abs(int(latitude)), pdfe) * (height/2))
-		+ MAP_TOP);
-  } else {
-    lon = floor((height/2) - (lerp(abs(int(latitude)), pdfe) * (height/2))
-		+ MAP_TOP);
-  }
-
-  return QPointF(lat, lon);
+  /* XXX: Calling setRadius() seems to cause Marble to no longer draw the
+   *      atmosphere. So, re-enable it. */
+  setShowAtmosphere(true);
 }
-  
-/** Linearly interpolates using the values in the Robinson projection table */
-float
-TorMapWidget::lerp(float input, float *table)
-{
-  int x = int(floor(input / 5));
 
-  return ((table[x+1] - table[x]) / 
-	  (((x+1)*5) - (x*5))) * (input - x*5) + table[x];
-}
-
-/** Returns the minimum size of the widget */
-QSize
-TorMapWidget::minimumSizeHint() const
-{
-  return MIN_SIZE;
-}
-
-/** Zooms to fit all currently displayed circuits on the map. If there are no
- * circuits on the map, the viewport will be returned to its default position
- * (zoomed all the way out and centered). */
-void
-TorMapWidget::zoomToFit()
-{
-  QRectF rect = circuitBoundingBox();
-  
-  if (rect.isNull()) {
-    /* If there are no circuits, zoom all the way out */
-    resetZoomPoint();
-    zoom(0.0);
-  } else {
-    /* Zoom in on the displayed circuits */
-    float zoomLevel = 1.0 - qMax(rect.height()/float(MAP_HEIGHT),
-                                 rect.width()/float(MAP_WIDTH));
-    
-    zoom(rect.center().toPoint(), zoomLevel+0.2);
-  }
-}
-
 /** Zoom to the circuit on the map with the given <b>circid</b>. */
 void
 TorMapWidget::zoomToCircuit(const CircuitId &circid)
 {
+#if 0
   if (_circuits.contains(circid)) {
     QPair<QPainterPath*,bool> *pair = _circuits.value(circid);
     QRectF rect = ((QPainterPath *)pair->first)->boundingRect();
@@ -291,35 +249,30 @@
       zoom(rect.center().toPoint(), zoomLevel+0.2);
     }
   }
+#endif
 }
 
 /** Zooms in on the router with the given <b>id</b>. */
 void
 TorMapWidget::zoomToRouter(const QString &id)
 {
-  QPair<QPointF,bool> *routerPair;
-  
   if (_routers.contains(id)) {
-    deselectAll();
-    routerPair = _routers.value(id);
-    routerPair->second = true;  /* Set the router point to "selected" */
-    zoom(routerPair->first.toPoint(), 1.0); 
+    qreal lon, lat;
+    GeoDataCoordinates coords = _routers.value(id);
+    coords.geoCoordinates(lon, lat, GeoDataPoint::Degree);
+
+    zoomView(maximumZoom());
+    centerOn(lon, lat, true);
   }
 }
 
-/** Computes a bounding box around all currently displayed circuit paths on
- * the map. */
-QRectF
-TorMapWidget::circuitBoundingBox()
+/** Paints the current circuits and streams on the image. */
+void
+TorMapWidget::customPaint(GeoPainter *painter)
 {
-  QRectF rect;
-
-  /* Compute the union of bounding rectangles for all circuit paths */
-  foreach (CircuitId circid, _circuits.keys()) {
-    QPair<QPainterPath*,bool> *pair = _circuits.value(circid);
-    QPainterPath *circuit = pair->first;
-    rect = rect.unite(circuit->boundingRect());
+  foreach (CircuitGeoPath *path, _circuits.values()) {
+    painter->setPen(path->second ? CIRCUIT_SELECTED_PEN : CIRCUIT_NORMAL_PEN);
+    painter->drawPolyline(path->first);
   }
-  return rect;
 }
 

Modified: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.h
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.h	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidget.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -19,15 +19,21 @@
 
 #include <QHash>
 #include <QPair>
-#include <QPainter>
 #include <QPainterPath>
+#include <routerdescriptor.h>
 #include <circuit.h>
 #include <stream.h>
+#include <network/geoip.h>
 
-#include "zimageview.h"
+#include <MarbleWidget.h>
+#include <GeoPainter.h>
+#include <GeoDataCoordinates.h>
+#include <GeoDataLineString.h>
 
+typedef QPair<Marble::GeoDataLineString, bool> CircuitGeoPath;
 
-class TorMapWidget : public ZImageView
+
+class TorMapWidget : public Marble::MarbleWidget
 {
   Q_OBJECT
 
@@ -38,15 +44,13 @@
   ~TorMapWidget();
 
   /** Plots the given router on the map using the given coordinates. */
-  void addRouter(const QString &id, float latitude, float longitude);
+  void addRouter(const RouterDescriptor &desc, const GeoIp &geoip);
   /** Plots the given circuit on the map. */
   void addCircuit(const CircuitId &circid, const QStringList &path);
   /** Selects and hightlights a router on the map. */
   void selectRouter(const QString &id);
   /** Selects and highlights a circuit on the map. */
   void selectCircuit(const CircuitId &circid);
-  /** Returns the minimum size of the widget */
-  QSize minimumSizeHint() const;
 
 public slots:
   /** Removes a circuit from the map. */
@@ -55,30 +59,28 @@
   void deselectAll();
   /** Clears the known routers and removes all the data from the map */
   void clear();
-  /** Zooms to fit all currently displayed circuits on the map. */
+  /** Zooms the map to fit entirely within the constraints of the current
+   * viewport size. */
   void zoomToFit();
   /** Zoom to a particular router on the map. */
   void zoomToRouter(const QString &id);
   /** Zoom to the circuit on the map with the given <b>circid</b>. */
   void zoomToCircuit(const CircuitId &circid);
 
+signals:
+  /** Emitted when the user selects a router placemark on the map. <b>id</b>
+   * contain's the selected router's fingerprint. */
+  void displayRouterInfo(const QString &id);
+
 protected:
   /** Paints the current circuits and streams on the image. */
-  virtual void paintImage(QPainter *painter);
+  virtual void customPaint(Marble::GeoPainter *painter);
 
 private:
-  /** Converts world space coordinates into map space coordinates */
-  QPointF toMapSpace(float latitude, float longitude);
-  /** Linearly interpolates using the values in the projection table */
-  float lerp(float input, float *table);
-  /** Computes a bounding box around all currently displayed circuit paths on
-   * the map. */
-  QRectF circuitBoundingBox();
-  
-  /** Stores map locations for tor routers */
-  QHash<QString, QPair<QPointF,bool>* > _routers;
+  /** Stores placemark IDs for Tor routers. */
+  QHash<QString, Marble::GeoDataCoordinates> _routers;
   /** Stores circuit information */
-  QHash<CircuitId, QPair<QPainterPath *,bool>* > _circuits;
+  QHash<CircuitId, CircuitGeoPath*> _circuits;
 };
 
 #endif

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.cpp (from rev 3502, vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,138 @@
+/*
+**  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.
+*/
+
+#include <QTimer>
+#include <QMouseEvent>
+#include <QWheelEvent>
+#include <QPersistentModelIndex>
+
+#include <MarbleWidget.h>
+#include <MarbleMap.h>
+#include <MarbleModel.h>
+#include <ViewParams.h>
+#include <ViewportParams.h>
+
+#include "tormapwidgetinputhandler.h"
+
+using namespace Marble;
+
+
+/** Amount to zoom in or out when responding to mouse double clicks. This
+ * value was taken from MarbleMap.cpp.
+ */
+#define MAP_ZOOM_STEP   40
+
+/** Number of units the mouse must be clicked and dragged before it will
+ * force a map rotation and repaint.
+*/
+#define MIN_DRAG_THRESHOLD 3
+
+
+TorMapWidgetInputHandler::TorMapWidgetInputHandler()
+  : MarbleWidgetInputHandler()
+{
+}
+
+bool
+TorMapWidgetInputHandler::eventFilter(QObject *obj, QEvent *e)
+{
+  Q_UNUSED(obj);
+
+  QWheelEvent *wheelEvent = 0;
+  QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(e);
+
+  switch (e->type()) {
+    case QEvent::MouseButtonPress:
+      _mousePressedX = mouseEvent->x();
+      _mousePressedY = mouseEvent->y();
+      _mousePressedLon = m_widget->centerLongitude();
+      _mousePressedLat = m_widget->centerLatitude();
+
+      if (pointHasFeatures(mouseEvent->pos()))
+        emit featureClicked(mouseEvent->pos(), mouseEvent->button());
+      else
+        m_widget->setCursor(Qt::ClosedHandCursor);
+      break;
+
+    case QEvent::MouseButtonRelease:
+      if (! pointHasFeatures(mouseEvent->pos()))
+        m_widget->setCursor(Qt::OpenHandCursor);
+      else
+        m_widget->setCursor(Qt::PointingHandCursor);
+      break;
+
+    case QEvent::MouseMove:
+      if (mouseEvent->buttons() & Qt::LeftButton) {
+        // Pan the map if the left button is pressed while dragging
+        int dx = mouseEvent->x() - _mousePressedX;
+        int dy = mouseEvent->y() - _mousePressedY;
+
+        if (abs(dx) <= MIN_DRAG_THRESHOLD && abs(dy) <= MIN_DRAG_THRESHOLD)
+          return true;
+        m_widget->setCursor(Qt::ClosedHandCursor);
+
+        qreal dir = 1;
+        if (m_widget->projection() == Spherical) {
+          if (m_widget->map()->viewParams()->viewport()->polarity() > 0) {
+            if (mouseEvent->y() < (-m_widget->northPoleY() + m_widget->height()/2))
+              dir = -1;
+          } else {
+            if (mouseEvent->y() > (+m_widget->northPoleY() + m_widget->height()/2))
+              dir = -1;
+          }
+        }
+
+        qreal radius = (qreal)(m_widget->radius());
+        qreal lon = (qreal)(_mousePressedLon) - 90.0 * dir * dx / radius;
+        qreal lat = (qreal)(_mousePressedLat) + 90.0 * dy / radius;
+        m_widget->centerOn(lon, lat, false);
+
+        return true;
+      } else {
+        // Change the mouse cursor if we're hovering over a relay placemark
+        if (pointHasFeatures(mouseEvent->pos()) > 0)
+          m_widget->setCursor(Qt::PointingHandCursor);
+        else
+          m_widget->setCursor(Qt::OpenHandCursor);
+      }
+      break;
+
+    case QEvent::MouseButtonDblClick:
+      // Adjust the zoom level on the map
+      if (mouseEvent->button() == Qt::LeftButton) {
+        m_widget->zoomViewBy(MAP_ZOOM_STEP);
+        return true;
+      } else if (mouseEvent->button() == Qt::RightButton) {
+        m_widget->zoomViewBy(-MAP_ZOOM_STEP);
+        return true;
+      }
+      break;
+
+    case QEvent::Wheel:
+      // Adjust the zoom level on the map
+      m_widget->setViewContext(Marble::Animation);
+
+      wheelEvent = static_cast<QWheelEvent*>(e);
+      m_widget->zoomViewBy((int)(wheelEvent->delta() / 3));
+      m_mouseWheelTimer->start(400);
+      return true;
+
+    default:
+      break;
+  }
+  return MarbleWidgetInputHandler::eventFilter(obj, e);
+}
+
+bool
+TorMapWidgetInputHandler::pointHasFeatures(const QPoint &point) const
+{
+  return (m_widget->model()->whichFeatureAt(point).size() > 0);
+}
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.h (from rev 3502, vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.h)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetinputhandler.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,55 @@
+/*
+**  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.
+*/
+
+#ifndef _TORMAPWIDGETINPUTHANDLER_H
+#define _TORMAPWIDGETINPUTHANDLER_H
+
+#include <QEvent>
+#include <QObject>
+#include <QPoint>
+
+#include <MarbleWidgetInputHandler.h>
+
+
+class TorMapWidgetInputHandler : public Marble::MarbleWidgetInputHandler
+{
+  Q_OBJECT
+
+public:
+  /** Default constructor.
+   */
+  TorMapWidgetInputHandler();
+
+signals:
+  /** Emitted when the user clicks on a map feature located at <b>point</b>.
+   * <b>button</b> indicates which mouse button was clicked.
+   */
+  void featureClicked(const QPoint &point, Qt::MouseButton button);
+
+protected:
+  /** Filter and handles event <b>e</b> that was sent to widget <b>obj</b>.
+   * <b>obj</b> is always a MarbleWidget object.
+   */
+  virtual bool eventFilter(QObject *obj, QEvent *e);
+
+private:
+  /** Returns true if the map has one or more features located at the screen
+   * position <b>point</b>.
+   */
+  bool pointHasFeatures(const QPoint &point) const;
+
+  int   _mousePressedX;
+  int   _mousePressedY;
+  qreal _mousePressedLon;
+  qreal _mousePressedLat;
+};
+
+#endif
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.cpp (from rev 3502, vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.cpp)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.cpp	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,90 @@
+/*
+**  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 tormapwidgetpopupmenu.cpp
+** \version $Id$
+** \brief Popup menu displayed when the user mouse clicks on a map placemark
+*/
+
+#include <QChar>
+#include <QVector>
+#include <QModelIndex>
+#include <vidalia.h>
+
+#include <MarbleModel.h>
+#include <MarblePlacemarkModel.h>
+
+#include "tormapwidgetpopupmenu.h"
+
+using namespace Marble;
+
+
+TorMapWidgetPopupMenu::TorMapWidgetPopupMenu(TorMapWidget *widget)
+  : QObject(widget),
+    _widget(widget)
+{
+  _leftClickMenu = new QMenu(widget);
+  connect(_leftClickMenu, SIGNAL(triggered(QAction*)),
+          this, SLOT(relaySelected(QAction*)));
+}
+
+void
+TorMapWidgetPopupMenu::featureClicked(const QPoint &pos, Qt::MouseButton btn)
+{
+  switch (btn) {
+    case Qt::LeftButton:
+      featureLeftClicked(pos);
+      break;
+
+    case Qt::RightButton:
+      break;
+
+    default:
+      break;
+  }
+}
+
+void
+TorMapWidgetPopupMenu::featureLeftClicked(const QPoint &pos)
+{
+  QVector<QModelIndex>::const_iterator it;
+  QVector<QModelIndex> features = _widget->model()->whichFeatureAt(pos);
+  QString name, id;
+  int numRelays = 0;
+
+  _leftClickMenu->clear();
+  for (it = features.constBegin(); it != features.constEnd(); ++it) {
+    QChar role = (*it).data(MarblePlacemarkModel::GeoTypeRole).toChar();
+    if (role == '1') {
+      /* Normal Tor Relay */
+      name = (*it).data().toString();
+      id   = (*it).data(MarblePlacemarkModel::DescriptionRole).toString();
+
+      QAction *action = _leftClickMenu->addAction(name);
+      action->setData(id);
+      numRelays++;
+    }
+  }
+
+  if (numRelays == 1)
+    emit displayRouterInfo(id);
+  else if (numRelays > 1)
+    _leftClickMenu->popup(_widget->mapToGlobal(pos));
+}
+
+void
+TorMapWidgetPopupMenu::relaySelected(QAction *action)
+{
+  QString id = action->data().toString();
+  if (! id.isEmpty())
+    emit displayRouterInfo(id);
+}
+

Copied: vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.h (from rev 3502, vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.h)
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.h	                        (rev 0)
+++ vidalia/branches/alt-launcher/src/vidalia/network/tormapwidgetpopupmenu.h	2009-02-02 17:47:07 UTC (rev 3503)
@@ -0,0 +1,81 @@
+/*
+**  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 tormapwidgetpopupmenu.h
+** \version $Id$
+** \brief Popup menu displayed when the user mouse clicks on a map placemark
+*/
+
+#ifndef _TORMAPWIDGETPOPUPMENU_H
+#define _TORMAPWIDGETPOPUPMENU_H
+
+#include <QObject>
+#include <QPoint>
+#include <QString>
+#include <QMenu>
+
+#include "tormapwidget.h"
+
+
+class TorMapWidgetPopupMenu : public QObject
+{
+  Q_OBJECT
+
+public:
+  /** Constructor. <b>widget</b> is the parent map widget on which the popup
+   * menu will be displayed.
+   */
+  TorMapWidgetPopupMenu(TorMapWidget *widget);
+
+public slots:
+  /** Called when the user clicks on one or more map features located at mouse
+   * position <b>pos</b>. <b>button</b> specifies the mouse button clicked.
+   * A popup menu will be displayed depending on which mouse button was
+   * clicked.
+   *
+   * \sa featureLeftClicked
+   */
+  void featureClicked(const QPoint &pos, Qt::MouseButton button);
+
+signals:
+  /** Emitted when the user selects the router placemark whose fingerprint
+   * is <b>id</b>.
+   */
+  void displayRouterInfo(const QString &id);
+
+protected:
+  /** Called when the user left-clicks on one or more placemarks at mouse
+   * position <b>pos</b>. If only one relay placemark exists at <b>pos</b>,
+   * then the displayRouterInfo() signal will be emitted. Otherwise, a
+   * popup menu will be displayed listing all placemarks at this location.
+   *
+   * \sa featureLeftClicked
+   */
+  virtual void featureLeftClicked(const QPoint &pos);
+
+private slots:
+  /** Called when the user selects a relay from the popup menu used to
+   * disambiguate a location with multiple relay placemarks.
+   */
+  void relaySelected(QAction *action);
+
+private:
+  /** The parent map widget on which the popup menu is displayed.
+   */
+  TorMapWidget *_widget;
+
+  /** Menu displayed when the user left-clicks on one or more placemarks.
+   */
+  QMenu *_leftClickMenu;
+};
+
+#endif
+

Copied: vidalia/branches/alt-launcher/src/vidalia/res/22x22/tor-logo.png (from rev 3502, vidalia/trunk/src/vidalia/res/22x22/tor-logo.png)
===================================================================
(Binary files differ)

Copied: vidalia/branches/alt-launcher/src/vidalia/res/64x64/tor-logo.png (from rev 3502, vidalia/trunk/src/vidalia/res/64x64/tor-logo.png)
===================================================================
(Binary files differ)

Copied: vidalia/branches/alt-launcher/src/vidalia/res/icons/placemark-relay.png (from rev 3502, vidalia/trunk/src/vidalia/res/icons/placemark-relay.png)
===================================================================
(Binary files differ)

Modified: vidalia/branches/alt-launcher/src/vidalia/res/icons/vidalia.icns
===================================================================
(Binary files differ)

Modified: vidalia/branches/alt-launcher/src/vidalia/res/vidalia.qrc
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/res/vidalia.qrc	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/res/vidalia.qrc	2009-02-02 17:47:07 UTC (rev 3503)
@@ -18,11 +18,12 @@
         <file>16x16/media-playback-stop.png</file>
         <file>16x16/preferences-desktop-notification.png</file>
         <file>16x16/preferences-system.png</file>
-        <file>16x16/status-green.png</file>
-        <file>16x16/status-orange.png</file>
-        <file>16x16/status-red.png</file>
         <file>16x16/system-help.png</file>
         <file>16x16/system-run.png</file>
+        <file>16x16/tor-off.png</file>
+        <file>16x16/tor-on.png</file>
+        <file>16x16/tor-starting.png</file>
+        <file>16x16/tor-stopping.png</file>
         <file>16x16/utilities-log-viewer.png</file>
         <file>16x16/utilities-system-monitor.png</file>
         <file>16x16/view-media-artist.png</file>
@@ -41,10 +42,11 @@
         <file>22x22/list-remove.png</file>
         <file>22x22/page-zoom.png</file>
         <file>22x22/preferences-system.png</file>
-        <file>22x22/status-green.png</file>
-        <file>22x22/status-orange.png</file>
-        <file>22x22/status-red.png</file>
         <file>22x22/system-help.png</file>
+        <file>22x22/tor-off.png</file>
+        <file>22x22/tor-on.png</file>
+        <file>22x22/tor-starting.png</file>
+        <file>22x22/tor-stopping.png</file>
         <file>22x22/utilities-system-monitor.png</file>
     </qresource>
     <qresource prefix="/images">
@@ -68,11 +70,13 @@
         <file>32x32/preferences-system-network.png</file>
         <file>32x32/preferences-system-network-sharing.png</file>
         <file>32x32/services.png</file>
-        <file>32x32/status-green.png</file>
-        <file>32x32/status-orange.png</file>
-        <file>32x32/status-red.png</file>
         <file>32x32/system-help.png</file>
         <file>32x32/system-software-update.png</file>
+        <file>32x32/tor-logo.png</file>
+        <file>32x32/tor-off.png</file>
+        <file>32x32/tor-on.png</file>
+        <file>32x32/tor-starting.png</file>
+        <file>32x32/tor-stopping.png</file>
         <file>32x32/utilities-log-viewer.png</file>
         <file>32x32/utilities-system-monitor.png</file>
         <file>32x32/view-refresh.png</file>
@@ -89,15 +93,15 @@
         <file>48x48/modem.png</file>
         <file>48x48/network-workgroup.png</file>
         <file>48x48/preferences-system-network-sharing.png</file>
-        <file>48x48/status-green.png</file>
-        <file>48x48/status-orange.png</file>
-        <file>48x48/status-red.png</file>
+        <file>48x48/tor-off.png</file>
+        <file>48x48/tor-on.png</file>
+        <file>48x48/tor-starting.png</file>
+        <file>48x48/tor-stopping.png</file>
         <file>48x48/system-software-update.png</file>
-        <file>48x48/vidalia.png</file>
         <file>48x48/view-media-artist.png</file>
     </qresource>
     <qresource prefix="/images">
-        <file>128x128/vidalia-logo.png</file>
+        <file>128x128/tor-logo.png</file>
     </qresource>
     <qresource prefix="/images">
         <file>icons/node-unresponsive.png</file>
@@ -106,6 +110,7 @@
         <file>icons/node-bw-low.png</file>
         <file>icons/node-bw-med.png</file>
         <file>icons/node-bw-high.png</file>
+        <file>icons/placemark-relay.png</file>
     </qresource>
     <qresource prefix="/images">
         <file>flags/ae.png</file>

Modified: vidalia/branches/alt-launcher/src/vidalia/vidalia.cpp
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/vidalia.cpp	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/vidalia.cpp	2009-02-02 17:47:07 UTC (rev 3503)
@@ -26,13 +26,16 @@
 #include <stringutil.h>
 #include <html.h>
 #include <stdlib.h>
+#include "config.h"
+#include "vidalia.h"
 
 #ifdef Q_OS_MACX
 #include <Carbon/Carbon.h>
 #endif
+#ifdef USE_MARBLE
+#include <MarbleDirs.h>
+#endif
 
-#include "vidalia.h"
-
 /* Available command-line arguments. */
 #define ARG_LANGUAGE   "lang"     /**< Argument specifying language.    */
 #define ARG_GUISTYLE   "style"    /**< Argument specfying GUI style.    */
@@ -119,6 +122,11 @@
 
   /* Creates a TorControl object, used to talk to Tor. */
   _torControl = new TorControl();
+
+#ifdef USE_MARBLE
+  /* Tell Marble where to stash its generated data */
+  Marble::MarbleDirs::setMarbleDataPath(dataDirectory());
+#endif
 }
 
 /** Destructor */

Modified: vidalia/branches/alt-launcher/src/vidalia/vidalia.desktop
===================================================================
--- vidalia/branches/alt-launcher/src/vidalia/vidalia.desktop	2009-02-02 17:32:32 UTC (rev 3502)
+++ vidalia/branches/alt-launcher/src/vidalia/vidalia.desktop	2009-02-02 17:47:07 UTC (rev 3503)
@@ -2,7 +2,7 @@
 Type=Application
 Exec=vidalia
 Name=Vidalia
-Icon=vidalia.png
+Icon=vidalia
 GenericName=Tor GUI
 Terminal=false
 Categories=Network;Qt