Vidalia 0.2.15
RouterDescriptorView.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.torproject.org/projects/vidalia.html. No part of Vidalia, 
00007 **  including this file, may be copied, modified, propagated, or distributed 
00008 **  except according to the terms described in the LICENSE file.
00009 */
00010 
00011 /*
00012 ** \file RouterDescriptorView.cpp
00013 ** \brief Formats and displays a router descriptor as HTML
00014 */
00015 
00016 #include "RouterDescriptorView.h"
00017 #include "Vidalia.h"
00018 
00019 #include "html.h"
00020 #include "stringutil.h"
00021 
00022 #include <QMenu>
00023 #include <QIcon>
00024 #include <QTextCursor>
00025 #include <QClipboard>
00026 #include <QShortcut>
00027 #include <QTextDocumentFragment>
00028 
00029 #define IMG_COPY      ":/images/22x22/edit-copy.png"
00030 
00031 
00032 /** Default constructor. */
00033 RouterDescriptorView::RouterDescriptorView(QWidget *parent)
00034 : QTextEdit(parent)
00035 {
00036   /* Steal QTextEdit's default "Copy" shortcut, since we want to do some
00037    * tweaking of the selected text before putting it on the clipboard. */
00038   QShortcut *shortcut = new QShortcut(QKeySequence::Copy, this,
00039                                       SLOT(copySelectedText()));
00040   Q_UNUSED(shortcut);
00041 }
00042 
00043 /** Displays a context menu for the user when they right-click on the
00044  * widget. */
00045 void
00046 RouterDescriptorView::contextMenuEvent(QContextMenuEvent *event)
00047 {
00048   QMenu *menu = new QMenu();
00049 
00050   QAction *copyAction = new QAction(QIcon(IMG_COPY), tr("Copy"), menu);
00051   copyAction->setShortcut(QKeySequence::Copy);
00052   connect(copyAction, SIGNAL(triggered()), this, SLOT(copySelectedText()));
00053 
00054   if (textCursor().selectedText().isEmpty())
00055     copyAction->setEnabled(false);
00056 
00057   menu->addAction(copyAction);
00058   menu->exec(event->globalPos());
00059   delete menu;
00060 }
00061 
00062 /** Copies any selected text to the clipboard. */
00063 void
00064 RouterDescriptorView::copySelectedText()
00065 { 
00066   QString selectedText = textCursor().selection().toPlainText();
00067   selectedText.replace(":\n", ": ");
00068   vApp->clipboard()->setText(selectedText);
00069 }
00070 
00071 /** Adjusts the displayed uptime to include time since the router's descriptor
00072  * was last published. */
00073 quint64
00074 RouterDescriptorView::adjustUptime(quint64 uptime, QDateTime published)
00075 {
00076   QDateTime now = QDateTime::currentDateTime().toUTC();
00077   
00078   if (now < published) {
00079     return uptime;
00080   }
00081   return (uptime + (now.toTime_t() - published.toTime_t()));
00082 }
00083 
00084 /** Displays all router descriptors in the given list. */
00085 void
00086 RouterDescriptorView::display(QList<RouterDescriptor> rdlist)
00087 {
00088   RouterDescriptor rd;
00089   QString html = "<html><body>";
00090   
00091   for (int r = 0; r < rdlist.size(); r++) { 
00092     rd = rdlist.at(r);
00093     if (rd.isEmpty())
00094       continue;
00095     
00096     /* Router name and status */
00097     html.append(p(b(rd.name()) + " (" + i(rd.status()) + ")"));
00098 
00099     /* IP and platform */
00100     html.append("<table>");
00101     
00102     /* If we have location information, show that first. */
00103     if (!rd.location().isEmpty()) {
00104       html.append(trow(tcol(b(tr("Location:"))) + tcol(rd.location())));
00105     }
00106     
00107     /* Add the IP address and router platform information */
00108     html.append(trow(tcol(b(tr("IP Address:"))) + tcol(rd.ip().toString())));
00109     html.append(trow(tcol(b(tr("Platform:")))   + tcol(rd.platform())));
00110 
00111     /* If the router is online, then show the uptime and bandwidth stats. */
00112     if (!rd.offline()) {
00113       qint64 minBandwidth = (qint64)qMin(rd.observedBandwidth(), 
00114                                 qMin(rd.averageBandwidth(),
00115                                      rd.burstBandwidth()));
00116       html.append(trow(tcol(b(tr("Bandwidth:")))  + 
00117                        tcol(string_format_bandwidth(minBandwidth))));
00118       html.append(trow(tcol(b(tr("Uptime:")))   + 
00119                        tcol(string_format_uptime(
00120                               adjustUptime(rd.uptime(), rd.published())))));
00121     }
00122 
00123     /* Date the router was published */
00124     html.append(trow(tcol(b(tr("Last Updated:")))  +
00125                      tcol(string_format_datetime(rd.published()) + " GMT")));
00126 
00127     html.append("</table>");
00128 
00129     /* If there are multiple descriptors, and this isn't is the last one 
00130      * then separate them with a short horizontal line. */
00131     if (r+1 != rdlist.size()) {
00132       html.append("<center><hr width=\"50%\"/></center>");
00133     }
00134   }
00135   html.append("</body></html>");
00136   setHtml(html); 
00137 }
00138 
00139 /** Displays the given router descriptor. */
00140 void
00141 RouterDescriptorView::display(RouterDescriptor rd)
00142 {
00143   display(QList<RouterDescriptor>() << rd);
00144 }
00145