Vidalia 0.2.12

RouterListItem.cpp

Go to the documentation of this file.
00001 /*
00002 **  This file is part of Vidalia, and is subject to the license terms in the
00003 **  LICENSE file, found in the top level directory of this distribution. If you
00004 **  did not receive the LICENSE file with this file, you may obtain it from the
00005 **  Vidalia source package distributed by the Vidalia Project at
00006 **  http://www.vidalia-project.net/. No part of Vidalia, including this file,
00007 **  may be copied, modified, propagated, or distributed except according to the
00008 **  terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file RouterListItem.cpp
00013 ** \brief Item representing a single router and status in a RouterListWidget
00014 */
00015 
00016 #include "RouterListItem.h"
00017 #include "RouterListWidget.h"
00018 
00019 #include <QHeaderView>
00020 
00021 #define STATUS_COLUMN   (RouterListWidget::StatusColumn)
00022 #define COUNTRY_COLUMN  (RouterListWidget::CountryColumn)
00023 #define NAME_COLUMN     (RouterListWidget::NameColumn)
00024 
00025 #define IMG_NODE_OFFLINE    ":/images/icons/node-unresponsive.png"
00026 #define IMG_NODE_SLEEPING   ":/images/icons/node-hibernating.png"
00027 #define IMG_NODE_NO_BW      ":/images/icons/node-bw-none.png"
00028 #define IMG_NODE_LOW_BW     ":/images/icons/node-bw-low.png"
00029 #define IMG_NODE_MED_BW     ":/images/icons/node-bw-med.png"
00030 #define IMG_NODE_HIGH_BW    ":/images/icons/node-bw-high.png"
00031 #define IMG_FLAG_UNKNOWN    ":/images/flags/unknown.png"
00032 
00033 
00034 /** Default constructor. */
00035 RouterListItem::RouterListItem(RouterListWidget *list, RouterDescriptor rd)
00036   : QTreeWidgetItem()
00037 {
00038   _list = list;
00039   _rd   = 0;
00040   _countryCode = "~"; /* Force items with no country to the bottom */
00041   setIcon(COUNTRY_COLUMN, QIcon(IMG_FLAG_UNKNOWN));
00042   update(rd);
00043 }
00044 
00045 /** Destructor. */
00046 RouterListItem::~RouterListItem()
00047 {
00048   if (_rd)
00049     delete _rd;
00050 }
00051 
00052 /** Updates the router descriptor for this item. */
00053 void
00054 RouterListItem::update(const RouterDescriptor &rd)
00055 {
00056   QIcon statusIcon;
00057   if (_rd) {
00058     delete _rd;
00059   }
00060   _rd = new RouterDescriptor(rd);
00061   
00062   /* Determine the status value (used for sorting) and icon */
00063   if (_rd->offline()) {
00064     _statusValue = -1;
00065     statusIcon = QIcon(IMG_NODE_OFFLINE);
00066     setToolTip(STATUS_COLUMN, tr("Offline"));
00067   } else if (_rd->hibernating()) {
00068     _statusValue = 0;
00069     statusIcon = QIcon(IMG_NODE_SLEEPING);
00070     setToolTip(STATUS_COLUMN, tr("Hibernating"));
00071   } else {
00072     _statusValue = (qint64)_rd->observedBandwidth();
00073     if (_statusValue >= 400*1024) {
00074       statusIcon = QIcon(IMG_NODE_HIGH_BW);
00075     } else if (_statusValue >= 60*1024) {
00076       statusIcon = QIcon(IMG_NODE_MED_BW);
00077     } else if (_statusValue >= 20*1024) {
00078       statusIcon = QIcon(IMG_NODE_LOW_BW);
00079     } else {
00080       statusIcon = QIcon(IMG_NODE_NO_BW);
00081     }
00082     setToolTip(STATUS_COLUMN, tr("%1 KB/s").arg(_statusValue/1024));
00083   }
00084   
00085   /* Make the new information visible */
00086   setIcon(STATUS_COLUMN, statusIcon);
00087   setText(NAME_COLUMN, _rd->name());
00088   setToolTip(NAME_COLUMN, QString(_rd->name() + "\r\n" + _rd->platform()));
00089 }
00090 
00091 /** Sets the location information for this item's router descriptor. */
00092 void
00093 RouterListItem::setLocation(const GeoIpRecord &geoip)
00094 {
00095   QPixmap flag(":/images/flags/" + geoip.countryCode().toLower() + ".png");
00096   if (!flag.isNull()) {
00097     setIcon(COUNTRY_COLUMN, QIcon(flag));
00098   }
00099   setToolTip(COUNTRY_COLUMN, geoip.toString());
00100 
00101   if (_rd)
00102     _rd->setLocation(geoip.toString());
00103   _countryCode = geoip.countryCode();
00104 }
00105 
00106 /** Overload the comparison operator. */
00107 bool
00108 RouterListItem::operator<(const QTreeWidgetItem &other) const
00109 {
00110   const RouterListItem *a = this;
00111   const RouterListItem *b = (RouterListItem *)&other;
00112  
00113   if (_list) {
00114     Qt::SortOrder order = _list->header()->sortIndicatorOrder();
00115     switch (_list->sortColumn()) {
00116       case RouterListWidget::StatusColumn:
00117         /* Numeric comparison based on status and/or bandwidth */
00118         if (a->_statusValue == b->_statusValue) {
00119           if (order == Qt::AscendingOrder)
00120             return (a->name().toLower() > b->name().toLower());
00121           else
00122             return (a->name().toLower() < b->name().toLower());
00123         }
00124         return (a->_statusValue < b->_statusValue);
00125       case RouterListWidget::CountryColumn:
00126         /* Compare based on country code */
00127         if (a->_countryCode == b->_countryCode) {
00128           if (order == Qt::AscendingOrder)
00129             return (a->_statusValue > b->_statusValue);
00130           else
00131             return (a->_statusValue < b->_statusValue);
00132         }
00133         return (a->_countryCode < b->_countryCode);
00134       case RouterListWidget::NameColumn:
00135         /* Case-insensitive comparison based on router name */
00136         if (a->name().toLower() == b->name().toLower()) {
00137           if (order == Qt::AscendingOrder)
00138             return (a->_statusValue > b->_statusValue);
00139           else
00140             return (a->_statusValue < b->_statusValue);
00141         }
00142         return (a->name().toLower() < b->name().toLower());
00143       default:
00144         break;
00145     }
00146   }
00147   return QTreeWidgetItem::operator<(other);
00148 }
00149