first networkview implementation. Totally unfinished

git-svn-id: http://svn.code.sf.net/p/retroshare/code/trunk@3738 b45a01b8-16f6-495d-af2f-9b41ad6348cc
This commit is contained in:
csoler 2010-11-01 14:17:18 +00:00
parent a1f9d2a607
commit 0fcc298801
7 changed files with 263 additions and 238 deletions

View File

@ -24,6 +24,8 @@
#include <gpgme.h>
#include <deque>
#include <set>
#include <iostream>
#include <algorithm>
@ -38,6 +40,9 @@ NetworkView::NetworkView(QWidget *parent)
mScene = new QGraphicsScene();
ui.graphicsView->setScene(mScene);
ui.graphicsView->setEdgeLength(ui.edgeLengthSB->value()) ;
setMaxFriendLevel(ui.maxFriendLevelSB->value()) ;
/* add button */
connect( ui.refreshButton, SIGNAL( clicked( void ) ), this, SLOT( insertPeers( void ) ) );
@ -45,7 +50,8 @@ NetworkView::NetworkView(QWidget *parent)
/* Hide Settings frame */
shownwSettingsFrame(false);
connect( ui.nviewsettingsButton, SIGNAL(toggled(bool)), this, SLOT(shownwSettingsFrame(bool)));
connect( ui.maxFriendLevelSB, SIGNAL(valueChanged(int)), this, SLOT(setMaxFriendLevel(int)));
connect( ui.edgeLengthSB, SIGNAL(valueChanged(int)), this, SLOT(setEdgeLength(int)));
insertPeers();
@ -65,6 +71,15 @@ NetworkView::NetworkView(QWidget *parent)
}
void NetworkView::setEdgeLength(int l)
{
ui.graphicsView->setEdgeLength(l);
}
void NetworkView::setMaxFriendLevel(int m)
{
_max_friend_level = m ;
insertPeers() ;
}
void NetworkView::changedFoFCheckBox( )
{
insertPeers();
@ -117,6 +132,14 @@ void NetworkView::clearLineItems()
mLineItems.clear();
}
class NodeInfo
{
public:
NodeInfo(const std::string& id,uint32_t lev) : gpg_id(id),friend_level(lev) {}
std::string gpg_id ;
uint32_t friend_level ;
} ;
void NetworkView::insertPeers()
{
@ -124,85 +147,116 @@ void NetworkView::insertPeers()
ui.graphicsView->clearGraph();
/* add all friends */
std::list<std::string> ids;
std::list<std::string>::iterator it;
std::string ownId = rsPeers->getGPGOwnId();
RsPeerDetails detail ;
if(!rsPeers->getPeerDetails(ownId,detail))
return ;
ids = detail.gpgSigners ;
std::cerr << "NetworkView::insertPeers()" << std::endl;
int i = 0;
uint32_t flags = 0;
std::map<std::string,GraphWidget::NodeId> node_ids ;
std::map<std::string,GraphWidget::NodeId> node_ids ; // node ids of the created nodes.
std::deque<NodeInfo> nodes_to_treat ; // list of nodes to be treated. Used as a queue. The int is the level of friendness
std::set<std::string> nodes_considered ; // list of nodes already considered. Eases lookup.
for(it = ids.begin(); it != ids.end(); it++, i++)
nodes_to_treat.push_front(NodeInfo(ownId,0)) ; // initialize queue with own id.
nodes_considered.insert(ownId) ;
// compute the list of GPG friends
std::set<std::string> gpg_friends ;
std::list<std::string> ssl_friends ;
if(!rsPeers->getFriendList(ssl_friends))
return ;
for(std::list<std::string>::const_iterator it(ssl_friends.begin());it!=ssl_friends.end();++it)
{
if (*it == ownId)
flags |= GraphWidget::ELASTIC_NODE_FLAG_OWN ;
RsPeerDetails d ;
if(!rsPeers->getPeerDetails(*it,d))
continue ;
/* *** */
if (!rsPeers->getPeerDetails(*it, detail))
gpg_friends.insert(d.gpg_id) ;
}
std::cerr << "Found " << gpg_friends.size() << " gpg friends." << std::endl ;
// Put own id in queue, and empty the queue, treating all nodes.
//
while(!nodes_to_treat.empty())
{
NodeInfo info(nodes_to_treat.back()) ;
nodes_to_treat.pop_back() ;
std::cerr << " Poped out of queue: " << info.gpg_id << ", with level " << info.friend_level << std::endl ;
RsPeerDetails detail ;
if(!rsPeers->getPeerDetails(info.gpg_id,detail))
{
continue;
}
switch(detail.validLvl)
{
case GPGME_VALIDITY_UNKNOWN:
case GPGME_VALIDITY_UNDEFINED:
case GPGME_VALIDITY_NEVER:
/* lots of fall through */
break;
case GPGME_VALIDITY_MARGINAL:
/* lots of fall through */
flags |= GraphWidget::ELASTIC_NODE_FLAG_MARGINALAUTH;
break;
case GPGME_VALIDITY_FULL:
case GPGME_VALIDITY_ULTIMATE:
/* lots of fall through */
flags |= GraphWidget::ELASTIC_NODE_FLAG_AUTHED;
break;
default:
break ;
std::cerr << "Could not request GPG details for node " << info.gpg_id << std::endl ;
continue ;
}
node_ids[*it] = ui.graphicsView->addNode(" "+detail.name+"@"+*it,flags);
if(info.friend_level <= _max_friend_level && (info.friend_level != 1 || gpg_friends.find(info.gpg_id) != gpg_friends.end()))
{
std::cerr << "NetworkView::insertPeers() Added Friend: " << *it << std::endl;
GraphWidget::NodeType type ;
GraphWidget::AuthType auth ;
switch(info.friend_level)
{
case 0: type = GraphWidget::ELASTIC_NODE_TYPE_OWN ;
break ;
case 1: type = GraphWidget::ELASTIC_NODE_TYPE_FRIEND ;
break ;
case 2: type = GraphWidget::ELASTIC_NODE_TYPE_F_OF_F ;
break ;
default:
type = GraphWidget::ELASTIC_NODE_TYPE_UNKNOWN ;
}
switch(detail.validLvl)
{
case GPGME_VALIDITY_MARGINAL: auth = GraphWidget::ELASTIC_NODE_AUTH_MARGINAL ; break;
case GPGME_VALIDITY_FULL:
case GPGME_VALIDITY_ULTIMATE: auth = GraphWidget::ELASTIC_NODE_AUTH_FULL ; break;
case GPGME_VALIDITY_UNKNOWN:
case GPGME_VALIDITY_UNDEFINED:
case GPGME_VALIDITY_NEVER:
default: auth = GraphWidget::ELASTIC_NODE_AUTH_UNKNOWN ; break ;
}
node_ids[info.gpg_id] = ui.graphicsView->addNode(" "+detail.name, detail.name+"@"+info.gpg_id,type,auth);
std::cerr << " inserted node " << info.gpg_id << ", type=" << type << ", auth=" << auth << std::endl ;
}
std::cerr << "NetworkView::insertPeers() Added Friend: " << info.gpg_id << std::endl;
for(std::list<std::string>::const_iterator sit(detail.gpgSigners.begin()); sit != detail.gpgSigners.end(); ++sit)
if(nodes_considered.find(*sit) == nodes_considered.end())
{
std::cerr << " adding to queue: " << *sit << ", with level " << info.friend_level+1 << std::endl ;
nodes_to_treat.push_front( NodeInfo(*sit,info.friend_level + 1) ) ;
nodes_considered.insert(*sit) ;
}
}
/* iterate through all friends */
std::cerr << "NetworkView::insertSignatures()" << std::endl;
for(it = ids.begin(); it != ids.end(); it++, i++)
for(std::map<std::string,GraphWidget::NodeId>::const_iterator it(node_ids.begin()); it != node_ids.end(); it++)
{
RsPeerDetails detail;
if (!rsPeers->getPeerDetails(*it, detail))
{
if (!rsPeers->getPeerDetails(it->first, detail))
continue;
}
for(std::list<std::string>::const_iterator sit(detail.gpgSigners.begin()); sit != detail.gpgSigners.end(); sit++)
{
if ((*it == ownId || *sit == ownId) && *it < *sit)
if(it->first < *sit)
{
std::cerr << "NetworkView: Adding Arrow: ";
std::cerr << *sit << " <-> " << *it;
std::cerr << *sit << " <-> " << it->first;
std::cerr << std::endl;
if(node_ids.find(*sit) != node_ids.end())
ui.graphicsView->addEdge(node_ids[*sit], node_ids[*it]);
ui.graphicsView->addEdge(node_ids[*sit], it->second);
}
}
}
@ -301,13 +355,13 @@ Toggles the Settings pane on and off, changes toggle button text
void NetworkView::shownwSettingsFrame(bool show)
{
if (show) {
ui.viewsettingsframe->setVisible(true);
ui.nviewsettingsButton->setChecked(true);
ui.nviewsettingsButton->setToolTip(tr("Hide Settings"));
// ui.viewsettingsframe->setVisible(true);
// ui.nviewsettingsButton->setChecked(true);
// ui.nviewsettingsButton->setToolTip(tr("Hide Settings"));
} else {
ui.viewsettingsframe->setVisible(false);
ui.nviewsettingsButton->setChecked(false);
ui.nviewsettingsButton->setToolTip(tr("Show Settings"));
// ui.viewsettingsframe->setVisible(false);
// ui.nviewsettingsButton->setChecked(false);
// ui.nviewsettingsButton->setToolTip(tr("Show Settings"));
}
}

View File

@ -38,6 +38,8 @@ public:
private slots:
void setMaxFriendLevel(int) ;
void setEdgeLength(int) ;
void insertPeers();
void insertSignatures();
void insertConnections();
@ -68,6 +70,7 @@ private:
/** Qt Designer generated object */
Ui::NetworkView ui;
int _max_friend_level ;
};
#endif

