[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[vidalia-svn] r3485: Merge the Marble branch to trunk. It's still optional and di (in vidalia/trunk: . cmake debian pkg/win32 src/common src/torcontrol src/vidalia src/vidalia/network src/vidalia/res src/vidalia/res/icons)
Author: edmanm
Date: 2009-01-30 23:22:30 -0500 (Fri, 30 Jan 2009)
New Revision: 3485
Added:
vidalia/trunk/cmake/FindMarble.cmake
vidalia/trunk/src/vidalia/network/routerinfodialog.cpp
vidalia/trunk/src/vidalia/network/routerinfodialog.h
vidalia/trunk/src/vidalia/network/routerinfodialog.ui
vidalia/trunk/src/vidalia/network/tormapimageview.cpp
vidalia/trunk/src/vidalia/network/tormapimageview.h
vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.cpp
vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.h
vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.cpp
vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.h
vidalia/trunk/src/vidalia/res/icons/placemark-relay.png
Modified:
vidalia/trunk/
vidalia/trunk/CMakeLists.txt
vidalia/trunk/INSTALL
vidalia/trunk/config.h.in
vidalia/trunk/debian/faq
vidalia/trunk/pkg/win32/vidalia.wxs.in
vidalia/trunk/src/common/stringutil.cpp
vidalia/trunk/src/common/stringutil.h
vidalia/trunk/src/torcontrol/torcontrol.cpp
vidalia/trunk/src/torcontrol/torcontrol.h
vidalia/trunk/src/vidalia/CMakeLists.txt
vidalia/trunk/src/vidalia/network/circuitlistwidget.cpp
vidalia/trunk/src/vidalia/network/netviewer.cpp
vidalia/trunk/src/vidalia/network/netviewer.h
vidalia/trunk/src/vidalia/network/routerdescriptorview.cpp
vidalia/trunk/src/vidalia/network/routerdescriptorview.h
vidalia/trunk/src/vidalia/network/routerlistitem.h
vidalia/trunk/src/vidalia/network/tormapwidget.cpp
vidalia/trunk/src/vidalia/network/tormapwidget.h
vidalia/trunk/src/vidalia/res/vidalia.qrc
vidalia/trunk/src/vidalia/vidalia.cpp
Log:
Merge the Marble branch to trunk. It's still optional and disabled by
default.
Property changes on: vidalia/trunk
___________________________________________________________________
Added: svn:mergeinfo
+ /vidalia/branches/marble:3435-3484
Modified: vidalia/trunk/CMakeLists.txt
===================================================================
--- vidalia/trunk/CMakeLists.txt 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/CMakeLists.txt 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/INSTALL
===================================================================
--- vidalia/trunk/INSTALL 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/INSTALL 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/cmake/FindMarble.cmake (from rev 3484, vidalia/branches/marble/cmake/FindMarble.cmake)
===================================================================
--- vidalia/trunk/cmake/FindMarble.cmake (rev 0)
+++ vidalia/trunk/cmake/FindMarble.cmake 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/config.h.in
===================================================================
--- vidalia/trunk/config.h.in 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/config.h.in 2009-01-31 04:22:30 UTC (rev 3485)
@@ -30,5 +30,7 @@
#cmakedefine USE_AUTOUPDATE
+#cmakedefine USE_MARBLE
+
#endif
Property changes on: vidalia/trunk/debian/faq
___________________________________________________________________
Deleted: svn:mergeinfo
-
Modified: vidalia/trunk/pkg/win32/vidalia.wxs.in
===================================================================
--- vidalia/trunk/pkg/win32/vidalia.wxs.in 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/pkg/win32/vidalia.wxs.in 2009-01-31 04:22:30 UTC (rev 3485)
@@ -19,62 +19,192 @@
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" />
+ </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 +239,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 +253,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/trunk/src/common/stringutil.cpp
===================================================================
--- vidalia/trunk/src/common/stringutil.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/common/stringutil.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/common/stringutil.h
===================================================================
--- vidalia/trunk/src/common/stringutil.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/common/stringutil.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/torcontrol/torcontrol.cpp
===================================================================
--- vidalia/trunk/src/torcontrol/torcontrol.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/torcontrol/torcontrol.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -848,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/trunk/src/torcontrol/torcontrol.h
===================================================================
--- vidalia/trunk/src/torcontrol/torcontrol.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/torcontrol/torcontrol.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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. */
Modified: vidalia/trunk/src/vidalia/CMakeLists.txt
===================================================================
--- vidalia/trunk/src/vidalia/CMakeLists.txt 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/CMakeLists.txt 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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
@@ -147,21 +165,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)
@@ -214,6 +251,7 @@
help/browser/helpbrowser.ui
log/messagelog.ui
network/netviewer.ui
+ network/routerinfodialog.ui
)
if (USE_MINIUPNPC)
@@ -245,6 +283,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 +338,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 +423,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}
@@ -320,4 +457,3 @@
DESTINATION share/icons/hicolor/22x22/apps)
endif(NOT WIN32 AND NOT APPLE)
-
Modified: vidalia/trunk/src/vidalia/network/circuitlistwidget.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/circuitlistwidget.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/circuitlistwidget.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/netviewer.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/netviewer.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/netviewer.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/netviewer.h
===================================================================
--- vidalia/trunk/src/vidalia/network/netviewer.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/netviewer.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerdescriptorview.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/routerdescriptorview.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/routerdescriptorview.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerdescriptorview.h
===================================================================
--- vidalia/trunk/src/vidalia/network/routerdescriptorview.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/routerdescriptorview.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerinfodialog.cpp (from rev 3484, vidalia/branches/marble/src/vidalia/network/routerinfodialog.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/routerinfodialog.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/routerinfodialog.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerinfodialog.h (from rev 3484, vidalia/branches/marble/src/vidalia/network/routerinfodialog.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/routerinfodialog.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/routerinfodialog.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerinfodialog.ui (from rev 3484, vidalia/branches/marble/src/vidalia/network/routerinfodialog.ui)
===================================================================
--- vidalia/trunk/src/vidalia/network/routerinfodialog.ui (rev 0)
+++ vidalia/trunk/src/vidalia/network/routerinfodialog.ui 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/routerlistitem.h
===================================================================
--- vidalia/trunk/src/vidalia/network/routerlistitem.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/routerlistitem.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapimageview.cpp (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapimageview.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapimageview.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapimageview.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapimageview.h (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapimageview.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapimageview.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapimageview.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapwidget.cpp
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidget.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/tormapwidget.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -15,59 +15,38 @@
*/
#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)
-
-/** 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 */
TorMapWidget::TorMapWidget(QWidget *parent)
-: ZImageView(parent)
+ : MarbleWidget(parent)
{
- QImage map(IMG_WORLD_MAP);
- setImage(map);
+ setMapThemeId("earth/srtm/srtm.dgml");
+ setShowScaleBar(false);
+ setShowCrosshairs(false);
+ setAnimationsEnabled(true);
+ setCursor(Qt::OpenHandCursor);
+
+ TorMapWidgetInputHandler *handler = new TorMapWidgetInputHandler();
+ TorMapWidgetPopupMenu *popupMenu = new TorMapWidgetPopupMenu(this);
+
+ connect(handler, SIGNAL(featureClicked(QPoint,Qt::MouseButton)),
+ popupMenu, SLOT(featureClicked(QPoint,Qt::MouseButton)));
+ connect(popupMenu, SIGNAL(displayRouterInfo(QString)),
+ this, SIGNAL(displayRouterInfo(QString)));
+
+ setInputHandler(handler);
}
/** Destructor */
@@ -78,75 +57,105 @@
/** 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);
-
- /* 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));
+ QString kml;
+ qreal lon = geoip.longitude();
+ qreal lat = geoip.latitude();
+
+ 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(desc.observedBandwidth()));
+ 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 +164,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 +175,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 +238,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/trunk/src/vidalia/network/tormapwidget.h
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidget.h 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/network/tormapwidget.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapwidgetinputhandler.cpp (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapwidgetinputhandler.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapwidgetinputhandler.h (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapwidgetinputhandler.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapwidgetinputhandler.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/network/tormapwidgetpopupmenu.cpp (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapwidgetpopupmenu.cpp)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.cpp (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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 <QPersistentModelIndex>
+#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<QPersistentModelIndex>::const_iterator it;
+ QVector<QPersistentModelIndex> 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/trunk/src/vidalia/network/tormapwidgetpopupmenu.h (from rev 3484, vidalia/branches/marble/src/vidalia/network/tormapwidgetpopupmenu.h)
===================================================================
--- vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.h (rev 0)
+++ vidalia/trunk/src/vidalia/network/tormapwidgetpopupmenu.h 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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/trunk/src/vidalia/res/icons/placemark-relay.png (from rev 3484, vidalia/branches/marble/src/vidalia/res/icons/placemark-relay.png)
===================================================================
(Binary files differ)
Modified: vidalia/trunk/src/vidalia/res/vidalia.qrc
===================================================================
--- vidalia/trunk/src/vidalia/res/vidalia.qrc 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/res/vidalia.qrc 2009-01-31 04:22:30 UTC (rev 3485)
@@ -106,6 +106,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/trunk/src/vidalia/vidalia.cpp
===================================================================
--- vidalia/trunk/src/vidalia/vidalia.cpp 2009-01-31 03:39:39 UTC (rev 3484)
+++ vidalia/trunk/src/vidalia/vidalia.cpp 2009-01-31 04:22:30 UTC (rev 3485)
@@ -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 */