[vidalia/alpha] Implement circuit clasification inside the Network Map

commit df79f222a6412c9abf337ff3d946cfeed3461ad4 Author: Tomás Touceda <chiiph@torproject.org> Date: Thu Mar 15 10:12:03 2012 -0300 Implement circuit clasification inside the Network Map Also, remove some whitespace --- src/torcontrol/Circuit.cpp | 80 +++++++- src/torcontrol/Circuit.h | 52 +++++- src/torcontrol/TorControl.cpp | 6 +- src/vidalia/network/GeoIpResolver.cpp | 8 +- src/vidalia/network/NetViewer.cpp | 36 +++-- src/vidalia/network/NetViewer.ui | 326 ++++++++++++++++++------------- src/vidalia/network/TorMapImageView.cpp | 42 ++-- 7 files changed, 361 insertions(+), 189 deletions(-) diff --git a/src/torcontrol/Circuit.cpp b/src/torcontrol/Circuit.cpp index 3b6cb80..a15ddd6 100644 --- a/src/torcontrol/Circuit.cpp +++ b/src/torcontrol/Circuit.cpp @@ -1,36 +1,44 @@ /* ** 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 +** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. 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 Circuit.cpp ** \brief Object representing a Tor circuit */ #include "tcglobal.h" #include "Circuit.h" +#include "stringutil.h" #include <QStringList> #include <QRegExp> +#include <QDebug> /** Default constructor. */ Circuit::Circuit() -{ - _status = Unknown; - _isValid = false; -} + : _status(Unknown), + _isValid(false), + _buildFlags(None), + _purpose(General) +{} /** Parses the string given in Tor control protocol format for a circuit. The * format is: - * - * CircuitID SP CircStatus [SP Path] + * + * CircuitID SP CircStatus [SP Path] + * [SP "BUILD_FLAGS=" BuildFlags] [SP "PURPOSE=" Purpose] + * [SP "HS_STATE=" HSState] [SP "REND_QUERY=" HSAddress] + * [SP "TIME_CREATED=" TimeCreated] + * [SP "REASON=" Reason [SP "REMOTE_REASON=" Reason]] CRLF + * * * If the status is "LAUNCHED", the Path is empty. Server names in the path * must follow Tor's VERBOSE_NAMES format. @@ -59,15 +67,65 @@ Circuit::Circuit(const QString &circuit) } } + if(parts.size() > 3) { + parts.removeFirst(); // remove id + parts.removeFirst(); // remove status + parts.removeFirst(); // remove path + + bool ok; + QHash<QString,QString> rest = string_parse_keyvals(parts.join(" "), &ok); + foreach(const QString key, rest.keys()) { + if(key.compare("BUILD_FLAGS", Qt::CaseInsensitive) == 0) { + _buildFlags = None; + foreach(const QString flag, rest.value(key).split(",")) + _buildFlags |= flagValue(flag); + } else if(key.compare("PURPOSE", Qt::CaseInsensitive) == 0) { + _purpose = purposeValue(rest.value(key)); + } + } + } + _isValid = true; } return; - + err: tc::warn("Improperly formatted circuit: '%1'").arg(circuit); _isValid = false; } +Circuit::BuildFlag +Circuit::flagValue(const QString &flag) const +{ + if (!flag.compare("ONEHOP_TUNNEL", Qt::CaseInsensitive)) + return OneHopTunnel; + if (!flag.compare("IS_INTERNAL", Qt::CaseInsensitive)) + return IsInternal; + if (!flag.compare("NEED_CAPACITY", Qt::CaseInsensitive)) + return NeedCapacity; + if (!flag.compare("NEED_UPTIME", Qt::CaseInsensitive)) + return NeedUptime; + return None; +} + +Circuit::Purpose +Circuit::purposeValue(const QString &purpose) const +{ + if (!purpose.compare("CONTROLLER", Qt::CaseInsensitive)) + return Controller; + if (!purpose.compare("HS_CLIENT_INTRO", Qt::CaseInsensitive)) + return HsClientIntro; + if (!purpose.compare("HS_CLIENT_REND", Qt::CaseInsensitive)) + return HsClientRend; + if (!purpose.compare("HS_SERVICE_INTRO", Qt::CaseInsensitive)) + return HsServiceIntro; + if (!purpose.compare("HS_SERVICE_REND", Qt::CaseInsensitive)) + return HsServiceRend; + if (!purpose.compare("TESTING", Qt::CaseInsensitive)) + return Testing; + return General; +} + /** Returns true iff <b>circId</b> consists of only between 1 and 16 * (inclusive) ASCII-encoded letters and numbers. */ bool diff --git a/src/torcontrol/Circuit.h b/src/torcontrol/Circuit.h index 33f12ef..831816a 100644 --- a/src/torcontrol/Circuit.h +++ b/src/torcontrol/Circuit.h @@ -1,10 +1,10 @@ /* ** 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 +** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, +** including this file, may be copied, modified, propagated, or distributed ** except according to the terms described in the LICENSE file. */ @@ -39,14 +39,35 @@ public: Closed /**< Circuit closed (was built) */ }; + /** Build flags for circuits */ + enum BuildFlag { + None = 0x0000, + OneHopTunnel = 0x0001, + IsInternal = 0x0002, + NeedCapacity = 0x0004, + NeedUptime = 0x0008, + }; + Q_DECLARE_FLAGS(BuildFlags, BuildFlag) + + /** Purpose for a circuit */ + enum Purpose { + General = 0, + HsClientIntro, + HsClientRend, + HsServiceIntro, + HsServiceRend, + Testing, + Controller + }; + /** Default constructor. */ Circuit(); - /** Constructor. */ + /** Constructor. */ Circuit(const CircuitId &circuit); - + /** Returns true if this circuit is valid. */ bool isValid() const { return _isValid; } - + /** Returns the ID for this circuit */ CircuitId id() const { return _circId; } /** Returns the status of this circuit */ @@ -60,6 +81,11 @@ public: /** Returns the circuit's path as an ordered list of router fingerprints. */ QStringList routerIDs() const { return _ids; } + /** Returns the circuit's build flags */ + BuildFlags buildFlags() const { return _buildFlags; } + /** Returns the circuit's purpose */ + Purpose purpose() const { return _purpose; } + /** Converts a string description of a circuit's status to an enum value */ static Status toStatus(const QString &strStatus); @@ -73,6 +99,18 @@ private: QStringList _names; /**< Nicknames of the routers in the circuit. */ QStringList _ids; /**< IDs of the routers in the circuit. */ bool _isValid; + + BuildFlags _buildFlags; + Purpose _purpose; + + /** Returns a BuildFlag enum value for the given router status + * <b>flag</b>. If <b>flag</b> is not recognized, then <i>None</i> + * is returned. */ + BuildFlag flagValue(const QString &flag) const; + /** Returns a Purpose enum value for the given router status + * <b>purpose</b>. If <b>purpose</b> is not recognized, then + * <i>General</i> is returned. */ + Purpose purposeValue(const QString &purpose) const; }; Q_DECLARE_METATYPE(Circuit); @@ -80,5 +118,7 @@ Q_DECLARE_METATYPE(Circuit); /** A collection of circuits. */ typedef QList<Circuit> CircuitList; +Q_DECLARE_OPERATORS_FOR_FLAGS(Circuit::BuildFlags) + #endif diff --git a/src/torcontrol/TorControl.cpp b/src/torcontrol/TorControl.cpp index 9cdf6ad..29d544f 100644 --- a/src/torcontrol/TorControl.cpp +++ b/src/torcontrol/TorControl.cpp @@ -3,8 +3,8 @@ ** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, +** including this file, may be copied, modified, propagated, or distributed ** except according to the terms described in the LICENSE file. */ @@ -906,7 +906,7 @@ TorControl::loadConf(const QString &contents, QString *errmsg) { ControlCommand cmd("+LOADCONF"); ControlReply reply; - + cmd.addArgument(contents + "."); return send(cmd, reply, errmsg); } diff --git a/src/vidalia/network/GeoIpResolver.cpp b/src/vidalia/network/GeoIpResolver.cpp index f2c5100..9752dd9 100644 --- a/src/vidalia/network/GeoIpResolver.cpp +++ b/src/vidalia/network/GeoIpResolver.cpp @@ -3,8 +3,8 @@ ** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, +** including this file, may be copied, modified, propagated, or distributed ** except according to the terms described in the LICENSE file. */ @@ -64,7 +64,7 @@ GeoIpResolver::resolveUsingLocalDatabase(const QHostAddress &ip) QString countryCode = _database.countryCodeByAddr(ip); if (! countryCode.isEmpty()) { QPair<float,float> coords = CountryInfo::countryLocation(countryCode); - return GeoIpRecord(ip, coords.first, coords.second, + return GeoIpRecord(ip, coords.first, coords.second, CountryInfo::countryName(countryCode), countryCode); } @@ -81,6 +81,6 @@ GeoIpResolver::resolve(const QHostAddress &ip) if (_useLocalDatabase) return resolveUsingLocalDatabase(ip); #endif - return resolveUsingTor(ip); + return resolveUsingTor(ip); } diff --git a/src/vidalia/network/NetViewer.cpp b/src/vidalia/network/NetViewer.cpp index 8ff6b32..052bc90 100644 --- a/src/vidalia/network/NetViewer.cpp +++ b/src/vidalia/network/NetViewer.cpp @@ -3,8 +3,8 @@ ** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, +** including this file, may be copied, modified, propagated, or distributed ** except according to the terms described in the LICENSE file. */ @@ -110,7 +110,7 @@ NetViewer::NetViewer(QWidget *parent) * needs to be called to get rid of any descriptors that were removed. */ _refreshTimer.setInterval(60*60*1000); connect(&_refreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); - + /* Connect the necessary slots and signals */ connect(ui.actionHelp, SIGNAL(triggered()), this, SLOT(help())); connect(ui.actionRefresh, SIGNAL(triggered()), this, SLOT(refresh())); @@ -229,7 +229,7 @@ NetViewer::refresh() /* Ok, they can refresh again. */ ui.actionRefresh->setEnabled(true); -} +} /** Clears the lists and the map */ void @@ -246,7 +246,7 @@ NetViewer::clear() ui.textRouterInfo->clear(); } -/** Called when the search of a router is triggered by the signal +/** Called when the search of a router is triggered by the signal * returnPressed from the search field. */ void NetViewer::onRouterSearch() @@ -287,7 +287,19 @@ void NetViewer::addCircuit(const Circuit &circuit) { /* Add the circuit to the list of all current circuits */ - ui.treeCircuitList->addCircuit(circuit); + if(circuit.purpose() == Circuit::General or + circuit.purpose() == Circuit::Controller or + circuit.purpose() == Circuit::Testing) { + if((circuit.buildFlags() & Circuit::OneHopTunnel) or + (circuit.buildFlags() & Circuit::IsInternal)) { + ui.treeInternalCircuitList->addCircuit(circuit); + } else { + ui.treeCircuitList->addCircuit(circuit); + } + } else { + ui.treeHSCircuitList->addCircuit(circuit); + } + /* Plot the circuit on the map */ _map->addCircuit(circuit.id(), circuit.routerIDs()); } @@ -301,7 +313,7 @@ NetViewer::addStream(const Stream &stream) if (stream.status() == Stream::New) { QString target = stream.targetAddress(); if (! QHostAddress(target).isNull() && _addressMap.isMapped(target)) { - /* Replace the IP address in the stream event with the original + /* Replace the IP address in the stream event with the original * hostname */ ui.treeCircuitList->addStream( Stream(stream.id(), stream.status(), stream.circuitId(), @@ -332,11 +344,11 @@ void NetViewer::preLoadNetworkStatus() { NetworkStatus networkStatus = _torControl->getNetworkStatus(); - + foreach(RouterStatus rs, networkStatus) { if (!rs.isRunning()) continue; - + RouterDescriptor rd = _torControl->getRouterDescriptor(rs.id()); if(_torControl->useMicrodescriptors()) { rd.appendRouterStatusInfo(rs); @@ -346,7 +358,7 @@ NetViewer::preLoadNetworkStatus() QCoreApplication::processEvents(); } - + _it = _routers.constBegin(); QTimer::singleShot(200, this, SLOT(loadNetworkStatus())); } @@ -448,13 +460,13 @@ NetViewer::routerSelected(const QList<RouterDescriptor> &routers) // _map->selectRouter(routers[0].id()); } -/** Called when the user selects a router on the network map. Displays a +/** 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(_map->isFullScreen() ? static_cast<QWidget*>(_map) + RouterInfoDialog dlg(_map->isFullScreen() ? static_cast<QWidget*>(_map) : static_cast<QWidget*>(this)); /* Fetch the specified router's descriptor */ diff --git a/src/vidalia/network/NetViewer.ui b/src/vidalia/network/NetViewer.ui index 11fd0a2..b7bc0e9 100644 --- a/src/vidalia/network/NetViewer.ui +++ b/src/vidalia/network/NetViewer.ui @@ -6,50 +6,20 @@ <rect> <x>0</x> <y>0</y> - <width>694</width> - <height>552</height> + <width>736</width> + <height>630</height> </rect> </property> <property name="windowTitle"> <string>Network Map</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> + <layout class="QVBoxLayout" name="verticalLayout_7"> <item> <layout class="QHBoxLayout" name="horizontalLayout"/> </item> <item> - <widget class="QSplitter" name="splitter"> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="childrenCollapsible"> - <bool>false</bool> - </property> - <widget class="QSplitter" name="splitter4"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>1</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>175</width> - <height>0</height> - </size> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="childrenCollapsible"> - <bool>false</bool> - </property> + <layout class="QGridLayout" name="gridLayout_6"> + <item row="0" column="1"> <widget class="QLineEdit" name="lineRouterSearch"> <property name="minimumSize"> <size> @@ -64,6 +34,8 @@ </size> </property> </widget> + </item> + <item row="1" column="1"> <widget class="RouterListWidget" name="treeRouterList"> <property name="sizePolicy"> <sizepolicy hsizetype="Preferred" vsizetype="Expanding"> @@ -111,23 +83,8 @@ </property> </column> </widget> - </widget> - <widget class="QSplitter" name="splitter3"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>100</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="orientation"> - <enum>Qt::Vertical</enum> - </property> - <property name="childrenCollapsible"> - <bool>false</bool> - </property> + </item> + <item row="0" column="0" rowspan="2"> <widget class="QFrame" name="frmMap"> <property name="sizePolicy"> <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> @@ -150,93 +107,198 @@ <property name="frameShadow"> <enum>QFrame::Raised</enum> </property> - <layout class="QHBoxLayout"> - <property name="spacing"> - <number>6</number> - </property> - <property name="margin"> - <number>9</number> - </property> + <layout class="QGridLayout" name="gridLayout_5"> + <item row="0" column="0"> + <layout class="QGridLayout" name="gridLayout"/> + </item> + </layout> + </widget> + </item> + </layout> + </item> + <item> + <widget class="QSplitter" name="splitter"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>2</number> + </property> + <widget class="QWidget" name="tab"> + <attribute name="title"> + <string>Exit circuits</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> - <layout class="QGridLayout" name="gridLayout"> - <property name="margin"> - <number>0</number> - </property> - <property name="spacing"> - <number>6</number> - </property> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="CircuitListWidget" name="treeCircuitList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>100</horstretch> + <verstretch>100</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="statusTip"> + <string/> + </property> + <property name="sortingEnabled"> + <bool>false</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <column> + <property name="text"> + <string>Connection</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + </widget> + </item> </layout> </item> </layout> </widget> - <widget class="QSplitter" name="splitter2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Minimum"> - <horstretch>100</horstretch> - <verstretch>1</verstretch> - </sizepolicy> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::NoContextMenu</enum> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="childrenCollapsible"> - <bool>false</bool> - </property> - <widget class="CircuitListWidget" name="treeCircuitList"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>100</horstretch> - <verstretch>100</verstretch> - </sizepolicy> - </property> - <property name="minimumSize"> - <size> - <width>300</width> - <height>0</height> - </size> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::CustomContextMenu</enum> - </property> - <property name="statusTip"> - <string/> - </property> - <property name="sortingEnabled"> - <bool>false</bool> - </property> - <property name="columnCount"> - <number>2</number> - </property> - <column> - <property name="text"> - <string>Connection</string> - </property> - </column> - <column> - <property name="text"> - <string>Status</string> - </property> - </column> - </widget> - <widget class="RouterDescriptorView" name="textRouterInfo"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> - <horstretch>100</horstretch> - <verstretch>100</verstretch> - </sizepolicy> - </property> - <property name="contextMenuPolicy"> - <enum>Qt::DefaultContextMenu</enum> - </property> - <property name="readOnly"> - <bool>true</bool> - </property> - </widget> + <widget class="QWidget" name="tab_2"> + <attribute name="title"> + <string>Internal circuits</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_4"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_3"> + <item> + <widget class="CircuitListWidget" name="treeInternalCircuitList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>100</horstretch> + <verstretch>100</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="statusTip"> + <string/> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="sortingEnabled"> + <bool>false</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <column> + <property name="text"> + <string>Connection</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + </widget> + </item> + </layout> + </item> + </layout> + </widget> + <widget class="QWidget" name="tab_3"> + <attribute name="title"> + <string>Hidden Service circuits</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_6"> + <item> + <layout class="QVBoxLayout" name="verticalLayout_5"> + <item> + <widget class="CircuitListWidget" name="treeHSCircuitList"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>100</horstretch> + <verstretch>100</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>300</width> + <height>0</height> + </size> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::CustomContextMenu</enum> + </property> + <property name="statusTip"> + <string/> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="frameShadow"> + <enum>QFrame::Sunken</enum> + </property> + <property name="sortingEnabled"> + <bool>false</bool> + </property> + <property name="columnCount"> + <number>2</number> + </property> + <column> + <property name="text"> + <string>Connection</string> + </property> + </column> + <column> + <property name="text"> + <string>Status</string> + </property> + </column> + </widget> + </item> + </layout> + </item> + </layout> </widget> </widget> + <widget class="RouterDescriptorView" name="textRouterInfo"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>100</horstretch> + <verstretch>100</verstretch> + </sizepolicy> + </property> + <property name="contextMenuPolicy"> + <enum>Qt::DefaultContextMenu</enum> + </property> + <property name="readOnly"> + <bool>true</bool> + </property> + </widget> </widget> </item> </layout> diff --git a/src/vidalia/network/TorMapImageView.cpp b/src/vidalia/network/TorMapImageView.cpp index 6c04d89..aac70d0 100644 --- a/src/vidalia/network/TorMapImageView.cpp +++ b/src/vidalia/network/TorMapImageView.cpp @@ -3,8 +3,8 @@ ** 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.torproject.org/projects/vidalia.html. No part of Vidalia, -** including this file, may be copied, modified, propagated, or distributed +** http://www.torproject.org/projects/vidalia.html. No part of Vidalia, +** including this file, may be copied, modified, propagated, or distributed ** except according to the terms described in the LICENSE file. */ @@ -59,7 +59,7 @@ static float plen[] = { 0.6213, 0.5722, 0.5322 }; -/** Distance of corresponding parallel from equator */ +/** 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, @@ -88,7 +88,7 @@ TorMapImageView::addRouter(const RouterDescriptor &desc, const GeoIpRecord &geoi { 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; @@ -101,25 +101,25 @@ 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 */ + + /* 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 @@ -156,7 +156,7 @@ TorMapImageView::selectRouter(const QString &id) repaint(); } -/** Selects and highlights the circuit with the id <b>circid</b> +/** Selects and highlights the circuit with the id <b>circid</b> * on the map. */ void TorMapImageView::selectCircuit(const CircuitId &circid) @@ -199,17 +199,17 @@ TorMapImageView::clear() 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->setPen((routerPair->second ? PEN_SELECTED : PEN_ROUTER)); painter->drawPoint(routerPair->first); } /* Draw the circuit paths */ @@ -231,10 +231,10 @@ TorMapImageView::toMapSpace(float latitude, float longitude) 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); @@ -245,14 +245,14 @@ TorMapImageView::toMapSpace(float latitude, float longitude) 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]) / + return ((table[x+1] - table[x]) / (((x+1)*5) - (x*5))) * (input - x*5) + table[x]; } @@ -270,7 +270,7 @@ void TorMapImageView::zoomToFit() { QRectF rect = circuitBoundingBox(); - + if (rect.isNull()) { /* If there are no circuits, zoom all the way out */ resetZoomPoint(); @@ -279,7 +279,7 @@ TorMapImageView::zoomToFit() /* 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); } } @@ -305,12 +305,12 @@ 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); + zoom(routerPair->first.toPoint(), 1.0); } }
participants (1)
-
chiiph@torproject.org