1 /***************************************************************************
2 * Copyright (C) 2007 by Schpilka Yannick *
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. *
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. *
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. *
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 *
30 ***************************************************************************/
33 #include <qpopupmenu.h>
34 #include <qcolordialog.h>
35 #include <qinputdialog.h>
36 #include <qdragobject.h>
44 Graph::Graph(QWidget *parent,QString id):QScrollView(parent,id){
45 //On rend la zone accessible
49 resizeContents(5000,5000);
51 //Mode normal de visualisation
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()),
64 //Quand le scroll bouge on redresh pour les liens
65 connect(this,SIGNAL(contentsMoving (int,int)),
68 connect(this,SIGNAL(edgeCreated()),
80 /**Ajouter un noeud dans le graphe*/
81 void Graph::operator<<( Node *node ){
82 reparent(viewport(),QPoint(0,0),true);
84 nodes << QString(node->name());
85 node->setStackColor( viewport()->paletteBackgroundColor());
91 void Graph::add (Node *node,QPoint p){
93 nodes << QString(node->name());
94 node->setStackColor( viewport()->paletteBackgroundColor());
97 connect(node,SIGNAL(nodeMoved()),
104 void Graph::link(Node *source, Node *cible ){
105 edges.append(new Edge(source, cible));
110 void Graph::link(QString source, QString cible ){
111 edges.append(new Edge((Node*)child(source), (Node*)child(cible)));
115 /** Creation d'un noeud a l'aide de boite de dialogue*/
116 void Graph::createNode(){
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))
124 Node *node = new Node(this,text);
125 connect(node,SIGNAL(nodeMoved()),
126 this,SLOT(update()));
129 connect(node,SIGNAL(createEdge(QString)),
130 this,SLOT(beginEdge(QString)));
133 connect(node,SIGNAL(endEdge(QString)),
134 this,SLOT(endEdge(QString)));
137 nodes << QString(node->name());
138 node->setStackColor( viewport()->paletteBackgroundColor());
144 /** Creation d'un lien a l'aide de boite de dialogue*/
145 void Graph::createEdge(){
149 QString src = QInputDialog::getText(
150 "KGraphInterface Edge Edition", "Enter node source id:", QLineEdit::
152 QString::null, &ok, this );
154 if (src.isEmpty() || !ok)
158 QString dest = QInputDialog::getText(
159 "KGraphInterface Edge Edition", "Enter node target id:", QLineEdit::
161 QString::null, &ok, this );
163 if (dest.isEmpty() || !ok)
167 QString type = QInputDialog::getText(
168 "KGraphInterface Edge Edition", "Enter edge type:", QLineEdit::Normal,
169 QString::null, &ok, this );
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)
187 //centre du noeud surce
188 start_drawing_edge = ((QWidget*)child(source))->pos();
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){
200 if (child(target) == 0){
204 if (target == source_drawing_edge)
207 link((Node*)child(source_drawing_edge),(Node*)child(target));
211 /** Annuler la creation d'un lien*/
212 void Graph::cancelEdge(){
214 start_drawing_edge = p;
215 viewport()->setMouseTracking(false);
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(){
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());
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));
248 //Nom du graphe toujours visible
249 painter.drawText(QPoint(30,30),"Graph : " + QString(name()));
252 painter.drawLine(start_drawing_edge,viewport()->mapFromGlobal(QCursor::pos()));
256 for ( e = edges.first(); e; e = edges.next() )
262 /** Drag d'un noeud ou couleur*/
263 void Graph::dragEnterEvent(QDragEnterEvent *event){
264 if (QColorDrag::canDecode(event))
268 /** Drop d'un noeud ou couleur */
269 void Graph::dropEvent(QDropEvent *event){
271 if ( QColorDrag::decode(event, c) ){
272 viewport()->setPaletteBackgroundColor(c);
273 for ( QStringList::Iterator it = nodes.begin(); it != nodes.end(
275 ((Node*)child(*it))->setStackColor(c);
280 /** Met a jour le tooltip */
281 void Graph::adjustTooltip(){
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 ){
303 /** Pop du menu contextuel*/
304 void Graph::mouseReleaseEvent(QMouseEvent *event){
309 if (event->button() == Qt::RightButton){
310 context_menu->exec( QCursor::pos());
314 QString Graph::toXml(){
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(
327 res.append(((Node*)child(*it))->toXml());
332 for ( e = edges.first(); e; e = edges.next() ){
333 res.append(e->toXml());
336 res.append("\n </graph>");
337 res.append("\n</gi>\n");