diff --git a/retroshare-gui/src/gui/NetworkDialog.cpp b/retroshare-gui/src/gui/NetworkDialog.cpp index 08779e0a3..70e0704e9 100644 --- a/retroshare-gui/src/gui/NetworkDialog.cpp +++ b/retroshare-gui/src/gui/NetworkDialog.cpp @@ -34,6 +34,7 @@ #include "common/RSTreeWidgetItem.h" #include "NetworkDialog.h" #include "TrustView.h" +#include "NetworkView.h" #include "GenCertDialog.h" #include "connect/ConfCertDialog.h" #include "settings/rsharesettings.h" @@ -144,8 +145,8 @@ NetworkDialog::NetworkDialog(QWidget *parent) ui.connecttreeWidget->sortItems( 1, Qt::AscendingOrder ); ui.unvalidGPGkeyWidget->sortItems( 1, Qt::AscendingOrder ); - //ui.networkTab->addTab(new NetworkView(),QString(tr("Network View"))); ui.networkTab->addTab(new TrustView(),QString(tr("Authentication matrix"))); + ui.networkTab->addTab(new NetworkView(),QString(tr("Network View"))); QString version = "-"; std::map::iterator vit; diff --git a/retroshare-gui/src/gui/NetworkView.cpp b/retroshare-gui/src/gui/NetworkView.cpp index 00951edee..fa4a438c7 100644 --- a/retroshare-gui/src/gui/NetworkView.cpp +++ b/retroshare-gui/src/gui/NetworkView.cpp @@ -36,18 +36,18 @@ NetworkView::NetworkView(QWidget *parent) /* Invoke the Qt Designer generated object setup routine */ ui.setupUi(this); - //mScene = new QGraphicsScene(); - //ui.graphicsView->setScene(mScene); + mScene = new QGraphicsScene(); + ui.graphicsView->setScene(mScene); /* add button */ connect( ui.refreshButton, SIGNAL( clicked( void ) ), this, SLOT( insertPeers( void ) ) ); - //connect( mScene, SIGNAL( changed ( const QList & ) ), this, SLOT ( changedScene( void ) ) ); + connect( mScene, SIGNAL( changed ( const QList & ) ), this, SLOT ( changedScene( void ) ) ); - /* Hide Settings frame */ - shownwSettingsFrame(false); - connect( ui.nviewsettingsButton, SIGNAL(toggled(bool)), this, SLOT(shownwSettingsFrame(bool))); - - insertPeers(); + /* Hide Settings frame */ + shownwSettingsFrame(false); + connect( ui.nviewsettingsButton, SIGNAL(toggled(bool)), this, SLOT(shownwSettingsFrame(bool))); + + insertPeers(); /* hide the Tree +/- */ @@ -86,7 +86,7 @@ void NetworkView::clearPeerItems() for(pit = mPeerItems.begin(); pit != mPeerItems.end(); pit++) { - //mScene->destroyItemGroup((QGraphicsItemGroup *) pit->second); + mScene->destroyItemGroup((QGraphicsItemGroup *) pit->second); } mPeerItems.clear(); } @@ -98,7 +98,7 @@ void NetworkView::clearOtherItems() for(oit = mOtherItems.begin(); oit != mOtherItems.end(); oit++) { - //mScene->removeItem(*oit); + mScene->removeItem(*oit); delete (*oit); } mOtherItems.clear(); @@ -111,7 +111,7 @@ void NetworkView::clearLineItems() for(oit = mLineItems.begin(); oit != mLineItems.end(); oit++) { - //mScene->removeItem(*oit); + mScene->removeItem(*oit); delete (*oit); } mLineItems.clear(); @@ -126,77 +126,100 @@ void NetworkView::insertPeers() /* add all friends */ std::list ids; std::list::iterator it; - rsPeers->getGPGAllList(ids); - std::string ownId = rsPeers->getGPGOwnId(); + + std::string ownId = rsPeers->getGPGOwnId(); + RsPeerDetails detail ; + + if(!rsPeers->getPeerDetails(ownId,detail)) + return ; + + ids = detail.gpgSigners ; std::cerr << "NetworkView::insertPeers()" << std::endl; - /* get the list of friends' issuers, as we flag them specially */ - std::list fids; - //rsPeers->getPGPFriendList(fids); - - int i = 0; - uint32_t type = 0; + uint32_t flags = 0; + + std::map node_ids ; + for(it = ids.begin(); it != ids.end(); it++, i++) { if (*it == ownId) - { - continue; - } + flags |= GraphWidget::ELASTIC_NODE_FLAG_OWN ; /* *** */ - RsPeerDetails detail; if (!rsPeers->getPeerDetails(*it, detail)) { continue; } switch(detail.validLvl) { - default: case GPGME_VALIDITY_UNKNOWN: case GPGME_VALIDITY_UNDEFINED: case GPGME_VALIDITY_NEVER: /* lots of fall through */ - type = ELASTIC_NODE_TYPE_FOF; break; case GPGME_VALIDITY_MARGINAL: /* lots of fall through */ - type = ELASTIC_NODE_TYPE_MARGINALAUTH; + flags |= GraphWidget::ELASTIC_NODE_FLAG_MARGINALAUTH; break; case GPGME_VALIDITY_FULL: case GPGME_VALIDITY_ULTIMATE: /* lots of fall through */ - type = ELASTIC_NODE_TYPE_AUTHED; - - if (fids.end() != std::find(fids.begin(), fids.end(), *it)) - { - type = ELASTIC_NODE_TYPE_FRIEND; - } + flags |= GraphWidget::ELASTIC_NODE_FLAG_AUTHED; break; + + default: + break ; } - ui.graphicsView->addNode(type, *it, detail.name); + + node_ids[*it] = ui.graphicsView->addNode(" "+detail.name+"@"+*it,flags); std::cerr << "NetworkView::insertPeers() Added Friend: " << *it << std::endl; } - insertConnections(); - insertSignatures(); + /* iterate through all friends */ + + std::cerr << "NetworkView::insertSignatures()" << std::endl; + + for(it = ids.begin(); it != ids.end(); it++, i++) + { + RsPeerDetails detail; + if (!rsPeers->getPeerDetails(*it, detail)) + { + continue; + } + + for(std::list::const_iterator sit(detail.gpgSigners.begin()); sit != detail.gpgSigners.end(); sit++) + { + if ((*it == ownId || *sit == ownId) && *it < *sit) + { + std::cerr << "NetworkView: Adding Arrow: "; + std::cerr << *sit << " <-> " << *it; + std::cerr << std::endl; + + if(node_ids.find(*sit) != node_ids.end()) + ui.graphicsView->addEdge(node_ids[*sit], node_ids[*it]); + } + } + } + } void NetworkView::insertConnections() { +#if 0 /* iterate through all friends */ std::list fids, ids; std::list::iterator it; - //std::string ownId = rsPeers->getGPGOwnId(); - //rsPeers->getPGPAllList(ids); - //rsPeers->getPGPFriendList(fids); + std::string ownId = rsPeers->getGPGOwnId(); + rsPeers->getPGPAllList(ids); + rsPeers->getPGPFriendList(fids); std::cerr << "NetworkView::insertConnections()" << std::endl; @@ -208,7 +231,6 @@ void NetworkView::insertConnections() std::cerr << std::endl; } -#if 0 int i = 0; for(it = ids.begin(); it != ids.end(); it++, i++) { @@ -267,37 +289,6 @@ void NetworkView::insertConnections() void NetworkView::insertSignatures() { - /* iterate through all friends */ - std::list ids; - std::list::iterator it, sit; - std::string ownId = rsPeers->getGPGOwnId(); - - rsPeers->getGPGAllList(ids); - - std::cerr << "NetworkView::insertSignatures()" << std::endl; - - int i = 0; - for(it = ids.begin(); it != ids.end(); it++, i++) - { - RsPeerDetails detail; - if (!rsPeers->getPeerDetails(*it, detail)) - { - continue; - } - - for(sit = detail.gpgSigners.begin(); sit != detail.gpgSigners.end(); sit++) - { - - if (*it != *sit) - { - std::cerr << "NetworkView: Adding Arrow: "; - std::cerr << *sit << " <-> " << *it; - std::cerr << std::endl; - - ui.graphicsView->addArrow(*sit, *it); - } - } - } } void NetworkView::changedScene() diff --git a/retroshare-gui/src/gui/elastic/arrow.cpp b/retroshare-gui/src/gui/elastic/arrow.cpp index dc4394d01..8ef0991d4 100644 --- a/retroshare-gui/src/gui/elastic/arrow.cpp +++ b/retroshare-gui/src/gui/elastic/arrow.cpp @@ -50,8 +50,10 @@ Arrow::Arrow(Node *sourceNode, Node *destNode) setAcceptedMouseButtons(0); source = sourceNode; dest = destNode; +#ifdef SUSP source->addArrow(this); dest->addArrow(this); +#endif adjust(); } diff --git a/retroshare-gui/src/gui/elastic/edge.cpp b/retroshare-gui/src/gui/elastic/edge.cpp index 7bba05b99..220bb3b55 100644 --- a/retroshare-gui/src/gui/elastic/edge.cpp +++ b/retroshare-gui/src/gui/elastic/edge.cpp @@ -1,36 +1,41 @@ /**************************************************************************** ** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the example classes of the Qt Toolkit. ** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ @@ -88,6 +93,8 @@ void Edge::adjust() QLineF line(mapFromItem(source, 0, 0), mapFromItem(dest, 0, 0)); qreal length = line.length(); + if(length==0.0f) + length=1.0 ; QPointF edgeOffset((line.dx() * 10) / length, (line.dy() * 10) / length); prepareGeometryChange(); @@ -119,21 +126,48 @@ void Edge::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *) painter->setPen(QPen(Qt::black, 1, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin)); painter->drawLine(line); + return ; // Draw the arrows if there's enough room - double angle = ::acos(line.dx() / line.length()); - if (line.dy() >= 0) - angle = TwoPi - angle; - QPointF sourceArrowP1 = sourcePoint + QPointF(sin(angle + Pi / 3) * arrowSize, - cos(angle + Pi / 3) * arrowSize); - QPointF sourceArrowP2 = sourcePoint + QPointF(sin(angle + Pi - Pi / 3) * arrowSize, - cos(angle + Pi - Pi / 3) * arrowSize); - QPointF destArrowP1 = destPoint + QPointF(sin(angle - Pi / 3) * arrowSize, - cos(angle - Pi / 3) * arrowSize); - QPointF destArrowP2 = destPoint + QPointF(sin(angle - Pi + Pi / 3) * arrowSize, - cos(angle - Pi + Pi / 3) * arrowSize); + float length = line.length() ; + float cos_theta,sin_theta ; + + if(length == 0.0f) + { + cos_theta = 1.0f ; + sin_theta = 0.0f ; + } + else + { + cos_theta = line.dx() / length ; + sin_theta =-line.dy() / length ; + } + + static const float cos_pi_over_3 = 0.5 ; + static const float sin_pi_over_3 = 0.5 * sqrt(3) ; + static const float cos_2_pi_over_3 =-0.5 ; + static const float sin_2_pi_over_3 = 0.5 * sqrt(3) ; + + float cos_theta_plus_pi_over_3 = cos_theta * cos_pi_over_3 - sin_theta * sin_pi_over_3 ; + float sin_theta_plus_pi_over_3 = sin_theta * cos_pi_over_3 + cos_theta * sin_pi_over_3 ; + + float cos_theta_mins_pi_over_3 = cos_theta_plus_pi_over_3 + 2 * sin_theta * sin_pi_over_3 ; + float sin_theta_mins_pi_over_3 = sin_theta_plus_pi_over_3 - 2 * cos_theta * sin_pi_over_3 ; + + float cos_theta_plus_2_pi_over_3 = cos_theta * cos_2_pi_over_3 - sin_theta * sin_2_pi_over_3 ; + float sin_theta_plus_2_pi_over_3 = sin_theta * cos_2_pi_over_3 + cos_theta * sin_2_pi_over_3 ; + + float cos_theta_mins_2_pi_over_3 = cos_theta_plus_2_pi_over_3 + 2 * sin_theta * sin_2_pi_over_3 ; + float sin_theta_mins_2_pi_over_3 = sin_theta_plus_2_pi_over_3 - 2 * cos_theta * sin_2_pi_over_3 ; + + QPointF sourceArrowP1 = sourcePoint + QPointF( sin_theta_plus_pi_over_3 * arrowSize, cos_theta_plus_pi_over_3 * arrowSize); + QPointF sourceArrowP2 = sourcePoint + QPointF(sin_theta_plus_2_pi_over_3 * arrowSize, cos_theta_plus_2_pi_over_3 * arrowSize); + + QPointF destArrowP1 = destPoint + QPointF( sin_theta_mins_pi_over_3 * arrowSize, cos_theta_mins_pi_over_3 * arrowSize); + QPointF destArrowP2 = destPoint + QPointF(sin_theta_mins_2_pi_over_3 * arrowSize, cos_theta_mins_2_pi_over_3 * arrowSize); painter->setBrush(Qt::black); - painter->drawPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2); - painter->drawPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); + painter->drawConvexPolygon(QPolygonF() << line.p1() << sourceArrowP1 << sourceArrowP2); + painter->drawConvexPolygon(QPolygonF() << line.p2() << destArrowP1 << destArrowP2); } + diff --git a/retroshare-gui/src/gui/elastic/edge.h b/retroshare-gui/src/gui/elastic/edge.h index 136e7a78b..4a2cc0cd9 100644 --- a/retroshare-gui/src/gui/elastic/edge.h +++ b/retroshare-gui/src/gui/elastic/edge.h @@ -1,73 +1,78 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef EDGE_H -#define EDGE_H - -#include - -class Node; - -class Edge : public QGraphicsItem -{ -public: - Edge(Node *sourceNode, Node *destNode); - ~Edge(); - - Node *sourceNode() const; - void setSourceNode(Node *node); - - Node *destNode() const; - void setDestNode(Node *node); - - void adjust(); - - enum { Type = UserType + 2 }; - int type() const { return Type; } - -protected: - QRectF boundingRect() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -private: - Node *source, *dest; - - QPointF sourcePoint; - QPointF destPoint; - qreal arrowSize; -}; - -#endif +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the example classes of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef EDGE_H +#define EDGE_H + +#include + +class Node; + +class Edge : public QGraphicsItem +{ +public: + Edge(Node *sourceNode, Node *destNode); + ~Edge(); + + Node *sourceNode() const; + void setSourceNode(Node *node); + + Node *destNode() const; + void setDestNode(Node *node); + + void adjust(); + + enum { Type = UserType + 2 }; + int type() const { return Type; } + +protected: + QRectF boundingRect() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +private: + Node *source, *dest; + + QPointF sourcePoint; + QPointF destPoint; + qreal arrowSize; +}; + +#endif diff --git a/retroshare-gui/src/gui/elastic/graphwidget.cpp b/retroshare-gui/src/gui/elastic/graphwidget.cpp index 2a4d8cef6..62d569636 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.cpp +++ b/retroshare-gui/src/gui/elastic/graphwidget.cpp @@ -1,210 +1,207 @@ /**************************************************************************** ** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) ** ** This file is part of the example classes of the Qt Toolkit. ** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. ** ** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ ** ****************************************************************************/ #include "graphwidget.h" #include "edge.h" -#include "arrow.h" #include "node.h" -#include - +#include #include #include #include #include -GraphWidget::GraphWidget(QWidget *parent) - :QGraphicsView(parent), timerId(0) -{ +#define SWAP(a,b) tempr=(a);(a)=(b);(b)=tempr -#if 0 +void fourn(double data[],unsigned long nn[],unsigned long ndim,int isign) +{ + int i1,i2,i3,i2rev,i3rev,ip1,ip2,ip3,ifp1,ifp2; + int ibit,idim,k1,k2,n,nprev,nrem,ntot; + double tempi,tempr; + double theta,wi,wpi,wpr,wr,wtemp; + + ntot=1; + for (idim=1;idim<=ndim;idim++) + ntot *= nn[idim]; + nprev=1; + for (idim=ndim;idim>=1;idim--) { + n=nn[idim]; + nrem=ntot/(n*nprev); + ip1=nprev << 1; + ip2=ip1*n; + ip3=ip2*nrem; + i2rev=1; + for (i2=1;i2<=ip2;i2+=ip1) { + if (i2 < i2rev) { + for (i1=i2;i1<=i2+ip1-2;i1+=2) { + for (i3=i1;i3<=ip3;i3+=ip2) { + i3rev=i2rev+i3-i2; + SWAP(data[i3],data[i3rev]); + SWAP(data[i3+1],data[i3rev+1]); + } + } + } + ibit=ip2 >> 1; + while (ibit >= ip1 && i2rev > ibit) { + i2rev -= ibit; + ibit >>= 1; + } + i2rev += ibit; + } + ifp1=ip1; + while (ifp1 < ip2) { + ifp2=ifp1 << 1; + theta=isign*6.28318530717959/(ifp2/ip1); + wtemp=sin(0.5*theta); + wpr = -2.0*wtemp*wtemp; + wpi=sin(theta); + wr=1.0; + wi=0.0; + for (i3=1;i3<=ifp1;i3+=ip1) { + for (i1=i3;i1<=i3+ip1-2;i1+=2) { + for (i2=i1;i2<=ip3;i2+=ifp2) { + k1=i2; + k2=k1+ifp1; + tempr=wr*data[k2]-wi*data[k2+1]; + tempi=wr*data[k2+1]+wi*data[k2]; + data[k2]=data[k1]-tempr; + data[k2+1]=data[k1+1]-tempi; + data[k1] += tempr; + data[k1+1] += tempi; + } + } + wr=(wtemp=wr)*wpr-wi*wpi+wr; + wi=wi*wpr+wtemp*wpi+wi; + } + ifp1=ifp2; + } + nprev *= n; + } +} + +#undef SWAP + +GraphWidget::GraphWidget(QWidget *) + : timerId(0) +{ QGraphicsScene *scene = new QGraphicsScene(this); scene->setItemIndexMethod(QGraphicsScene::NoIndex); - //scene->setSceneRect(-200, -200, 400, 400); scene->setSceneRect(-200, -200, 1000, 1000); setScene(scene); - centerNode = new Node(this, 1, "You"); - scene->addItem(centerNode); - centerNode->setPos(0, 0); - -#endif - centerNode = NULL; - setCacheMode(CacheBackground); + setViewportUpdateMode(BoundingRectViewportUpdate); setRenderHint(QPainter::Antialiasing); setTransformationAnchor(AnchorUnderMouse); setResizeAnchor(AnchorViewCenter); - scale(0.8, 0.8); - //setMinimumSize(400, 400); - //setMinimumSize(1000, 1000); + + + + scale(qreal(0.8), qreal(0.8)); + setMinimumSize(400, 400); setWindowTitle(tr("Elastic Nodes")); - - clearGraph(); } -bool GraphWidget::clearGraph() +void GraphWidget::clearGraph() { - QGraphicsScene *oldscene = scene(); + QGraphicsScene *oldscene = scene(); - QGraphicsScene *scene = new QGraphicsScene(this); - scene->setItemIndexMethod(QGraphicsScene::NoIndex); - //scene->setSceneRect(-200, -200, 400, 400); - scene->setSceneRect(-200, -200, 1000, 1000); - setScene(scene); + QGraphicsScene *scene = new QGraphicsScene(this); + scene->setItemIndexMethod(QGraphicsScene::NoIndex); + scene->setSceneRect(-200, -200, 1000, 1000); + setScene(scene); - centerNode = new Node(this, 1, rsPeers->getGPGOwnId(), "You"); - scene->addItem(centerNode); - centerNode->setPos(0, 0); +// scene->addItem(centerNode); +// centerNode->setPos(0, 0); - if (oldscene) - { - delete oldscene; - } + if (oldscene != NULL) + { + delete oldscene; + } - nodeMap.clear(); - edgeList.clear(); - arrowList.clear(); - - return true; + _edges.clear(); + _nodes.clear(); } -void GraphWidget::addNode(uint32_t type, std::string id, std::string name) +GraphWidget::NodeId GraphWidget::addNode(const std::string& node_string,uint32_t flags) { - Node *node = new Node(this, type, id, name); - - /* store node */ - nodeMap[id] = node; + Node *node = new Node(node_string,flags,this); + _nodes.push_back(node) ; scene()->addItem(node); - node->setPos(-50 + qrand() % 100 , -50 + qrand() % 100); + node->setPos(-50+rand()%1000/53.0f, -50+rand()%1000/53.0f); + return _nodes.size()-1 ; } - -void GraphWidget::addEdge(std::string id1, std::string id2) +GraphWidget::EdgeId GraphWidget::addEdge(NodeId n1,NodeId n2) { - std::map::iterator it; - Node *n1 = NULL; - Node *n2 = NULL; - - if (id1 == "") - { - n1 = centerNode; - } - else - { - it = nodeMap.find(id1); - if (it != nodeMap.end()) - { - n1 = it->second; - } - } - - it = nodeMap.find(id2); - if (it != nodeMap.end()) - { - n2 = it->second; - } - - if ((n1) && (n2)) - { - Edge *edge = new Edge(n1, n2); - scene()->addItem(edge); - edgeList.push_back(edge); - } + Edge *edge = new Edge(_nodes[n1],_nodes[n2]); + scene()->addItem(edge); + return 0 ; } - -void GraphWidget::addArrow(std::string id1, std::string id2) -{ - std::map::iterator it; - Node *n1 = NULL; - Node *n2 = NULL; - - if (id1 == "") - { - n1 = centerNode; - } - else - { - it = nodeMap.find(id1); - if (it != nodeMap.end()) - { - n1 = it->second; - } - } - - it = nodeMap.find(id2); - if (it != nodeMap.end()) - { - n2 = it->second; - } - - if ((n1) && (n2)) - { - Arrow *arrow = new Arrow(n1, n2); - scene()->addItem(arrow); - arrowList.push_back(arrow); - } -} - void GraphWidget::itemMoved() { if (!timerId) - timerId = startTimer(1000 / 1); + timerId = startTimer(1000 / 25); } void GraphWidget::keyPressEvent(QKeyEvent *event) { switch (event->key()) { - case Qt::Key_Up: - centerNode->moveBy(0, -20); - break; - case Qt::Key_Down: - centerNode->moveBy(0, 20); - break; - case Qt::Key_Left: - centerNode->moveBy(-20, 0); - break; - case Qt::Key_Right: - centerNode->moveBy(20, 0); - break; +// case Qt::Key_Up: +// centerNode->moveBy(0, -20); +// break; +// case Qt::Key_Down: +// centerNode->moveBy(0, 20); +// break; +// case Qt::Key_Left: +// centerNode->moveBy(-20, 0); +// break; +// case Qt::Key_Right: +// centerNode->moveBy(20, 0); +// break; case Qt::Key_Plus: - scaleView(1.2); + scaleView(qreal(1.2)); break; case Qt::Key_Minus: - scaleView(1 / 1.2); + scaleView(1 / qreal(1.2)); break; case Qt::Key_Space: case Qt::Key_Enter: @@ -218,22 +215,95 @@ void GraphWidget::keyPressEvent(QKeyEvent *event) } } +static void convolveWithGaussian(double *forceMap,int S,int s) +{ + static double *bf = NULL ; + + if(bf == NULL) + { + bf = new double[S*S*2] ; + + for(int i=0;i derivative is constant + bf[2*(i+S*j)+1] = 0 ; + } + + unsigned long nn[2] = {S,S}; + fourn(&bf[-1],&nn[-1],2,1) ; + } + + unsigned long nn[2] = {S,S}; + fourn(&forceMap[-1],&nn[-1],2,1) ; + + for(int i=0;i nodes; - foreach (QGraphicsItem *item, scene()->items()) { - if (Node *node = qgraphicsitem_cast(item)) - nodes << node; - } + static const int S = 256 ; + static double *forceMap = new double[2*S*S] ; - foreach (Node *node, nodes) - node->calculateForces(); + memset(forceMap,0,2*S*S*sizeof(double)) ; + QRectF R(scene()->sceneRect()) ; + + foreach (Node *node, _nodes) + { + QPointF pos = node->mapToScene(QPointF(0,0)) ; + + float x = S*(pos.x()-R.left())/R.width() ; + float y = S*(pos.y()- R.top())/R.height() ; + + int i=(int)floor(x) ; + int j=(int)floor(y) ; + float di = x-i ; + float dj = y-j ; + + if( i>=0 && i=0 && jmapToScene(QPointF(0,0)) ; + float x = S*(pos.x()-R.left())/R.width() ; + float y = S*(pos.y()-R.top())/R.height() ; + + node->calculateForces(forceMap,R.width(),R.height(),S,S,x,y,speedf); + } bool itemsMoved = false; - foreach (Node *node, nodes) { + foreach (Node *node, _nodes) { if (node->advance()) itemsMoved = true; } @@ -271,19 +341,19 @@ void GraphWidget::drawBackground(QPainter *painter, const QRectF &rect) painter->drawRect(sceneRect); // Text -// QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, -// sceneRect.width() - 4, sceneRect.height() - 4); -// QString message(tr("Click and drag the nodes around, and zoom with the mouse " -// "wheel or the '+' and '-' keys")); -// -// QFont font = painter->font(); -// font.setBold(true); -// font.setPointSize(14); -// painter->setFont(font); -// painter->setPen(Qt::lightGray); -// painter->drawText(textRect.translated(2, 2), message); -// painter->setPen(Qt::black); -// painter->drawText(textRect, message); + QRectF textRect(sceneRect.left() + 4, sceneRect.top() + 4, + sceneRect.width() - 4, sceneRect.height() - 4); + QString message(tr("Click and drag the nodes around, and zoom with the mouse " + "wheel or the '+' and '-' keys")); + + QFont font = painter->font(); + font.setBold(true); + font.setPointSize(14); + painter->setFont(font); + painter->setPen(Qt::lightGray); + painter->drawText(textRect.translated(2, 2), message); + painter->setPen(Qt::black); + painter->drawText(textRect, message); } void GraphWidget::scaleView(qreal scaleFactor) diff --git a/retroshare-gui/src/gui/elastic/graphwidget.h b/retroshare-gui/src/gui/elastic/graphwidget.h index 5c78e5a22..24acf698b 100644 --- a/retroshare-gui/src/gui/elastic/graphwidget.h +++ b/retroshare-gui/src/gui/elastic/graphwidget.h @@ -1,80 +1,89 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef GRAPHWIDGET_H -#define GRAPHWIDGET_H - -#include -#include -#include -#include - -class Node; -class Edge; -class Arrow; - -class GraphWidget : public QGraphicsView -{ - Q_OBJECT - -public: - GraphWidget(QWidget *parent); - - void itemMoved(); - - bool clearGraph(); - void addNode(uint32_t type, std::string id, std::string name); - void addEdge(std::string id1, std::string id2); - void addArrow(std::string id1, std::string id2); - -protected: - void keyPressEvent(QKeyEvent *event); - void timerEvent(QTimerEvent *event); - void wheelEvent(QWheelEvent *event); - void drawBackground(QPainter *painter, const QRectF &rect); - - void scaleView(qreal scaleFactor); - -private: - int timerId; - Node *centerNode; - - std::map nodeMap; - std::list edgeList; - std::list arrowList; -}; - -#endif +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the example classes of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef GRAPHWIDGET_H +#define GRAPHWIDGET_H + +#include + +class Node; + +class GraphWidget : public QGraphicsView +{ + Q_OBJECT + +public: + GraphWidget(QWidget * = NULL); + + typedef int NodeId ; + 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 ; + + virtual void itemMoved(); + NodeId addNode(const std::string& NodeText,uint32_t flags) ; + EdgeId addEdge(NodeId n1,NodeId n2) ; + + void clearGraph() ; + +protected: + void keyPressEvent(QKeyEvent *event); + void timerEvent(QTimerEvent *event); + void wheelEvent(QWheelEvent *event); + void drawBackground(QPainter *painter, const QRectF &rect); + + void scaleView(qreal scaleFactor); + +private: + int timerId; + //Node *centerNode; + bool mDeterminedBB ; + + std::vector _nodes ; + std::vector _edges ; +}; + +#endif diff --git a/retroshare-gui/src/gui/elastic/node.cpp b/retroshare-gui/src/gui/elastic/node.cpp index 5a037e58c..aac03300f 100644 --- a/retroshare-gui/src/gui/elastic/node.cpp +++ b/retroshare-gui/src/gui/elastic/node.cpp @@ -1,473 +1,297 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#include -#include -#include -#include -#include - -#include "edge.h" -#include "arrow.h" -#include "node.h" -#include "graphwidget.h" -#include -#include "../connect/ConfCertDialog.h" - -#include - -#include - -Node::Node(GraphWidget *graphWidget, uint32_t t, std::string id_in, std::string n) - : graph(graphWidget), ntype(t), id(id_in), name(n), - mDeterminedBB(false) -{ - setFlag(ItemIsMovable); - setZValue(1); -} - -void Node::addEdge(Edge *edge) -{ - edgeList << edge; - edge->adjust(); -} - -QList Node::edges() const -{ - return edgeList; -} - -void Node::addArrow(Arrow *arrow) -{ - arrowList << arrow; - arrow->adjust(); -} - -QList Node::arrows() const -{ - return arrowList; -} - -void Node::calculateForces() -{ - if (!scene() || scene()->mouseGrabberItem() == this) { - newPos = pos(); - return; - } - - // Sum up all forces pushing this item away - qreal xvel = 0; - qreal yvel = 0; - foreach (QGraphicsItem *item, scene()->items()) { - Node *node = qgraphicsitem_cast(item); - if (!node) - continue; - - QLineF line(mapFromItem(node, 0, 0), QPointF(0, 0)); - qreal dx = line.dx(); - qreal dy = line.dy(); - double l = 2.0 * (dx * dx + dy * dy); - if (l > 0) { - xvel += (dx * 150.0) / l; - yvel += (dy * 150.0) / l; - } - } - - - // Now subtract all forces pulling items together - double weight = sqrt(edgeList.size() + 1) * 10; - foreach (Edge *edge, edgeList) { - QPointF pos; - if (edge->sourceNode() == this) - pos = mapFromItem(edge->destNode(), 0, 0); - else - pos = mapFromItem(edge->sourceNode(), 0, 0); - xvel += pos.x() / weight; - yvel += pos.y() / weight; - } - - - // Now subtract all forces pulling items together - // alternative weight?? - weight = sqrt(arrowList.size() + 1) * 10; - foreach (Arrow *arrow, arrowList) { - QPointF pos; - if (arrow->sourceNode() == this) - pos = mapFromItem(arrow->destNode(), 0, 0); - else - pos = mapFromItem(arrow->sourceNode(), 0, 0); - xvel += pos.x() / weight; - yvel += pos.y() / weight; - } - - // push away from edges too. - QRectF sceneRect = scene()->sceneRect(); - int mid_x = (sceneRect.left() + sceneRect.right()) / 2; - int mid_y = (sceneRect.top() + sceneRect.bottom()) / 2; - - if (qAbs(xvel) < 0.1 && qAbs(yvel) < 0.1) - xvel = yvel = 0; - - //newPos = pos() + QPointF(xvel, yvel); - // Increased the velocity for faster settling period. - newPos = pos() + QPointF(5 * xvel, 5 * yvel); - newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); - newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); - - if (ntype == ELASTIC_NODE_TYPE_OWN) - { - /* own one always goes in the middle */ - newPos.setX(mid_x); - newPos.setY(mid_y); - } -} - -bool Node::advance() -{ - if (newPos == pos()) - return false; - - setPos(newPos); - return true; -} - -QRectF Node::boundingRect() const -{ - qreal adjust = 2; - /* add in the size of the text */ - qreal realwidth = 40; - if (mDeterminedBB) - { - realwidth = mBBWidth + adjust; - } - if (realwidth < 23 + adjust) - { - realwidth = 23 + adjust; - } - - return QRectF(-10 - adjust, -10 - adjust, - realwidth, 23 + adjust); - // 23 + adjust, 23 + adjust); -} - - -//QPainterPath Node::shape() const -//{ -// QPainterPath path; -// path.addEllipse(-10, -10, 20, 20); -// return path; -//} - -void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) -{ - painter->setPen(Qt::NoPen); - painter->setBrush(Qt::darkGray); - painter->drawEllipse(-7, -7, 20, 20); - - QColor col0, col1; - if (ntype == ELASTIC_NODE_TYPE_OWN) - { - col0 = QColor(Qt::yellow); - col1 = QColor(Qt::darkYellow); - } - else if (ntype == ELASTIC_NODE_TYPE_FRIEND) - { - col0 = QColor(Qt::green); - col1 = QColor(Qt::darkGreen); - } - else if (ntype == ELASTIC_NODE_TYPE_AUTHED) - { - //col0 = QColor(Qt::cyan); - //col1 = QColor(Qt::darkCyan); - //col0 = QColor(Qt::blue); - - col0 = QColor(Qt::cyan); - col1 = QColor(Qt::darkBlue); - } - else if (ntype == ELASTIC_NODE_TYPE_MARGINALAUTH) - { - col0 = QColor(Qt::magenta); - col1 = QColor(Qt::darkMagenta); - } - else - { - col0 = QColor(Qt::red); - col1 = QColor(Qt::darkRed); - } - - QRadialGradient gradient(-3, -3, 10); - 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 { - gradient.setColorAt(0, col0); - gradient.setColorAt(1, col1); - } - painter->setBrush(gradient); - painter->setPen(QPen(Qt::black, 0)); - painter->drawEllipse(-10, -10, 20, 20); - painter->drawText(-10, 0, QString::fromStdString(name)); - - if (!mDeterminedBB) - { - QRect textBox = painter->boundingRect(-10, 0, 400, 20, 0, QString::fromStdString(name)); - mBBWidth = textBox.width(); - mDeterminedBB = true; - } -} - -QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) -{ - switch (change) { - case ItemPositionHasChanged: - foreach (Edge *edge, edgeList) - edge->adjust(); - foreach (Arrow *arrow, arrowList) - arrow->adjust(); - graph->itemMoved(); - break; - default: - break; - }; - - return QGraphicsItem::itemChange(change, value); -} - -void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) -{ - update(); - QGraphicsItem::mousePressEvent(event); -} - -void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) -{ - update(); - QGraphicsItem::mouseReleaseEvent(event); -} - -void Node::contextMenuEvent(QGraphicsSceneContextMenuEvent *event) -{ - RsPeerDetails details; - if (!rsPeers->getPeerDetails(id, details)) - { - event->accept(); - return; - } - - /* no events for self */ -#if 0 - if (ntype == ELASTIC_NODE_TYPE_OWN) - { - event->accept(); - return; - } -#endif - - QString menuTitle = QString::fromStdString(details.name); - menuTitle += " : "; - - std::cerr << "Node Menu for " << details.name << std::endl; - - QMenu menu; - - switch(ntype) - { - case ELASTIC_NODE_TYPE_OWN: - { - menuTitle += "Ourselves"; - break; - } - case ELASTIC_NODE_TYPE_FRIEND: - { - menuTitle += "Friend"; - break; - } - case ELASTIC_NODE_TYPE_AUTHED: - { - menuTitle += "Authenticated"; - break; - } - case ELASTIC_NODE_TYPE_MARGINALAUTH: - { - menuTitle += "Friend of a Friend"; - break; - } - default: - case ELASTIC_NODE_TYPE_FOF: - { - menuTitle += " Unknown"; - break; - } - } - - QAction *titleAction = menu.addAction(menuTitle); - titleAction->setEnabled(false); - menu.addSeparator(); - - /* find all the peers which have this pgp peer as issuer */ - std::list ids; - std::list::iterator it; - bool haveSSLcerts = false; - - if ((ntype == ELASTIC_NODE_TYPE_AUTHED) || - (ntype == ELASTIC_NODE_TYPE_FRIEND) || - (ntype == ELASTIC_NODE_TYPE_OWN)) - { - rsPeers->getFriendList(ids); - - QAction *addAction = menu.addAction("Add All as Friends"); - QAction *rmAction = menu.addAction("Remove All as Friends"); - - std::cerr << "OthersList looking for ::Issuer " << id << std::endl; - int nssl = 0; - for(it = ids.begin(); it != ids.end(); it++) - { - RsPeerDetails d2; - if (!rsPeers->getPeerDetails(*it, d2)) - continue; - - std::cerr << "OthersList::Id " << d2.id; - std::cerr << " ::Issuer " << d2.issuer << std::endl; - if (d2.issuer == id) - { - QString sslTitle = " SSL ID: "; - sslTitle += QString::fromStdString(d2.location); - - if (RS_PEER_STATE_FRIEND & d2.state) - { - sslTitle += " Allowed"; - } - else - { - sslTitle += " Denied"; - } - - QMenu *sslMenu = menu.addMenu (sslTitle); - if (RS_PEER_STATE_FRIEND & d2.state) - { - sslMenu->addAction("Deny"); - } - else - { - sslMenu->addAction("Allow"); - } - nssl++; - } - } - - if (nssl > 0) - { - menu.addSeparator(); - haveSSLcerts = true; - } - else - { - addAction->setVisible(false); - rmAction->setVisible(false); - - QAction *noAction = menu.addAction("No SSL Certificates for Peer"); - noAction->setEnabled(false); - menu.addSeparator(); - } - } - - - switch(ntype) - { - case ELASTIC_NODE_TYPE_OWN: - { - break; - } - case ELASTIC_NODE_TYPE_FRIEND: - { - menu.addAction("Chat"); - menu.addAction("Msg"); - menu.addSeparator(); - menu.addAction("Connect"); - menu.addSeparator(); - break; - } - case ELASTIC_NODE_TYPE_AUTHED: - { - break; - } - case ELASTIC_NODE_TYPE_MARGINALAUTH: - { - if (haveSSLcerts) - { - menu.addAction("Sign Peer and Add Friend"); - menu.addSeparator(); - } - else - { - menu.addAction("Sign Peer to Authenticate"); - menu.addSeparator(); - } - break; - } - default: - case ELASTIC_NODE_TYPE_FOF: - { - if (haveSSLcerts) - { - menu.addAction("Sign Peer and Add Friend"); - menu.addSeparator(); - } - else - { - menu.addAction("Sign Peer to Authenticate"); - menu.addSeparator(); - } - break; - } - } - - QAction *detailAction = menu.addAction("Peer Details"); - QObject::connect( detailAction , SIGNAL( triggered() ), this, SLOT( peerdetails() ) ); - connect( detailAction , SIGNAL( triggered() ), this, SLOT( peerdetails() ) ); - - menu.addAction("Export Certificate"); - - menu.exec(event->screenPos()); -} - -void Node::peerdetails() -{ - ConfCertDialog::show(id); -} - +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the example classes of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include +#include +#include + +#include + +#include "edge.h" +#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) +{ + setFlag(ItemIsMovable); + setFlag(ItemSendsGeometryChanges); + setCacheMode(DeviceCoordinateCache); + setZValue(1); + mDeterminedBB = false ; + mBBWidth = 0 ; + + _speedx=_speedy=0; + _steps=0; +} + +void Node::addEdge(Edge *edge) +{ + edgeList << edge; + edge->adjust(); +} + +QList Node::edges() const +{ + return edgeList; +} + +static double interpolate(const double *map,int W,int H,float x,float y) +{ + if(x>W-2) x=W-2 ; + if(y>H-2) y=H-2 ; + if(x<0 ) x=0 ; + if(y<0 ) y=0 ; + + int i=(int)floor(x) ; + int j=(int)floor(y) ; + double di = x-i ; + double dj = y-j ; + + return (1-di)*( (1-dj)*map[2*(i+W*j)] + dj*map[2*(i+W*(j+1))]) + +di *( (1-dj)*map[2*(i+1+W*j)] + dj*map[2*(i+1+W*(j+1))]) ; +} + +void Node::calculateForces(const double *map,int width,int height,int W,int H,float x,float y,float speedf) +{ + if (!scene() || scene()->mouseGrabberItem() == this) + { + newPos = pos(); + return; + } + + + // Sum up all forces pushing this item away + qreal xforce = 0; + qreal yforce = 0; + + float dei=0.0f ; + float dej=0.0f ; + + static float *e = NULL ; + static const int KS = 5 ; + + if(e == NULL) + { + e = new float[(2*KS+1)*(2*KS+1)] ; + + for(int i=-KS;i<=KS;++i) + for(int j=-KS;j<=KS;++j) + e[i+KS+(2*KS+1)*(j+KS)] = exp( -(i*i+j*j)/30.0 ) ; // can be precomputed + } + + for(int i=-KS;i<=KS;++i) + for(int j=-KS;j<=KS;++j) + { + int X = std::min(W-1,std::max(0,(int)rint(x))) ; + int Y = std::min(H-1,std::max(0,(int)rint(y))) ; + + float val = map[2*((i+X)%W + W*((j+Y)%H))] ; + + dei += i * e[i+KS+(2*KS+1)*(j+KS)] * val ; + dej += j * e[i+KS+(2*KS+1)*(j+KS)] * val ; + } + + xforce = REPULSION_FACTOR * dei/25.0; + yforce = REPULSION_FACTOR * dej/25.0; + + // Now subtract all forces pulling items together + double weight = (edgeList.size() + 1) ; + foreach (Edge *edge, edgeList) { + QPointF pos; + if (edge->sourceNode() == this) + pos = mapFromItem(edge->destNode(), 0, 0); + else + pos = mapFromItem(edge->sourceNode(), 0, 0); + + float dist = sqrtf(pos.x()*pos.x() + pos.y()*pos.y()) ; + float val = dist - NODE_DISTANCE ; + + xforce += 0.01*pos.x() * val / weight; + yforce += 0.01*pos.y() * val / weight; + } + + static const float friction = 0.4 ; + + xforce -= FRICTION_FACTOR * _speedx ; + yforce -= FRICTION_FACTOR * _speedy ; + + // This term drags nodes away from the sides. + // + if(x < 15) xforce += 100.0/(x+0.1) ; + if(y < 15) yforce += 100.0/(y+0.1) ; + if(x > width-15) xforce -= 100.0/(width-x+0.1) ; + if(y > height-15) yforce -= 100.0/(height-y+0.1) ; + + // now time filter: + + _speedx += xforce / MASS_FACTOR; + _speedy += yforce / MASS_FACTOR; + + if(_speedx > 10) _speedx = 10.0f ; + if(_speedy > 10) _speedy = 10.0f ; + if(_speedx <-10) _speedx =-10.0f ; + if(_speedy <-10) _speedy =-10.0f ; + + QRectF sceneRect = scene()->sceneRect(); + newPos = pos() + QPointF(_speedx, _speedy); + newPos.setX(qMin(qMax(newPos.x(), sceneRect.left() + 10), sceneRect.right() - 10)); + newPos.setY(qMin(qMax(newPos.y(), sceneRect.top() + 10), sceneRect.bottom() - 10)); +} + +bool Node::advance() +{ + if (newPos == pos()) + return false; + + setPos(newPos); + return true; +} + +QRectF Node::boundingRect() const +{ + qreal adjust = 2; + /* add in the size of the text */ + qreal realwidth = 40; + if (mDeterminedBB) + { + realwidth = mBBWidth + adjust; + } + if (realwidth < 23 + adjust) + { + realwidth = 23 + adjust; + } + + return QRectF(-10 - adjust, -10 - adjust, + realwidth, 23 + adjust); +} + +QPainterPath Node::shape() const +{ + QPainterPath path; + path.addEllipse(-10, -10, 20, 20); + return path; +} + +void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *) +{ + 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); + } + + QRadialGradient gradient(-3, -3, 10); + 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 { + gradient.setColorAt(0, col0); + gradient.setColorAt(1, col1); + } + painter->setBrush(gradient); + painter->setPen(QPen(Qt::black, 0)); + painter->drawEllipse(-10, -10, 20, 20); + painter->drawText(-10, 0, QString::fromStdString(_desc_string)); + + if (!mDeterminedBB) + { + QRect textBox = painter->boundingRect(-10, 0, 400, 20, 0, QString::fromStdString(_desc_string)); + mBBWidth = textBox.width(); + mDeterminedBB = true; + } +} + +QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value) +{ + switch (change) { + case ItemPositionHasChanged: + foreach (Edge *edge, edgeList) + edge->adjust(); + graph->itemMoved(); + break; + default: + break; + }; + + return QGraphicsItem::itemChange(change, value); +} + +void Node::mousePressEvent(QGraphicsSceneMouseEvent *event) +{ + update(); + QGraphicsItem::mousePressEvent(event); +} + +void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event) +{ + update(); + QGraphicsItem::mouseReleaseEvent(event); +} diff --git a/retroshare-gui/src/gui/elastic/node.h b/retroshare-gui/src/gui/elastic/node.h index c76b16575..7aa67d1c2 100644 --- a/retroshare-gui/src/gui/elastic/node.h +++ b/retroshare-gui/src/gui/elastic/node.h @@ -1,104 +1,95 @@ -/**************************************************************************** -** -** Copyright (C) 2006-2007 Trolltech ASA. All rights reserved. -** -** This file is part of the example classes of the Qt Toolkit. -** -** This file may be used under the terms of the GNU General Public -** License version 2.0 as published by the Free Software Foundation -** and appearing in the file LICENSE.GPL included in the packaging of -** this file. Please review the following information to ensure GNU -** General Public Licensing requirements will be met: -** http://trolltech.com/products/qt/licenses/licensing/opensource/ -** -** If you are unsure which license is appropriate for your use, please -** review the following information: -** http://trolltech.com/products/qt/licenses/licensing/licensingoverview -** or contact the sales department at sales@trolltech.com. -** -** In addition, as a special exception, Trolltech gives you certain -** additional rights. These rights are described in the Trolltech GPL -** Exception version 1.0, which can be found at -** http://www.trolltech.com/products/qt/gplexception/ and in the file -** GPL_EXCEPTION.txt in this package. -** -** In addition, as a special exception, Trolltech, as the sole copyright -** holder for Qt Designer, grants users of the Qt/Eclipse Integration -** plug-in the right for the Qt/Eclipse Integration to link to -** functionality provided by Qt Designer and its related libraries. -** -** Trolltech reserves all rights not expressly granted herein. -** -** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE -** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. -** -****************************************************************************/ - -#ifndef NODE_H -#define NODE_H - -#include -#include - -#define ELASTIC_NODE_TYPE_OWN 1 -#define ELASTIC_NODE_TYPE_FRIEND 2 -#define ELASTIC_NODE_TYPE_AUTHED 3 -#define ELASTIC_NODE_TYPE_MARGINALAUTH 4 -#define ELASTIC_NODE_TYPE_FOF 5 - -class Edge; -class Arrow; -class GraphWidget; -class QGraphicsSceneMouseEvent; - -class Node : public QObject, public QGraphicsItem -{ - Q_OBJECT - - -public: - Node(GraphWidget *graphWidget, uint32_t t, std::string id_in, std::string n); - - void addEdge(Edge *edge); - QList edges() const; - - void addArrow(Arrow *arrow); - QList arrows() const; - - enum { Type = UserType + 1 }; - int type() const { return Type; } - - void calculateForces(); - bool advance(); - - QRectF boundingRect() const; - //QPainterPath shape() const; - void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); - -public slots: - void peerdetails(); - -protected: - QVariant itemChange(GraphicsItemChange change, const QVariant &value); - - void mousePressEvent(QGraphicsSceneMouseEvent *event); - void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); - void contextMenuEvent(QGraphicsSceneContextMenuEvent *event); - -private: - QList edgeList; - QList arrowList; - QPointF newPos; - GraphWidget *graph; - - /* extra information */ - uint32_t ntype; /* Ourself, friend, fof */ - std::string id; - std::string name; - - bool mDeterminedBB; - uint32_t mBBWidth; - -}; - -#endif +/**************************************************************************** +** +** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). +** Contact: Qt Software Information (qt-info@nokia.com) +** +** This file is part of the example classes of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** Commercial Usage +** Licensees holding valid Qt Commercial licenses may use this file in +** accordance with the Qt Commercial License Agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and Nokia. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain +** additional rights. These rights are described in the Nokia Qt LGPL +** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this +** package. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU General Public License version 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** If you are unsure which license is appropriate for your use, please +** contact the sales department at qt-sales@nokia.com. +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef NODE_H +#define NODE_H + +#include +#include + +#include "graphwidget.h" + +class Edge; +QT_BEGIN_NAMESPACE +class QGraphicsSceneMouseEvent; +QT_END_NAMESPACE + +class Node : public QGraphicsItem +{ +public: + Node(const std::string& node_string,uint32_t flags,GraphWidget *graphWidget); + + void addEdge(Edge *edge); + QList edges() const; + + int type() const { return Type; } + + void calculateForces(const double *data,int width,int height,int W,int H,float x,float y,float speedf); + bool advance(); + + QRectF boundingRect() const; + QPainterPath shape() const; + void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget); + +protected: + virtual QVariant itemChange(GraphicsItemChange change, const QVariant &value); + + virtual void mousePressEvent(QGraphicsSceneMouseEvent *event); + virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event); + +private: + QList edgeList; + QPointF newPos; + GraphWidget *graph; + qreal _speedx,_speedy; + int _steps ; + std::string _desc_string ; + uint32_t _flags ; + bool mDeterminedBB ; + int mBBWidth ; + + static const float MASS_FACTOR = 10 ; + static const float FRICTION_FACTOR = 6.8 ; + static const float REPULSION_FACTOR = 4 ; + static const float NODE_DISTANCE = 130.0 ; +}; + +#endif