routerlistwidget.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 routerlistwidget.cpp
00013 ** \version $Id: routerlistwidget.cpp 2978 2008-08-17 01:52:19Z edmanm $
00014 ** \brief Displays a list of Tor servers and their status
00015 */
00016 
00017 #include <QHeaderView>
00018 #include <vidalia.h>
00019 
00020 #include "routerlistwidget.h"
00021 
00022 #define IMG_ZOOM   ":/images/22x22/page-zoom.png"
00023 
00024 
00025 RouterListWidget::RouterListWidget(QWidget *parent)
00026 : QTreeWidget(parent)
00027 {
00028   /* Create and initialize columns */
00029   setHeaderLabels(QStringList() << QString("")
00030                                 << QString("")
00031                                 << tr("Relay"));
00032 
00033   /* Sort by descending server bandwidth */
00034   sortItems(StatusColumn, Qt::DescendingOrder);
00035 
00036   /* Find out when the selected item has changed. */
00037   connect(this, SIGNAL(itemSelectionChanged()), 
00038           this, SLOT(onSelectionChanged()));
00039   connect(this, SIGNAL(customContextMenuRequested(QPoint)),
00040           this, SLOT(customContextMenuRequested(QPoint)));
00041 }
00042 
00043 /** Called when the user requests a context menu for a router in the list. A
00044  * context menu will be displayed providing a list of actions, including
00045  * zooming in on the server. */
00046 void
00047 RouterListWidget::customContextMenuRequested(const QPoint &pos)
00048 {
00049   QMenu menu(this);
00050 
00051   /* Find out which (if any) router in the list is selected */
00052   RouterListItem *item = dynamic_cast<RouterListItem *>(itemAt(pos));
00053   if (!item)
00054     return;
00055   
00056   /* Set up the context menu */
00057   QAction *zoomAction =
00058     new QAction(QIcon(IMG_ZOOM), tr("Zoom to Relay"), &menu);
00059   menu.addAction(zoomAction);
00060   
00061   /* Display the menu and find out which (if any) action was selected */
00062   QAction *action = menu.exec(mapToGlobal(pos));
00063   if (action == zoomAction)
00064     emit zoomToRouter(item->id());
00065 }
00066 
00067 /** Deselects all currently selected routers. */
00068 void
00069 RouterListWidget::deselectAll()
00070 {
00071   QList<QTreeWidgetItem *> selected = selectedItems();
00072   foreach (QTreeWidgetItem *item, selected) {
00073     setItemSelected(item, false);
00074   }
00075 }
00076 
00077 /** Clear the list of router items. */
00078 void
00079 RouterListWidget::clearRouters()
00080 {
00081   _idmap.clear();
00082   QTreeWidget::clear();
00083   setStatusTip(tr("%1 relays online").arg(0));
00084 }
00085 
00086 /** Called when the user selects a router from the list. This will search the
00087  * list for a router whose names starts with the key pressed. */
00088 void
00089 RouterListWidget::keyPressEvent(QKeyEvent *event)
00090 {
00091   int index;
00092   
00093   QString key = event->text();
00094   if (!key.isEmpty() && key.at(0).isLetterOrNumber()) {
00095     /* A text key was pressed, so search for routers that begin with that key. */
00096     QList<QTreeWidgetItem *> list = findItems(QString("^[%1%2].*$")
00097                                                   .arg(key.toUpper())
00098                                                   .arg(key.toLower()),
00099                                                Qt::MatchRegExp|Qt::MatchWrap,
00100                                                NameColumn);
00101     if (list.size() > 0) {
00102       QList<QTreeWidgetItem *> s = selectedItems();
00103       
00104       /* A match was found, so deselect any previously selected routers,
00105        * select the new match, and make sure it's visible. If there was
00106        * already a router selected that started with the search key, go to the
00107        * next match in the list. */
00108       deselectAll();
00109       index = (!s.size() ? 0 : (list.indexOf(s.at(0)) + 1) % list.size());
00110 
00111       /* Select the item and scroll to it */
00112       setItemSelected(list.at(index), true);
00113       scrollToItem(list.at(index));
00114     }
00115     event->accept();
00116   } else {
00117     /* It was something we don't understand, so hand it to the parent class */
00118     QTreeWidget::keyPressEvent(event);
00119   }
00120 }
00121 
00122 /** Finds the list item whose key ID matches <b>id</b>. Returns 0 if not 
00123  * found. */
00124 RouterListItem*
00125 RouterListWidget::findRouterById(QString id)
00126 {
00127   if (_idmap.contains(id)) {
00128     return _idmap.value(id);
00129   }
00130   return 0;
00131 }
00132 
00133 /** Adds a router descriptor to the list. */
00134 void
00135 RouterListWidget::addRouter(RouterDescriptor rd)
00136 {
00137   QString id = rd.id();
00138   if (id.isEmpty())
00139     return;
00140 
00141   RouterListItem *item = findRouterById(id);
00142   if (item) {
00143     item->update(rd);
00144   } else {
00145     item = new RouterListItem(this, rd);
00146     addTopLevelItem(item);
00147     _idmap.insert(id, item);
00148   }
00149 
00150   /* Set our status tip to the number of servers in the list */
00151   setStatusTip(tr("%1 relays online").arg(topLevelItemCount()));
00152 }
00153 
00154 /** Called when the selected items have changed. This emits the 
00155  * routerSelected() signal with the descriptor for the selected router.
00156  */
00157 void
00158 RouterListWidget::onSelectionChanged()
00159 {
00160   RouterDescriptor rd;
00161   QList<QTreeWidgetItem *> items = selectedItems();
00162 
00163   if (items.count() > 0) {
00164     rd = ((RouterListItem *)items[0])->descriptor();
00165   }
00166   emit routerSelected(rd);
00167 }
00168 

Generated on Wed Dec 23 21:06:55 2009 for Vidalia by  doxygen 1.6.1