View File

@ -1,63 +1,50 @@
<ui version="4.0" >
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NetworkView</class>
<widget class="QWidget" name="NetworkView" >
<property name="geometry" >
<widget class="QWidget" name="NetworkView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>493</width>
<height>373</height>
<width>616</width>
<height>499</height>
</rect>
</property>
<property name="windowTitle" >
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QGridLayout" >
<property name="leftMargin" >
<number>0</number>
</property>
<property name="topMargin" >
<number>0</number>
</property>
<property name="rightMargin" >
<number>0</number>
</property>
<property name="bottomMargin" >
<number>0</number>
</property>
<property name="horizontalSpacing" >
<layout class="QGridLayout">
<property name="horizontalSpacing">
<number>6</number>
</property>
<property name="verticalSpacing" >
<property name="verticalSpacing">
<number>2</number>
</property>
<item row="0" column="0" >
<widget class="GraphWidget" name="graphicsView" >
<property name="styleSheet" >
<string>background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
stop:0 lightgray, stop:1 darkgray);
</string>
<property name="margin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="GraphWidget" name="graphicsView">
<property name="styleSheet">
<string>background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,stop:0 lightgray, stop:1 darkgray);</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QPushButton" name="refreshButton" >
<property name="text" >
<item row="1" column="0">
<layout class="QGridLayout">
<item row="0" column="0">
<widget class="QPushButton" name="refreshButton">
<property name="text">
<string>Refresh</string>
</property>
</widget>
</item>
<item row="0" column="1" >
<item row="0" column="7">
<spacer>
<property name="orientation" >
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<property name="sizeHint" stdset="0">
<size>
<width>391</width>
<height>23</height>
@ -65,97 +52,71 @@
</property>
</spacer>
</item>
<item row="0" column="2" >
<widget class="QPushButton" name="nviewsettingsButton" >
<property name="text" >
<string>Settings</string>
<item row="0" column="2">
<widget class="QComboBox" name="comboBox">
<item>
<property name="text">
<string>Basic</string>
</property>
</item>
<item>
<property name="text">
<string>Friends</string>
</property>
</item>
<item>
<property name="text">
<string>Extended</string>
</property>
</item>
</widget>
</item>
<item row="0" column="1">
<widget class="QLabel" name="label">
<property name="text">
<string>Display mode:</string>
</property>
<property name="checkable" >
<bool>true</bool>
</widget>
</item>
<item row="0" column="4">
<widget class="QSpinBox" name="maxFriendLevelSB">
<property name="minimum">
<number>0</number>
</property>
<property name="maximum">
<number>10</number>
</property>
</widget>
</item>
<item row="0" column="3">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Friends level:</string>
</property>
</widget>
</item>
<item row="0" column="6">
<widget class="QSpinBox" name="edgeLengthSB">
<property name="minimum">
<number>10</number>
</property>
<property name="maximum">
<number>200</number>
</property>
<property name="value">
<number>50</number>
</property>
</widget>
</item>
<item row="0" column="5">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Edge length:</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0" >
<widget class="QFrame" name="viewsettingsframe" >
<property name="frameShape" >
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow" >
<enum>QFrame::Raised</enum>
</property>
<layout class="QGridLayout" >
<property name="leftMargin" >
<number>9</number>
</property>
<property name="topMargin" >
<number>9</number>
</property>
<property name="rightMargin" >
<number>9</number>
</property>
<property name="bottomMargin" >
<number>9</number>
</property>
<item row="0" column="0" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="fofCheckBox" >
<property name="text" >
<string>Show Friends of Friends</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<widget class="QCheckBox" name="checkBox" >
<property name="text" >
<string>Connect Signature</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="1" >
<layout class="QGridLayout" >
<item row="0" column="0" >
<widget class="QCheckBox" name="checkBox_2" >
<property name="text" >
<string>Draw Friend Connections</string>
</property>
</widget>
</item>
<item row="1" column="0" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>141</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
<item row="0" column="2" >
<spacer>
<property name="orientation" >
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" >
<size>
<width>161</width>
<height>41</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>

