NodeModel.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 2005-2007 by Peter Dimov.
00004 
00005 This file is part of Calitko (http://www.calitko.org).
00006 
00007 Calitko is free software; you can redistribute it and/or modify
00008 it under the terms of the GNU General Public License as published by
00009 the Free Software Foundation; either version 2 of the License, or
00010 (at your option) any later version.
00011 
00012 Calitko is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Calitko; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 
00021 */
00022 
00027 #include "Qt.h"
00028 #include "NodeModel.h"
00029 #include "Gnutella/LocalPeer.h"
00030 
00031 NodeModel::NodeModel()
00032  :  nodeInfos(), updateTimer(), mapper()
00033 {
00034     // <pd_todo> move back to the view
00035     connect (&updateTimer, SIGNAL (timeout()), this, SLOT (refreshModel()));
00036     updateTimer.setInterval (ModelRefreshInterval);
00037     updateTimer.start();
00038     connect (&mapper, SIGNAL (mapped (QObject *)),
00039          this, SLOT (setDisconnected (QObject *)));
00040 }
00041 
00042 NodeModel::~NodeModel()
00043 {
00044     foreach (NodeData *info, nodeInfos)
00045         delete info;
00046     nodeInfos.clear();
00047 }
00050 int NodeModel::nodeIndex (ConnectionId id)
00051 {
00052     int count = nodeInfos.count();
00053     for (int i = 0; i < count; i++)
00054         if (nodeInfos.at (i)->id == id)
00055             return i;
00056 
00057     return -1;
00058 }
00059 
00060 void NodeModel::refreshModel()
00061 {
00062     dataChanged (index(0, 0), index(rowCount() - 1, columnCount() - 1));
00063 }
00064 
00065 int NodeModel::rowCount (const QModelIndex &) const
00066 {
00067     return nodeInfos.count();
00068 }
00069 
00070 int NodeModel::columnCount (const QModelIndex &) const
00071 {
00072     return ColumnCount;
00073 }
00074 
00075 QVariant NodeModel::data (const QModelIndex &index, int role) const
00076 {
00077     if (role == Qt::DisplayRole){
00078         NodeData* nodeInfo = nodeInfos.at(index.row());
00079         switch (index.column())
00080         {
00081         case AddressIndex:              return nodeInfo->address;
00082         case PortIndex:                 return static_cast <uint> (nodeInfo->port);
00083         case DurationIndex:
00084             switch (nodeInfo->status)
00085             {
00086             case Connecting:            return tr ("Connecting...");
00087             case Handshaking:           return tr ("Handshaking...");
00088             case Connected:         //return tr ("Connected"); <pd_todo> Calculate days and time!
00089                 return QTime().addSecs (nodeInfo->startDateTime.secsTo (QDateTime::currentDateTime()));
00090             case Disconnecting:         return tr ("Disconnecting...");
00091             case Disconnected:          return tr ("Disconnected");
00092             default:                    return tr ("Unknown");
00093             }
00094         case TypeIndex:
00095             switch (nodeInfo->type)
00096             {
00097             case Peer:                  return tr ("Peer");
00098             case Ultrapeer:             return tr ("Ultrapeer");
00099             case Leaf:                  return tr ("Leaf");
00100             case Undetermined:          // fallthrough
00101             default:                    return QVariant();
00102             }
00103         case ServentIndex:              return nodeInfo->servent;
00104         default:                        return QVariant();
00105         }
00106     }
00107 
00108     if (role == Qt::DecorationRole && index.column() == AddressIndex)
00109         return QIcon ("Icons/peer.png");
00110 
00111     return QVariant();
00112 }
00113 
00114 QVariant NodeModel::headerData (int section, Qt::Orientation orientation, int role) const
00115 {
00116     if (orientation == Qt::Vertical || role != Qt::DisplayRole)
00117         return QVariant();
00118 
00119     switch (section)
00120     {
00121     case AddressIndex:      return tr ("Address");
00122     case PortIndex:         return tr ("Port");
00123     case DurationIndex:     return tr ("Duration");
00124     case TypeIndex:         return tr ("Type");
00125     case ServentIndex:      return tr ("Servent");
00126     default:                return QVariant();
00127     }
00128 }
00129 
00130 void NodeModel::nodeConnecting (Connection *connection, NodeAddress nodeAddress)
00131 {
00132     int row = nodeInfos.count();
00133     beginInsertRows (QModelIndex(), row, row);
00134 
00135     NodeData *info      = new NodeData;
00136     info->id            = reinterpret_cast <ConnectionId> (connection);
00137     info->address       = nodeAddress.hostAddress().toString();
00138     if (info->address.length() == 0)
00139         info->address   = nodeAddress.hostName();
00140     info->port          = nodeAddress.hostPort();
00141     info->startDateTime = QDateTime::currentDateTime();
00142     info->status        = Connecting;
00143     info->type          = Undetermined;
00144     nodeInfos.append (info);
00145 
00146     endInsertRows ();
00147 
00148     connect (connection, SIGNAL (destroyed()), &mapper, SLOT (map()));
00149     mapper.setMapping (connection, reinterpret_cast <QObject *> (connection));
00150 }
00151 
00152 void NodeModel::setHandshaking (Connection *connection)
00153 {
00154     setNodeStatus (reinterpret_cast <ConnectionId> (connection), Handshaking);
00155 }
00156 
00157 void NodeModel::setConnected (Connection *connection, NodeInfo nodeInfo)
00158 {
00159     Type type = Undetermined;
00160     if (nodeInfo.type == Gnutella::TypeLeaf)
00161         type = Leaf;
00162     if (nodeInfo.type == Gnutella::TypePeer)
00163         type = Peer;
00164     if (nodeInfo.type == Gnutella::TypeUltrapeer)
00165         type = Ultrapeer;
00166 
00167     setNodeStatus (reinterpret_cast <ConnectionId> (connection), Connected);
00168     setNodeType (reinterpret_cast <ConnectionId> (connection), type);
00169     setNodeServent (reinterpret_cast <ConnectionId> (connection), nodeInfo.identification);
00170     setNodePort (reinterpret_cast <ConnectionId> (connection), nodeInfo.address.hostPort());
00171 }
00172 
00173 void NodeModel::setDisconnected (QObject *id)
00174 {
00175     nodeDisconnected (reinterpret_cast <ConnectionId> (id));
00176 }
00177 
00178 bool NodeModel::nodeDisconnected (ConnectionId id)
00179 {
00180     int row = nodeIndex (id);
00181     if (row == -1)
00182         return false;
00183 
00184     beginRemoveRows (QModelIndex(), row, row);
00185 
00186     delete nodeInfos.takeAt (row);
00187 
00188     endRemoveRows();
00189     return true;
00190 }
00191 
00202 bool NodeModel::setNodeStatus (ConnectionId id, Status status)
00203 {
00204     int row = nodeIndex (id);
00205     if (row == -1)
00206         return false;
00207 
00208     NodeData *info = nodeInfos.at (row);
00209     if (status == Connected)
00210         info->startDateTime = QDateTime::currentDateTime();
00211     info->status = status;
00212 
00213     dataChanged (index (row, DurationIndex), index (row, DurationIndex));
00214     return true;
00215 }
00216 
00217 bool NodeModel::setNodeType (ConnectionId id, Type type)
00218 {
00219     int row = nodeIndex (id);
00220     if (row == -1)
00221         return false;
00222 
00223     nodeInfos.at (row)->type = type;
00224     dataChanged (index (row, TypeIndex), index (row, TypeIndex));
00225     return true;
00226 }
00227 
00228 bool NodeModel::setNodeServent (ConnectionId id, const QString &servent)
00229 {
00230     int row = nodeIndex (id);
00231     if (row == -1)
00232         return false;
00233 
00234     nodeInfos.at (row)->servent = servent;
00235     dataChanged (index (row, ServentIndex), index (row, ServentIndex));
00236     return true;
00237 }
00238 
00239 bool NodeModel::setNodePort (ConnectionId id, quint16 port)
00240 {
00241     int row = nodeIndex (id);
00242     if (row == -1)
00243         return false;
00244 
00245     nodeInfos.at (row)->port = port;
00246     dataChanged (index (row, PortIndex), index (row, PortIndex));
00247     return true;
00248 }