Yannick Shpilka , cleaned up
[kgraphinterface.git] / src / graph.cpp~
blob209b30565c6fa8c62a910436971c4643bd291d7a
1 /***************************************************************************
2  *   Copyright (C) 2007 by Schpilka Yannick   *
3  *   schpilka@gmail.com   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  *                                                                         *
20  *   In addition, as a special exception, the copyright holders give       *
21  *   permission to link the code of this program with any edition of       *
22  *   the Qt library by Trolltech AS, Norway (or with modified versions     *
23  *   of Qt that use the same license as Qt), and distribute linked         *
24  *   combinations including the two.  You must obey the GNU General        *
25  *   Public License in all respects for all of the code used other than    *
26  *   Qt.  If you modify this file, you may extend this exception to        *
27  *   your version of the file, but you are not obligated to do so.  If     *
28  *   you do not wish to do so, delete this exception statement from        *
29  *   your version.                                                         *
30  ***************************************************************************/
31 #include "graph.h"
32 #include "edge.h"
33 #include <qpopupmenu.h>
34 #include <qcolordialog.h>
35 #include <qinputdialog.h>
36 #include <qdragobject.h>
37 #include <qcursor.h>
38 #include "node.h"
39 #include <qtooltip.h>
40 #include <qpainter.h>
41 #include <qpen.h>
42 #include <qpoint.h>
44 Graph::Graph(QWidget *parent,QString id):QScrollView(parent,id){
45         //On rend la zone accessible
46         setAcceptDrops(true);
48         //Taille du contenu
49         resizeContents(5000,5000);
51         //Mode normal de visualisation
52         drawing = false;
54         //Les mise a jour lors des signaux
55         connect(this,SIGNAL(nodeAdded()),
56                 this,SLOT(adjustTooltip()));
57         //Les mise a jour lors des signaux
58         connect(this,SIGNAL(edgeCreated()),
59                 this,SLOT(adjustTooltip()));
61         //Signaux necessitant un refresh
62         connect(this,SIGNAL(nodeAdded()),
63                 this,SLOT(update()));
64         //Quand le scroll bouge on redresh pour les liens
65         connect(this,SIGNAL(contentsMoving (int,int)),
66                 this,SLOT(update()));
68         connect(this,SIGNAL(edgeCreated()),
69                 this,SLOT(update()));
72         adjustTooltip();
73         initContextMenu();
77 Graph::~Graph(){
80 /**Ajouter un noeud dans le graphe*/
81 void Graph::operator<<( Node *node ){
82         reparent(viewport(),QPoint(0,0),true);
83         addChild(node);
84         nodes << QString(node->name());
85         node->setStackColor( viewport()->paletteBackgroundColor());
86         node->move(300,300);
87         node->show();
88         emit nodeAdded();
91 void Graph::add (Node *node,QPoint p){
92         addChild(node);
93         nodes << QString(node->name());
94         node->setStackColor( viewport()->paletteBackgroundColor());
95         node->move(p);
96         node->show();
97         connect(node,SIGNAL(nodeMoved()),
98                 this,SLOT(update()));
100         emit nodeAdded();
103 /**Lie deux noeuds*/
104 void Graph::link(Node *source, Node *cible ){
105         edges.append(new Edge(source, cible));
106         emit edgeCreated();
109 /**Lie deux noeuds*/
110 void Graph::link(QString source, QString cible ){
111         edges.append(new Edge((Node*)child(source), (Node*)child(cible)));
112         emit edgeCreated();
115 /** Creation d'un noeud a l'aide de boite de dialogue*/
116 void Graph::createNode(){
117         bool ok;
118         QString text = QInputDialog::getText(
119             "KGraphInterface Node Edition", "Enter node name:", QLineEdit::Normal,
120              QString::null, &ok, this );
121         if (text.isEmpty() || !ok || nodes.contains(text))
122                 return;
124         Node *node = new Node(this,text);
125         connect(node,SIGNAL(nodeMoved()),
126                 this,SLOT(update()));
128         //Creation d'un lien
129         connect(node,SIGNAL(createEdge(QString)),
130                 this,SLOT(beginEdge(QString)));
132         //Creation d'un lien
133         connect(node,SIGNAL(endEdge(QString)),
134                 this,SLOT(endEdge(QString)));
136         addChild(node);
137         nodes << QString(node->name());
138         node->setStackColor( viewport()->paletteBackgroundColor());
139         node->move(300,300);
140         node->show();
141         emit nodeAdded();
144 /** Creation d'un lien a l'aide de boite de dialogue*/
145 void Graph::createEdge(){
146         bool ok;
148         // id source
149         QString src = QInputDialog::getText(
150             "KGraphInterface Edge Edition", "Enter node source id:", QLineEdit::
151 Normal,
152              QString::null, &ok, this );
154         if (src.isEmpty() || !ok)
155                 return;
157         // id cible
158         QString dest = QInputDialog::getText(
159             "KGraphInterface Edge Edition", "Enter node target id:", QLineEdit::
160 Normal,
161              QString::null, &ok, this );
163         if (dest.isEmpty() || !ok)
164                 return;
166         // type
167         QString type = QInputDialog::getText(
168             "KGraphInterface Edge Edition", "Enter edge type:", QLineEdit::Normal,
169              QString::null, &ok, this );
171         if (!ok)
172                 return;
174         if (type.isEmpty())
175                 type = "undirected";
177         if (nodes.contains(src) && nodes.contains(dest))
178                 link((Node*)child(src),(Node*)child(dest));
181 /** Commencer la creation d'un lien a partir d'un noeud source*/
182 void Graph::beginEdge(QString source){
183         if (child(source) == 0)
184                 return;
185         //mode dessin
186         drawing = true;
187         //centre du noeud surce
188         start_drawing_edge = ((QWidget*)child(source))->pos();
189         //on retient l'id
190         source_drawing_edge = source;
191         //on observe les mouvements de la souris
192         viewport()->setMouseTracking(true);
195 /** Terminer la creation d'un lien a partir d'un noeud cible*/
196 void Graph::endEdge(QString target){
197         if (!drawing)
198                 return;
200         if (child(target) == 0){
201                 cancelEdge();
202                 return;
203         }
204         if (target == source_drawing_edge)
205                 return;
207         link((Node*)child(source_drawing_edge),(Node*)child(target));
208         cancelEdge();
211 /** Annuler la creation d'un lien*/
212 void Graph::cancelEdge(){
213         QPoint p(0,0);
214         start_drawing_edge = p;
215         viewport()->setMouseTracking(false);
216         drawing = false;
217         update();
220 /** Montre une vue d'ensemble du graphe */
221 void Graph::showOverview(){
225 /** Ouvrir une boite de dialogue de choix de couleur*/
226 void Graph::openColorDlg(){
227         QColor c;
228         c = QColorDialog::getColor(c,this,"colordlg");
231 /**Dessin du graphe*/
232 void Graph::paintEvent(QPaintEvent *ev){
233         viewport()->repaint();
235         QPainter painter(viewport());
236         painter.setWindow(viewport()->rect());
237         
238         QColor color = viewport()->paletteBackgroundColor();
239         //on inverse la couleur de fond pour ecrire le titre
240         int r = 255 - color.red();
241         int g = 255 - color.green();
242         int b = 255 - color.blue();
244         painter.setPen(QColor(r,g,b));
247         painter.save();
248         //Nom du graphe toujours visible
249         painter.drawText(QPoint(30,30),"Graph : " + QString(name()));
251         if (drawing)
252                 painter.drawLine(start_drawing_edge,viewport()->mapFromGlobal(QCursor::pos()));
254         //Edges
255         Edge *e;
256         for ( e = edges.first(); e; e = edges.next() )
257                 e->draw(&painter);
259         painter.restore();
262 /** Drag d'un noeud ou couleur*/
263 void Graph::dragEnterEvent(QDragEnterEvent *event){
264         if (QColorDrag::canDecode(event))
265                 event->accept();
268 /** Drop d'un noeud ou couleur */
269 void Graph::dropEvent(QDropEvent *event){
270         QColor c;
271         if ( QColorDrag::decode(event, c) ){
272                 viewport()->setPaletteBackgroundColor(c);
273                 for ( QStringList::Iterator it = nodes.begin(); it != nodes.end(
274 ); ++it )
275                         ((Node*)child(*it))->setStackColor(c);
276         }
277         update();
280 /** Met a jour le tooltip */
281 void Graph::adjustTooltip(){
282         QString strInfos;
283         strInfos = "Graph\n";
284         strInfos.append("\nName:        " + QString(name()));
285         strInfos.append("\nNbr nodes:   " + QString::number(nodes.size()));
286         strInfos.append("\nNbr edges:   " + QString::number(edges.count()));
287         QToolTip::add( this, strInfos);
290 /** Initialisation du menu contextuel */
291 void Graph::initContextMenu(){
292         context_menu = new QPopupMenu;
293         context_menu->insertItem( "create node",  this, SLOT(createNode()));
294         context_menu->insertItem( "create edge", this, SLOT(createEdge()));
295         context_menu->insertItem( "open color dialog", this, SLOT(openColorDlg()                              ));
298 /** On bouge la souris dans le graphe (perçu si mousetracking true)*/
299 void Graph::contentsMouseMoveEvent ( QMouseEvent * e ){
300         update();
303 /** Pop du menu contextuel*/
304 void Graph::mouseReleaseEvent(QMouseEvent *event){
305         if (drawing){
306                 cancelEdge();
307                 return;
308         }
309         if (event->button() == Qt::RightButton){
310                 context_menu->exec( QCursor::pos());
311         }
314 QString Graph::toXml(){
315         QString res;
317         /**Graphe*/
318         res = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
319         res.append("\n<!DOCTYPE gi>");
320         res.append("\n<gi version=\"1.0\">");
321         res.append("\n     <graph id=\"" + QString(name()) + "\">");
323         res.append("<!-- Nodes Definition -->");
325           for ( QStringList::Iterator it = nodes.begin(); it != nodes.end(
326 ); ++it )
327                 res.append(((Node*)child(*it))->toXml());
329         /**Liens*/
330         
331         Edge *e;
332         for ( e = edges.first(); e; e = edges.next() ){
333                 res.append(e->toXml());
334         }
336         res.append("\n     </graph>");
337         res.append("\n</gi>\n");
338         return res;
342 #include "graph.moc"