View File

@ -143,28 +143,28 @@ GraphWidget::GraphWidget(QWidget *)
void GraphWidget::clearGraph()
{
QGraphicsScene *oldscene = scene();
QGraphicsScene *scene = new QGraphicsScene(this);
scene->setItemIndexMethod(QGraphicsScene::NoIndex);
scene->setSceneRect(-200, -200, 1000, 1000);
setScene(scene);
// QGraphicsScene *scene = new QGraphicsScene(this);
// scene->setItemIndexMethod(QGraphicsScene::NoIndex);
// setScene(scene);
// scene->addItem(centerNode);
// centerNode->setPos(0, 0);
if (oldscene != NULL)
{
delete oldscene;
}
// if (oldscene != NULL)
// {
// delete oldscene;
// }
scene()->clear();
scene()->setSceneRect(-200, -200, 1000, 1000);
_edges.clear();
_nodes.clear();
}
GraphWidget::NodeId GraphWidget::addNode(const std::string& node_string,uint32_t flags)
GraphWidget::NodeId GraphWidget::addNode(const std::string& node_short_string,const std::string& node_complete_string,NodeType type,AuthType auth)
{
Node *node = new Node(node_string,flags,this);
Node *node = new Node(node_short_string,type,auth,this);
node->setToolTip(QString::fromStdString(node_complete_string)) ;
_nodes.push_back(node) ;
scene()->addItem(node);
node->setPos(-50+rand()%1000/53.0f, -50+rand()%1000/53.0f);
@ -179,7 +179,10 @@ GraphWidget::EdgeId GraphWidget::addEdge(NodeId n1,NodeId n2)
void GraphWidget::itemMoved()
{
if (!timerId)
{
std::cout << "starting timer" << std::endl;
timerId = startTimer(1000 / 25);
}
}
void GraphWidget::keyPressEvent(QKeyEvent *event)
@ -306,17 +309,28 @@ void GraphWidget::timerEvent(QTimerEvent *event)
}
bool itemsMoved = false;
foreach (Node *node, _nodes) {
if (node->advance())
foreach (Node *node, _nodes)
if(node->advance())
itemsMoved = true;
}
if (!itemsMoved) {
killTimer(timerId);
std::cerr << "Killing timr" << std::endl ;
timerId = 0;
}
}
void GraphWidget::setEdgeLength(uint32_t l)
{
_edge_length = l ;
if(!timerId)
{
std::cout << "starting timer" << std::endl;
timerId = startTimer(1000 / 25);
}
}
void GraphWidget::wheelEvent(QWheelEvent *event)
{
scaleView(pow((double)2, -event->delta() / 240.0));

View File

@ -58,17 +58,26 @@ public:
typedef int EdgeId ;
typedef enum {
ELASTIC_NODE_FLAG_OWN = 0x0001,
ELASTIC_NODE_FLAG_FRIEND = 0x0002,
ELASTIC_NODE_FLAG_AUTHED = 0x0004,
ELASTIC_NODE_FLAG_MARGINALAUTH = 0x0008
} NodeFlags ;
ELASTIC_NODE_TYPE_OWN = 0x0000,
ELASTIC_NODE_TYPE_FRIEND = 0x0001,
ELASTIC_NODE_TYPE_F_OF_F = 0x0002,
ELASTIC_NODE_TYPE_UNKNOWN = 0x0003
} NodeType ;
virtual void itemMoved();
NodeId addNode(const std::string& NodeText,uint32_t flags) ;
typedef enum {
ELASTIC_NODE_AUTH_FULL = 0x0000,
ELASTIC_NODE_AUTH_MARGINAL = 0x0001,
ELASTIC_NODE_AUTH_UNKNOWN = 0x0002
} AuthType ;
NodeId addNode(const std::string& NodeShortText,const std::string& nodeCompleteText,NodeType type,AuthType auth) ;
EdgeId addEdge(NodeId n1,NodeId n2) ;
void clearGraph() ;
virtual void itemMoved();
void setEdgeLength(uint32_t l) ;
uint32_t edgeLength() const { return _edge_length ; }
protected:
void keyPressEvent(QKeyEvent *event);
@ -85,6 +94,8 @@ private:
std::vector<Node *> _nodes ;
std::vector<Node *> _edges ;
uint32_t _edge_length ;
};
#endif

View File

@ -51,8 +51,8 @@
#include "node.h"
#include "graphwidget.h"
Node::Node(const std::string& node_string,uint32_t flags,GraphWidget *graphWidget)
: graph(graphWidget),_desc_string(node_string),_flags(flags)
Node::Node(const std::string& node_string,GraphWidget::NodeType type,GraphWidget::AuthType auth,GraphWidget *graphWidget)
: graph(graphWidget),_desc_string(node_string),_type(type),_auth(auth)
{
setFlag(ItemIsMovable);
#if QT_VERSION >= 0x040600
@ -147,7 +147,7 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl
pos = mapFromItem(edge->sourceNode(), 0, 0);
float dist = sqrtf(pos.x()*pos.x() + pos.y()*pos.y()) ;
float val = dist - NODE_DISTANCE ;
float val = dist - graph->edgeLength() ;
xforce += 0.01*pos.x() * val / weight;
yforce += 0.01*pos.y() * val / weight;
@ -183,11 +183,10 @@ void Node::calculateForces(const double *map,int width,int height,int W,int H,fl
bool Node::advance()
{
if (newPos == pos())
return false;
float f = std::max(fabs(newPos.x() - pos().x()), fabs(newPos.y() - pos().y())) ;
setPos(newPos);
return true;
return f > 0.05;
}
QRectF Node::boundingRect() const
@ -217,44 +216,26 @@ QPainterPath Node::shape() const
void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
static QColor type_color[4] = { QColor(Qt::yellow), QColor(Qt::green), QColor(Qt::cyan), QColor(Qt::black) } ;
static QColor auth_color[3] = { QColor(Qt::darkYellow), QColor(Qt::darkGreen), QColor(Qt::darkBlue) } ;
painter->setPen(Qt::NoPen);
painter->setBrush(Qt::darkGray);
painter->drawEllipse(-7, -7, 20, 20);
QColor col0, col1;
if (_flags & GraphWidget::ELASTIC_NODE_FLAG_OWN)
{
col0 = QColor(Qt::yellow);
col1 = QColor(Qt::darkYellow);
}
else if (_flags & GraphWidget::ELASTIC_NODE_FLAG_FRIEND)
{
col0 = QColor(Qt::green);
col1 = QColor(Qt::darkGreen);
}
else if (_flags & GraphWidget::ELASTIC_NODE_FLAG_AUTHED)
{
col0 = QColor(Qt::cyan);
col1 = QColor(Qt::darkBlue);
}
else if (_flags & GraphWidget::ELASTIC_NODE_FLAG_MARGINALAUTH)
{
col0 = QColor(Qt::magenta);
col1 = QColor(Qt::darkMagenta);
}
else
{
col0 = QColor(Qt::red);
col1 = QColor(Qt::darkRed);
}
QColor col0(type_color[_type]) ;
QColor col1(auth_color[_auth]) ;
QRadialGradient gradient(-3, -3, 10);
if (option->state & QStyle::State_Sunken) {
if (option->state & QStyle::State_Sunken)
{
gradient.setCenter(3, 3);
gradient.setFocalPoint(3, 3);
gradient.setColorAt(1, col0.light(120));
gradient.setColorAt(0, col1.light(120));
} else {
}
else
{
gradient.setColorAt(0, col0);
gradient.setColorAt(1, col1);
}

View File

@ -55,7 +55,7 @@ QT_END_NAMESPACE
class Node : public QGraphicsItem
{
public:
Node(const std::string& node_string,uint32_t flags,GraphWidget *graphWidget);
Node(const std::string& node_string,GraphWidget::NodeType type,GraphWidget::AuthType auth,GraphWidget *graphWidget);
void addEdge(Edge *edge);
QList<Edge *> edges() const;
@ -82,7 +82,8 @@ private:
qreal _speedx,_speedy;
int _steps ;
std::string _desc_string ;
uint32_t _flags ;
GraphWidget::NodeType _type ;
GraphWidget::AuthType _auth ;
bool mDeterminedBB ;
int mBBWidth ;