NCL Composer  0.1.5
 All Classes Functions Variables Pages
qnstview.cpp
1 #include "qnstview.h"
2 
3 //
4 // ATTENTION: This code needs a refactoring.
5 //
6 
7 #include <assert.h>
8 #include <QDebug>
9 
10 #ifdef SMOOTH_ZOOM
11 #include <QTimeLine>
12 #endif
13 
14 #include "qnstutil.h"
15 
16 #include "qnstgraphicsbind.h"
17 
18 std::map <Qnst::EntityType, QString> QnstView::mediaTypeToXMLStr =
20  (Qnst::Media, "media")
21  (Qnst::Image, "image")
22  (Qnst::Audio, "audio")
23  (Qnst::Video, "video")
24  (Qnst::Html, "text/html")
25  (Qnst::NCL, "application/x-ginga-NCL")
26  (Qnst::Text, "text")
27  (Qnst::NCLua, "application/x-ginga-NCLua")
28  (Qnst::Settings, "application/x-ncl-settings");
29 
30 QnstView::QnstView(QWidget* parent)
31  : QGraphicsView(parent)
32 {
33  createObjects();
34  createConnection();
35 
36  zoomStep = 0;
37 
38 #ifdef SMOOTH_ZOOM
39  _numScheduledScalings = 0;
40 #endif
41  linking = false;
42 
43  modified = false;
44 
45  link = NULL;
46 
47  selected = NULL;
48 
49  clipboard = NULL;
50 
51  hasCutted = false;
52 
53  lastLinkMouseOver = NULL;
54 
55  // Initialize entity counters
56  for(int i = Qnst::Node; i < Qnst::NoType; i += 1)
57  entityCounter[ (Qnst::EntityType) i ] = 0;
58 }
59 
60 QnstView::~QnstView()
61 {
62 
63 }
64 
65 void QnstView::load(QString data)
66 {
67  qDebug() << "###########################################";
68  qDebug() << data;
69  qDebug() << "###########################################";
70 
71  QDomDocument* dom = new QDomDocument();
72  dom->setContent(data);
73 
74  QDomElement parent = dom->firstChildElement();
75 
76  QDomNodeList list = parent.childNodes();
77 
78  for (unsigned int i = 0; i < list.length(); i++)
79  {
80  if (list.item(i).isElement())
81  {
82  QDomElement e = list.item(i).toElement();
83 
84  read(e, parent);
85  }
86  }
87 
88  for (unsigned int i = 0; i < list.length(); i++)
89  {
90  if (list.item(i).isElement())
91  {
92  QDomElement e = list.item(i).toElement();
93 
94  readLink(e, parent);
95  }
96  }
97 
98  for (unsigned int i = 0; i < list.length(); i++)
99  {
100  if (list.item(i).isElement())
101  {
102  QDomElement e = list.item(i).toElement();
103 
104  if (e.nodeName() == "context" ||
105  e.nodeName() == "switch" ||
106  e.nodeName() == "body")
107  {
108  collapseCompositions(e, parent);
109  }
110  }
111  }
112 
113  foreach (QnstGraphicsEntity* entity, entities.values())
114  {
115  if (entity->isMedia())
116  {
117  qDebug() << "=========================================" << entity->getnstId();
118  adjustMedia((QnstGraphicsMedia*) entity);
119  }
120 
121  entity->adjust();
122  }
123 
124  deletePendingEntities();
125 }
126 
127 void QnstView::collapseCompositions(QDomElement element, QDomElement parent)
128 {
129  QDomNodeList list = element.childNodes();
130 
131  for (unsigned int i = 0; i < list.length(); i++)
132  {
133  if (list.item(i).isElement())
134  {
135  QDomElement e = list.item(i).toElement();
136 
137  if (e.nodeName() == "context" ||
138  e.nodeName() == "switch" ||
139  e.nodeName() == "body")
140  {
141  collapseCompositions(e, parent);
142  }
143  }
144  }
145 
146  if (element.attribute("collapsed") == "1")
147  {
148  if(entities.contains(element.attribute("uid")))
149  {
151  ((QnstGraphicsComposition*) entities[element.attribute("uid")]);
152 
153  c->collapse();
154 
155  c->setTop(element.attribute("top").toDouble());
156  c->setLeft(element.attribute("left").toDouble());
157  }
158  }
159 }
160 
161 void QnstView::read(QDomElement element, QDomElement parent)
162 {
163  QMap<QString, QString> properties;
164 
165  QString uid = element.attribute("uid");
166 
167  // \todo before fill the properties, check if we are a valid element.
168 
169  // Fill common properties
170  properties["TYPE"] = element.nodeName();
171  QDomNamedNodeMap attributeMap = element.attributes();
172 
173  // copy every attribute from XML to proerties variable
174  for (int i = 0; i < attributeMap.count(); ++i)
175  {
176  QDomNode attribute = attributeMap.item(i);
177  properties[attribute.nodeName()] = attribute.nodeValue();
178  }
179  // end fill
180 
181  if (element.nodeName() == "body" ||
182  element.nodeName() == "context" ||
183  element.nodeName() == "switch" ||
184  element.nodeName() == "media" ||
185  element.nodeName() == "port" ||
186  element.nodeName() == "switchPort" ||
187  element.nodeName() == "property" ||
188  element.nodeName() == "area")
189  {
190  if(element.nodeName() == "body")
191  addEntity(uid, "", properties, true);
192  else
193  addEntity(uid, parent.attribute("uid"), properties, true, false);
194  }
195  else if (element.nodeName() == "interfaceReference")
196  {
197 // deprecated since version 0.1.2
198 // interfaceRefers[element.attribute("interfaceReferUID")] =
199 // element.attribute("interfaceOriginUID");
200  }
201  else if (element.nodeName() == "nodeReference")
202  {
203  refers[element.attribute("nodeReferUID")] =
204  element.attribute("nodeOriginUID");
205  }
206  else if (element.nodeName() == "importBase")
207  {
208  importBases[element.attribute("uid")] = element.attribute("connUID");
209  }
210  else if (element.nodeName() == "connector")
211  {
212  QnstConnector* conn = new QnstConnector();
213  conn->setnstUid(element.attribute("uid"));
214  conn->setName(element.attribute("id"));
215 
216  QDomNodeList list = element.childNodes();
217 
218  for (unsigned int i=0;i<list.length();i++)
219  {
220  if (list.item(i).isElement())
221  {
222  QDomElement e = list.item(i).toElement();
223 
224  if (e.nodeName() == "condition")
225  {
226  if (e.attribute("uid") != "")
227  conn->addCondition(e.attribute("uid"), e.attribute("type"));
228  else
229  conn->addCondition(e.attribute("type"), e.attribute("type"));
230  }
231  else if (e.nodeName() == "action")
232  {
233  if (e.attribute("uid") != "")
234  conn->addAction(e.attribute("uid"), e.attribute("type"));
235  else
236  conn->addAction(e.attribute("type"), e.attribute("type"));
237  }
238  else if (e.nodeName() == "param")
239  {
240  if (e.attribute("type") == "action")
241  {
242  conn->addActionParam(e.attribute("uid"), e.attribute("name"), e.attribute("value"));
243  }
244  else if (e.attribute("type") == "condition")
245  {
246  conn->addConditionParam(e.attribute("uid"), e.attribute("name"), e.attribute("value"));
247  }
248  else
249  {
250  // maintaining compatibility with old versions (< v0.1.5)
251  conn->addActionParam(e.attribute("name"), "", e.attribute("name"));
252  conn->addConditionParam(e.attribute("name"), "", e.attribute("name"));
253  }
254  }
255  }
256  }
257 
258  connectors[conn->getName()] = conn;
259  connectors2[conn->getnstUid()] = conn;
260 
261  return;
262  }
263  // \fixme This is deprecated since version 0.1.3 and is here only for
264  // compatibility! We will remove it soon!!
265  else if(element.nodeName() == "aggregator")
266  {
267  // \todo Look for link that point to this aggregatorUID and set its position
268  // to the position saved by aggregator element.
269  }
270 
271  QDomNodeList list = element.childNodes();
272 
273  for (unsigned int i=0;i<list.length();i++)
274  {
275  if (list.item(i).isElement())
276  {
277  QDomElement e = list.item(i).toElement();
278 
279  read(e, element);
280  }
281  }
282 }
283 
284 void QnstView::readLink(QDomElement element, QDomElement parent)
285 {
286  // \fixme Why this is here, and not inside the read method ?
287  QMap<QString, QString> properties;
288 
289  if (element.nodeName() == "linkdata" || //linkdata is deprecated since version
290  // 0.1.3. And is here only for
291  // compatibility issues.
292  element.nodeName() == "link")
293  {
294  // Fill common properties
295  properties["TYPE"] = "link";
296  // This block of code is here only for compatibility with older versions,
297  // since in older version we were saving with the name "xconnetor"
298  if(element.hasAttribute("xconnetor"))
299  properties["xconnector"] = element.attribute("xconnetor");
300  if(element.hasAttribute("xconnetorUID"))
301  properties["xconnectorUID"] = element.attribute("xconnetorUID");
302  // end compatibility block of code
303 
304  // copy every attribute from XML to proerties variable
305  QDomNamedNodeMap attributeMap = element.attributes();
306  for (int i = 0; i < attributeMap.count(); ++i)
307  {
308  QDomNode attribute = attributeMap.item(i);
309  properties[attribute.nodeName()] = attribute.nodeValue();
310  }
311  // end fill
312 
313  addEntity(element.attribute("uid"),
314  element.attribute("parent"),
315  properties,
316  true);
317  }
318  else if (element.nodeName() == "mapping")
319  {
320 
321  properties["TYPE"] = element.nodeName();
322  // copy every attribute from XML to proerties variable
323  QDomNamedNodeMap attributeMap = element.attributes();
324  for (int i = 0; i < attributeMap.count(); ++i)
325  {
326  QDomNode attribute = attributeMap.item(i);
327  properties[attribute.nodeName()] = attribute.nodeValue();
328  }
329  // end fill
330 
331  addEntity(properties["uid"],
332  element.attribute("switchportUid"),
333  properties,
334  true);
335  }
336  else if (element.nodeName() == "port")
337  {
338  if (entities.contains(element.attribute("uid")))
339  {
340  if (entities.contains(element.attribute("interfaceUID")))
341  {
342  QnstGraphicsInterface* entitya = (QnstGraphicsInterface*) entities[element.attribute("uid")];
343  QnstGraphicsInterface* entityb = (QnstGraphicsInterface*) entities[element.attribute("interfaceUID")];
344 
345  if (entitya != entityb)
346  {
348  entity->setEntityA(entitya);
349  entity->setEntityB(entityb);
350  entity->adjust();
351 
352  entitya->getnstGraphicsParent()->addnstGraphicsEntity(entity);
353 
354  entitya->addnstGraphicsEdge(entity);
355  entityb->addnstGraphicsEdge(entity);
356  }
357  }
358  else if (entities.contains(element.attribute("componentUID")))
359  {
360  QnstGraphicsInterface* entitya =
361  (QnstGraphicsInterface*)entities[element.attribute("uid")];
362 
363  QnstGraphicsNode* entityb =
364  (QnstGraphicsNode*)entities[element.attribute("componentUID")];
365 
367  entity->setEntityA(entitya);
368  entity->setEntityB(entityb);
369  entity->adjust();
370 
371  entitya->getnstGraphicsParent()->addnstGraphicsEntity(entity);
372 
373  entitya->addnstGraphicsEdge(entity);
374  entityb->addnstGraphicsEdge(entity);
375  }
376  }
377  }
378  else if (element.nodeName() == "bind")
379  {
380  if (!entities.contains(element.attribute("uid")) &&
381  links.contains(element.attribute("linkUID")))
382  {
383  // Fill common properties
384  properties["TYPE"] = "bind";
385  QDomNamedNodeMap attributeMap = element.attributes();
386 
387  // copy every attribute from XML to proerties variable
388  for (int i = 0; i < attributeMap.count(); ++i)
389  {
390  QDomNode attribute = attributeMap.item(i);
391  properties[attribute.nodeName()] = attribute.nodeValue();
392  }
393 
394  addEntity(properties["uid"],
395  entities[element.attribute("linkUID")]->getnstParent()->getnstUid(),
396  properties,
397  true);
398  // end fill
399 
400  // SET THE BIND PARAMS
401  // Add bindParams to the entity that we just added to model
402  if(entities.contains(properties["uid"]))
403  {
404  QnstGraphicsBind *bind =
405  dynamic_cast<QnstGraphicsBind *> (entities[properties["uid"]]);
406 
407  if(bind)
408  {
409  QMap<QString, QString> params;
410  QMap<QString, QString> name_uid;
411 
412  // Load from XML
413  QDomNodeList list = element.childNodes();
414  for (unsigned int i=0;i<list.length();i++)
415  {
416  if (list.item(i).isElement())
417  {
418  QDomElement e = list.item(i).toElement();
419 
420  if (e.nodeName() == "param")
421  {
422  params[e.attribute("name")] = e.attribute("value");
423  name_uid[e.attribute("name")] = e.attribute("uid");
424 
425  bindParamUIDToBindUID[e.attribute("uid")] = bind->getnstUid();
426  }
427  }
428  }
429 
430  // Set bindParams
431  bind->setParams(params);
432  bind->setNamesUIDs(name_uid);
433 
434  connect(bind,
435  SIGNAL(bindParamAdded(QString,QString,QMap<QString, QString>)),
436  SLOT(requestBindParamAdjust(QString,QString,QMap<QString, QString>)));
437 
438  connect(bind,
439  SIGNAL(bindParamUpdated(QString,QMap<QString,QString>,QMap<QString,QString>)),
440  SLOT(updateBindParams(QString,QMap<QString,QString>,QMap<QString,QString>)));
441 
442  }
443  }
444  }
445  else
446  {
447  qWarning() << "[QNST] Warning!! Trying to add a bind to a link that \
448  does not exists!! It will be ignored!!";
449  }
450  //FINISH BIND PARAMS
451  }
452 
453  QDomNodeList list = element.childNodes();
454  for (unsigned int i=0;i<list.length();i++)
455  {
456  if (list.item(i).isElement())
457  {
458  QDomElement e = list.item(i).toElement();
459 
460  readLink(e, element);
461  }
462  }
463 }
464 
465 QString QnstView::serialize()
466 {
467  QDomDocument* dom = new QDomDocument();
468  QDomElement root = dom->createElement("qnst");
469 
470  foreach(QString key, importBases.keys())
471  {
472  QDomElement e = dom->createElement("importBase");
473 
474  e.setAttribute("uid", key);
475  e.setAttribute("connUID", importBases[key]);
476 
477  root.appendChild(e);
478  }
479 
480  foreach(QnstConnector* conn, connectors.values())
481  {
482  assert(conn != NULL);
483 
484  QDomElement e = dom->createElement("connector");
485 
486  e.setAttribute("id", conn->getName());
487  e.setAttribute("uid", conn->getnstUid());
488 
489  foreach(QString k, conn->getConditions().keys())
490  {
491  QDomElement c = dom->createElement("condition");
492  c.setAttribute("uid", k); // since version 0.1.5
493  c.setAttribute("type", conn->getConditions().value(k));
494 
495  e.appendChild(c);
496  }
497 
498  foreach(QString k, conn->getActions().keys())
499  {
500  QDomElement a = dom->createElement("action");
501  a.setAttribute("uid", k); // since version 0.1.5
502  a.setAttribute("type", conn->getActions().value(k));
503 
504  e.appendChild(a);
505  }
506 
507 // deprecated since version 0.1.5
508 // foreach(QString key, conn->getParams().keys())
509 // {
510 // QDomElement p = dom->createElement("param");
511 
512 // p.setAttribute("uid", key);
513 // p.setAttribute("name", conn->getParams()[key]);
514 
515 // e.appendChild(p);
516 // }
517 
518  QPair<QString, QString> key;
519 
520  foreach(key, conn->getActionParams().keys())
521  {
522  QDomElement p = dom->createElement("param");
523 
524  p.setAttribute("uid", key.first);
525  p.setAttribute("name", key.second);
526  p.setAttribute("value", conn->getActionParams().value(key));
527  p.setAttribute("type", "action");
528 
529  e.appendChild(p);
530  }
531 
532  foreach(key, conn->getConditionParams().keys())
533  {
534  QDomElement p = dom->createElement("param");
535 
536  p.setAttribute("uid", key.first);
537  p.setAttribute("name", key.second);
538  p.setAttribute("value", conn->getConditionParams().value(key));
539  p.setAttribute("type", "condition");
540 
541  e.appendChild(p);
542  }
543 
544  root.appendChild(e);
545  }
546 
547 // // deprecated since version 0.1.2
548 // foreach(QString key, interfaceRefers.keys())
549 // {
550 // QDomElement e = dom->createElement("interfaceReference");
551 
552 // e.setAttribute("interfaceReferUID", key);
553 // e.setAttribute("interfaceOriginUID", interfaceRefers[key]);
554 
555 // root.appendChild(e);
556 // }
557 
558  foreach(QString key, refers.keys())
559  {
560  QDomElement e = dom->createElement("nodeReference");
561 
562  e.setAttribute("nodeReferUID", key);
563  e.setAttribute("nodeOriginUID", refers[key]);
564 
565  root.appendChild(e);
566  }
567 
568  foreach(QnstGraphicsLink* link, links.values())
569  {
570  QDomElement e = dom->createElement("link"); // Previously from 0.1.3 thi was linkdata
571 
572  e.setAttribute("id", link->getnstId());
573  e.setAttribute("uid", link->getnstUid());
574 
575  e.setAttribute("top", link->getTop());
576  e.setAttribute("left", link->getLeft());
577  e.setAttribute("width", link->getWidth());
578  e.setAttribute("height", link->getHeight());
579 
580  // \fixme Be careful, there are cases where even with no body element the
581  // links map is not empty!
582 // if(link->getnstParent() != NULL)
583 // {
584  e.setAttribute("parent",
585  link->getnstParent()->getnstUid());
586 // }
587 
588  e.setAttribute("xconnector", link->getxConnector());
589  e.setAttribute("xconnectorUID", link->getxConnectorUID());
590 
591  // \fixme This is deprecated since version 0.1.3
592  // e.setAttribute("aggregatorUID", link->getAggregatorUID());
593 
594  root.appendChild(e);
595  }
596 
597  foreach(QnstGraphicsEntity* entity, scene->getRoots())
598  {
599  QDomElement e = dom->createElement("body");
600 
601  e.setAttribute("id", entity->getnstId());
602  e.setAttribute("uid", entity->getnstUid());
603 
604  e.setAttribute("top", entity->getTop());
605  e.setAttribute("left", entity->getLeft());
606  e.setAttribute("width", entity->getWidth());
607  e.setAttribute("height", entity->getHeight());
608 
609  e.setAttribute("collapsed", ((QnstGraphicsComposition*) entity)->isCollapsed());
610 
611  e.setAttribute("expandWidth", ((QnstGraphicsComposition*) entity)->getLastW());
612  e.setAttribute("expandHeight", ((QnstGraphicsComposition*) entity)->getLastH());
613 
614  foreach(QnstGraphicsEntity* c, entity->getnstGraphicsEntities())
615  {
616  write(e, dom, c);
617  }
618 
619  writeLink(e, dom, entity);
620 
621  root.appendChild(e);
622  }
623 
624  dom->appendChild(root);
625 
626  linkWriterAux.clear();
627 
628  return dom->toString(4);
629 }
630 
631 void QnstView::write(QDomElement element, QDomDocument* dom,
632  QnstGraphicsEntity* entity)
633 {
634  QDomElement e;
635 
636  switch(entity->getnstType())
637  {
638  case Qnst::Body:
639  e = dom->createElement("body");
640 
641  e.setAttribute("collapsed", ((QnstGraphicsComposition*) entity)->isCollapsed());
642 
643  e.setAttribute("expandWidth", ((QnstGraphicsComposition*) entity)->getLastW());
644  e.setAttribute("expandHeight", ((QnstGraphicsComposition*) entity)->getLastH());
645  break;
646 
647  case Qnst::Context:
648  e = dom->createElement("context");
649 
650  e.setAttribute("collapsed", ((QnstGraphicsComposition*) entity)->isCollapsed());
651 
652  e.setAttribute("expandWidth", ((QnstGraphicsComposition*) entity)->getLastW());
653  e.setAttribute("expandHeight", ((QnstGraphicsComposition*) entity)->getLastH());
654  break;
655 
656  case Qnst::Switch:
657  e = dom->createElement("switch");
658 
659  e.setAttribute("collapsed", ((QnstGraphicsComposition*) entity)->isCollapsed());
660 
661  e.setAttribute("expandWidth", ((QnstGraphicsComposition*) entity)->getLastW());
662  e.setAttribute("expandHeight", ((QnstGraphicsComposition*) entity)->getLastH());
663  break;
664 
665  case Qnst::Media:
666  case Qnst::Image:
667  case Qnst::Audio:
668  case Qnst::Video:
669  case Qnst::Html:
670  case Qnst::NCL:
671  case Qnst::Text:
672  case Qnst::Settings:
673  case Qnst::NCLua:
674  e = dom->createElement("media");
675 
676  e.setAttribute("type", mediaTypeToXMLStr[entity->getnstType()]);
677 
678  if (((QnstGraphicsMedia*) entity)->getSource() != "" )
679  {
680  e.setAttribute("src", ((QnstGraphicsMedia*) entity)->getSource());
681  }
682 
683  e.setAttribute("refer", ((QnstGraphicsMedia*) entity)->getRefer());
684  e.setAttribute("referUID", ((QnstGraphicsMedia*) entity)->getReferUID());
685  e.setAttribute("instance", ((QnstGraphicsMedia*) entity)->getInstance());
686  break;
687 
688  case Qnst::Property:
689  e = dom->createElement("property");
690 
691  if (((QnstGraphicsInterface*) entity)->isRefer())
692  e.setAttribute("isRefer","true");
693 
694  break;
695 
696  case Qnst::SwitchPort:
697  e = dom->createElement("switchPort");
698  break;
699 
700  case Qnst::Area:
701  e = dom->createElement("area");
702 
703  if (((QnstGraphicsInterface*) entity)->isRefer())
704  e.setAttribute("isRefer","true");
705 
706  break;
707 
708  case Qnst::Aggregator:
709  // \fixme This is deprecated!! Now, aggregator is the same of link!!
710  // e = dom->createElement("aggregator");
711  break;
712 
713  case Qnst::Port:
714  {
715  e = dom->createElement("port");
716 
717  QnstGraphicsPort* pentity = ((QnstGraphicsPort*) entity);
718 
719  foreach(QnstGraphicsEdge* edge, pentity->getnstGraphicsEdges())
720  {
721  if (edge->getnstType() == Qnst::Reference)
722  {
723  if (edge->getEntityB()->getncgType() == Qncg::Node)
724  {
725  e.setAttribute("componentUID", edge->getEntityB()->getnstUid());
726  }
727  else if (edge->getEntityB()->getncgType() == Qncg::Interface)
728  {
729  e.setAttribute("componentUID", edge->getEntityB()->getnstParent()->getnstUid());
730  e.setAttribute("interfaceUID", edge->getEntityB()->getnstUid());
731  }
732  break;
733  }
734  }
735  }
736  break;
737 
738  default:
739  // do nothing
740  break;
741  }
742 
743  e.setAttribute("id", entity->getnstId());
744  e.setAttribute("uid", entity->getnstUid());
745 
746  e.setAttribute("top", entity->getTop());
747  e.setAttribute("left", entity->getLeft());
748  e.setAttribute("width", entity->getWidth());
749  e.setAttribute("height", entity->getHeight());
750 
751  writeLink(element, dom, entity);
752 
753  foreach(QnstGraphicsEntity* c, entity->getnstGraphicsEntities())
754  {
755  write(e, dom, c);
756  }
757 
758  element.appendChild(e);
759 }
760 
761 void QnstView::writeLink(QDomElement element, QDomDocument* dom,
762  QnstGraphicsEntity* entity)
763 {
764  if (entity->getncgType() == Qncg::Node)
765  {
766  QnstGraphicsNode* node = (QnstGraphicsNode*) entity;
767 
768  foreach(QnstGraphicsEdge* edge, node->getnstGraphicsEdges())
769  {
770  //We already have this link, so skipping
771  if(linkWriterAux.contains(edge->getnstUid())) continue;
772  QDomElement e; // the element that will be inserted
773 
774  if (edge->getnstType() == Qnst::Condition ||
775  edge->getnstType() == Qnst::Action)
776  {
777  QnstGraphicsBind* bind = dynamic_cast <QnstGraphicsBind*> (edge);
778 
779  if(bind)
780  {
781  e = dom->createElement("bind");
782  e.setAttribute("id", bind->getnstId());
783  e.setAttribute("uid", bind->getnstUid());
784 
785  e.setAttribute("linkUID", bind->getLink()->getnstUid());
786 
787  // We are writing a condition
788  if (edge->getnstType() == Qnst::Condition)
789  {
790  e.setAttribute("type", "condition");
791 
792  e.setAttribute("condition",
794  bind->getType()) );
795  }
796  // We are writing an action
797  else if(edge->getnstType() == Qnst::Action)
798  {
799  e.setAttribute("type", "action");
800  e.setAttribute("action",
801  QnstUtil::getStrFromBindType(bind->getType()));
802  }
803 
804  e.setAttribute("componentaUID", bind->getEntityA()->getnstUid());
805  e.setAttribute("componentbUID", bind->getEntityB()->getnstUid());
806 
807  e.setAttribute("component", bind->getComponent());
808  e.setAttribute("componentUid", bind->getComponentUid());
809 
810  e.setAttribute("interface", bind->getInterface());
811  e.setAttribute("interfaceUid", bind->getInterfaceUid());
812 
813  element.appendChild(e);
814 
815  linkWriterAux.insert(bind->getnstUid());
816 
817  // Write the bind parameters
818  if(bind != NULL)
819  {
820  foreach(QString param, bind->getParams().keys())
821  {
822  QDomElement ebp = dom->createElement("param");
823 
824  ebp.setAttribute("name", param);
825  ebp.setAttribute("value", bind->getParams()[param]);
826  ebp.setAttribute("uid", bind->getNameUIDs()[param]);
827 
828  e.appendChild(ebp);
829  }
830  }
831  }
832  }
833  else if (edge->getnstType() == Qnst::Mapping)
834  {
836 
837  e = dom->createElement("mapping");
838 
839  e.setAttribute("uid", edge->getnstUid());
840 
841  e.setAttribute("switchportUid", link->getSwitchPortUid());
842  e.setAttribute("component", link->getComponent());
843  e.setAttribute("componentUid", link->getComponentUid());
844  e.setAttribute("interface", link->getInterfaceUid());
845  e.setAttribute("interfaceUid", link->getInterfaceUid());
846 
847  element.appendChild(e);
848 
849  linkWriterAux.insert(link->getnstUid());
850  }
851  }
852  }
853 }
854 
855 void QnstView::createObjects()
856 {
857  scene = new QnstScene();
858  scene->setParent(this);
859  scene->setSceneRect(0, 0, 4000, 4000);
860 
861  setScene(scene);
862 
863  linkDialog = new QnstGraphicsLinkDialog(this);
864 
865  conditionDialog = new QnstGraphicsConditionDialog(this);
866 
867  actionDialog = new QnstGraphicsActionDialog(this);
868 }
869 
870 void QnstView::createConnection()
871 {
872  // connect(scene, SIGNAL(undoRequested()), SLOT(performUndo()));
873  // connect(scene, SIGNAL(redoRequested()), SLOT(performRedo()));
874 
875  connect(scene, SIGNAL(cutRequested()), SLOT(performCut()));
876  connect(scene, SIGNAL(copyRequested()), SLOT(performCopy()));
877  connect(scene, SIGNAL(pasteRequested()), SLOT(performPaste()));
878 
879  connect(scene, SIGNAL(deleteRequested()), SLOT(performDelete()));
880 
881  connect(scene, SIGNAL(exportRequested()), SLOT(performExport()));
882 
883  connect(scene, SIGNAL(zoominRequested()), SLOT(performZoomIn()));
884  connect(scene, SIGNAL(zoomoutRequested()), SLOT(performZoomOut()));
885  connect(scene, SIGNAL(zoomresetRequested()), SLOT(performZoomReset()));
886  connect(scene, SIGNAL(fullscreenRequested()), SLOT(performFullscreen()));
887 
888  connect(scene, SIGNAL(entityAdded(QnstGraphicsEntity*)),
889  SLOT(requestEntityAddition(QnstGraphicsEntity*)));
890  connect(scene, SIGNAL(entityChanged(QnstGraphicsEntity*)),
891  SLOT(requestEntityChange(QnstGraphicsEntity*)));
892  connect(scene, SIGNAL(entityRemoved(QnstGraphicsEntity*)),
893  SLOT(requestEntityRemotion(QnstGraphicsEntity*)));
894  connect(scene, SIGNAL(entitySelected(QnstGraphicsEntity*)),
895  SLOT(requestEntitySelection(QnstGraphicsEntity*)));
896 
897  connect(scene,
898  SIGNAL(entityAboutToChange(QnstGraphicsEntity*,
899  QMap<QString,QString>)),
900  SLOT(requestEntityPreparation(QnstGraphicsEntity*,
901  QMap<QString,QString>)));
902 }
903 
904 bool QnstView::hasEntity(QString uid)
905 {
906  if (entities.contains(uid) ||
907  binds.contains(uid) ||
908  links.contains(uid))
909  {
910  return true;
911  }
912 
913  return false;
914 }
915 
916 QnstEntity* QnstView::getEntity(QString uid)
917 {
918  if (links.contains(uid))
919  return links.value(uid);
920 
921  else if (binds.contains(uid))
922  return binds.value(uid);
923 
924  else if (entities.contains(uid))
925  return entities.value(uid);
926 
927  return NULL;
928 }
929 
930 void QnstView::addEntity(const QString uid, const QString parent,
931  const QMap<QString, QString> &properties, bool undo,
932  bool adjust)
933 {
934  // \fixme Move this logic to AddCommand
935  bool ok = false;
936 
937  Qnst::EntityType type = QnstUtil::getnstTypeFromStr(properties["TYPE"]);
938  QnstGraphicsEntity *entityParent = 0;
939  QnstGraphicsEntity *entity = NULL;
940 
941  if(entities.count(parent))
942  {
943  entityParent = dynamic_cast<QnstGraphicsEntity*> (entities[parent]);
944  }
945 
946  qDebug() << "[QNST]" << ":" << "Adding entity '" + uid + "'" << properties << "Parent: " << parent;
947 
948 
949 
950  if(!entityParent &&
951  type != Qnst::Body &&
952  type != Qnst::Bind // for bind we will discover the parent after that
953  )
954  {
955  qWarning() << "[QNST] Trying to add an entity without a parent!!";
956  ok = false; // We still can be a special case. So, I can not return here!
957 
958  if( properties["TYPE"] == "importBase" ||
959  properties["TYPE"] == "causalConnector" ||
960  properties["TYPE"] == "simpleAction" ||
961  properties["TYPE"] == "simpleCondition" )
962  { // In these cases we do not need a parent.
963  qWarning() << "[QNST] " << properties["TYPE"] << " is a special case. So, we will not need a parent.";
964  }
965  else
966  {
967  qWarning() << "[QNST] The entityAdd is beging ignored!";
968  return;
969  }
970  }
971  // \fixme There are a lot of duplicated code among the cases bellow!
972  switch (type)
973  {
974  case Qnst::Body:
975  entity = QnstUtil::makeGraphicsEntity(type);
976  entity->setnstUid(uid);
977 
978  entity->setTop(scene->height()/2 - DEFAULT_BODY_HEIGHT/2);
979  entity->setLeft(scene->width()/2 - DEFAULT_BODY_WIDTH/2);
980  entity->setWidth(DEFAULT_BODY_WIDTH);
981  entity->setHeight(DEFAULT_BODY_HEIGHT);
982 
983  scene->addRoot(entity);
984  ok = true;
985  break;
986 
987  case Qnst::Context:
988  case Qnst::Switch:
989  {
990  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
991  if(entity != NULL) ok = true;
992  break;
993  }
994 
995  case Qnst::Media:
996  {
997  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
998 
999  if(entity != NULL)
1000  {
1001  entity->setnstType(QnstUtil::getnstTypeFromMime(properties["type"]));
1002  ok = true;
1003  }
1004  break;
1005  }
1006 
1007  case Qnst::Port:
1008  {
1009  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
1010  if(entity != NULL) ok = true;
1011  break;
1012  }
1013 
1014  case Qnst::Link:
1015  {
1016  if (!links.contains(uid))
1017  {
1018  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
1019  QnstGraphicsLink *link = dynamic_cast <QnstGraphicsLink*>(entity);
1020 
1021  if(link)
1022  {
1023  link->setnstUid(uid);
1024 
1025  if (properties["id"] != "")
1026  link->setnstId(properties["id"]);
1027 
1028  links[uid] = link;
1029  ok = true;
1030  }
1031  }
1032  else
1033  {
1034  qWarning() << "[QNST] Warning! Link already added!!";
1035  }
1036  break;
1037  }
1038 
1039  case Qnst::Bind:
1040  case Qnst::Action:
1041  case Qnst::Condition:
1042  {
1043  if (!binds.contains(uid))
1044  {
1045  QnstGraphicsEntity *entitya = NULL, *entityb = NULL;
1046  QString action = "", condition = "";
1047 
1048  if(entities.contains(properties["linkUID"]))
1049  entitya = entities[properties["linkUID"]];
1050  else
1051  qWarning() << "[QNST] Trying to make a bind that componentaUID does not exist!";
1052 
1053  if(entities.contains(properties["componentbUID"]))
1054  entityb = entities[properties["componentbUID"]];
1055  else
1056  qWarning() << "[QNST] Trying to make a bind that componentbUID \
1057  does not exist!";
1058 
1059  if(properties.contains("action"))
1060  action = properties["action"];
1061  else
1062  condition = properties["condition"];
1063 
1064  if(entitya != NULL)
1065  {
1066  if(links.contains(entitya->getnstUid()))
1067  {
1068  QnstGraphicsLink *link = links[ entitya->getnstUid() ];
1069 
1070  QnstGraphicsBind* bind = createBind( link,
1071  entityb,
1072  action,
1073  condition,
1074  false ); // \todo Use makeGraphicsEntity!
1075 
1076  // p.s. The parent set is made inside createBind!
1077  bind->setnstUid(uid);
1078  bind->setProperties(properties);
1079  entities[uid] = bind;
1080  binds[uid] = bind;
1081 
1082  ok = false;
1083  changeEntity(bind->getnstUid(), properties, true);
1084  }
1085  }
1086  }
1087  break;
1088  }
1089 
1090  case Qnst::BindParam: /* Warning: this is not a QnstEntity subclass */
1091  if (entities.contains(parent))
1092  {
1093  QnstGraphicsBind *bind = dynamic_cast<QnstGraphicsBind *>(entityParent);
1094 
1095  if(bind)
1096  {
1097  bind->addParam(uid, properties["name"], properties["value"]);
1098  bindParamUIDToBindUID[uid] = parent;
1099  }
1100  else
1101  {
1102  qWarning() << "[QNST] Warning! Trying to add a bind param inside a \
1103  not bind parent. This command will be ignored!";
1104  }
1105  }
1106  break;
1107 
1108  case Qnst::SwitchPort:
1109  {
1110  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
1111  if(entity != NULL) ok = true;
1112  break;
1113  }
1114 
1115 
1116  case Qnst::Mapping:
1117  {
1118  QnstGraphicsNode* oparent =
1119  (QnstGraphicsNode*) entityParent->getnstGraphicsParent();
1120 
1121  entity = new QnstGraphicsMapping(oparent);
1122  ((QnstGraphicsMapping*) entity)->setSwitchPortUid(parent);
1123  ok = true;
1124 
1125  break;
1126  }
1127 
1128  case Qnst::Aggregator:
1129  {
1130  qWarning() << "[QNST] ERROR!!! Trying to add an Aggregator!! This is not \
1131  supported anymore!";
1132  break;
1133  }
1134 
1135 
1136  case Qnst::Area:
1137  case Qnst::Property:
1138  {
1139  entity = QnstUtil::makeGraphicsEntity(type, entityParent, properties);
1140 
1141  if (properties.contains("isRefer"))
1142  {
1143  ((QnstGraphicsInterface*) entity)->setRefer(true);
1144  }
1145 
1146  ok = true;
1147  break;
1148  }
1149 
1150  default:
1151  //do nothing
1152  break;
1153  }
1154 
1155  if(ok)
1156  {
1157  entity->setnstUid(uid);
1158  entities[uid] = entity;
1159  entity->setProperties(properties);
1160 
1161  entity->updateToolTip();
1162 
1163  entity->adjust();
1164 
1165  if (adjust)
1166  adjustEntity(entity);
1167  }
1168 
1169  // if the entity type is CONNECTOR
1170  if (properties["TYPE"] == "causalConnector")
1171  {
1172  addConnector(uid, properties);
1173  }
1174  // if the entity type is CONDITION
1175  else if (properties["TYPE"] == "simpleCondition")
1176  {
1177  addCondition(uid, properties);
1178  }
1179  // if the entity type is ACTION
1180  else if (properties["TYPE"] == "simpleAction")
1181  {
1182  addAction(uid, properties);
1183  }
1184  // if the entity type is IMPORTBASE
1185  else if (properties["TYPE"] == "importBase")
1186  {
1187  addImportBase(uid, properties);
1188  }
1189  else if (properties["TYPE"] == "connectorParam")
1190  {
1191  addConnectorParam(uid, parent, properties);
1192  }
1193 
1194  if(ok && !undo && entity != NULL)
1195  {
1196  QnstAddCommand* cmd = new QnstAddCommand(this, entity);
1197  history.push(cmd);
1198  }
1199 }
1200 
1201 void QnstView::removeEntity(const QString uid, bool undo, bool rmRef)
1202 {
1203  // traceEntities();
1204 
1205  QnstConnector* cONN = NULL;
1206 
1207  // \fixme Move this logic to RemoveCommand
1208  if (entities.contains(uid))
1209  {
1210  QnstGraphicsEntity* entity = entities[uid];
1211 
1212  if (entity != NULL)
1213  {
1214  Qncg::EntityType qncgType = entity->getncgType();
1215  bool mustRemoveFromParent = false;
1216 
1217  //handle UNDO: By now, we aren't handling Links!!
1218  if(entity->getncgType() == Qncg::Node ||
1219  entity->getncgType() == Qncg::Interface)
1220  {
1221  if (!undo)
1222  {
1223  QnstRemoveCommand* cmd = new QnstRemoveCommand(this, entity);
1224  history.push(cmd);
1225  }
1226  }
1227 
1228  // We are removing a Node
1229  switch(qncgType)
1230  {
1231  case Qncg::Node:
1232  {
1233  QnstGraphicsNode *node = dynamic_cast <QnstGraphicsNode*>(entity);
1234  if(node)
1235  removeEdgesOfEntity(node, false);
1236 
1237  // Remove recursively
1238  foreach(QnstGraphicsEntity* e, entity->getnstGraphicsEntities())
1239  {
1240  if (e->getnstType() != Qnst::Edge &&
1241  e->getnstType() != Qnst::Condition &&
1242  e->getnstType() != Qnst::Mapping &&
1243  e->getnstType() != Qnst::Action &&
1244  e->getnstType() != Qnst::Reference)
1245  {
1246  removeEntity(e->getnstUid(), true, false);
1247  }
1248  }
1249 
1250  // If we are removing a link, also remove it from the links map
1251  if (entity->getnstType() == Qnst::Link ||
1252  entity->getnstType() == Qnst::Aggregator)
1253  {
1254  if (links.contains(entity->getnstUid()))
1255  {
1256  links.remove(entity->getnstUid());
1257  }
1258  }
1259 
1260  mustRemoveFromParent = true;
1261  break;
1262  }
1263 
1264  case Qncg::Interface:
1265  {
1266  QnstGraphicsInterface *interface =
1267  dynamic_cast <QnstGraphicsInterface*>(entity);
1268 
1269  if(interface)
1270  removeEdgesOfEntity(interface, false); // Remove the edges of this entity
1271  else
1272  qWarning() << "Could not make a cast to QnstGraphicsInterface*";
1273 
1274  mustRemoveFromParent = true;
1275  break;
1276  }
1277 
1278  case Qncg::Edge:
1279  {
1280  QnstGraphicsEdge *edge = dynamic_cast<QnstGraphicsEdge *>(entity);
1281 
1282  if(edge)
1283  removeEdge(edge, false);
1284  break;
1285  }
1286 
1287  default:
1288  //do nothing ?
1289  mustRemoveFromParent = true;
1290  break;
1291  }
1292 
1293  // Everything is ok, now only remove the entity from its parent
1294  if(mustRemoveFromParent)
1295  {
1296  //Remove the entity of its parent
1297  QnstGraphicsEntity* parent = entity->getnstGraphicsParent();
1298  if (parent != NULL)
1299  {
1300  qDebug() << "parent = "
1301  << QString().sprintf("%p", parent)
1302  << parent->getnstUid();
1303 
1304  parent->removenstGraphicsEntity(entity);
1305  }
1306  else
1307  scene->removeRoot(entity);
1308 
1309  if (selected == entity)
1310  selected = NULL;
1311 
1312  if (clipboard == entity)
1313  clipboard = NULL;
1314 
1315  if (entity->getnstType() == Qnst::Link &&
1316  links.contains(entity->getnstUid()))
1317  {
1318  links.remove(entity->getnstUid());
1319  }
1320 
1321  entities.remove(entity->getnstUid());
1322 
1323  entity->deleteLater();
1324 
1325  // Update refer entities
1326  if (qncgType == Qncg::Interface)
1327  {
1328  qDebug() << "I am Qncg::Interface" << uid;
1329  if (refers.contains(uid))
1330  {
1331  qDebug() << "Only remove from refer";
1332  refers.remove(uid);
1333  }
1334  else
1335  {
1336  qDebug() << "Calling adjust... :P" << uid;
1337  qDebug() << "Before adjustMedia";
1338  QnstGraphicsMedia* parentMedia
1339  = dynamic_cast<QnstGraphicsMedia*>(parent);
1340  if (parentMedia &&
1341  entities.contains(parentMedia->getnstUid()))
1342  {
1343  // adjustMedia(parentMedia);
1344 
1345  foreach(QString rUid, refers.keys(parentMedia->getnstUid()))
1346  {
1347  if (entities.contains(rUid))
1348  {
1349  QnstGraphicsMedia* referMedia =
1350  dynamic_cast <QnstGraphicsMedia*>(entities.value(rUid));
1351 
1352  if (referMedia)
1353  {
1354  qDebug() << "referMedia is ok, so calling adjustMedia";
1355  adjustMedia(referMedia);
1356  }
1357  }
1358  }
1359  }
1360 
1361  qDebug() << "After adjust... :P";
1362  }
1363  }
1364  else
1365  {
1366  qDebug() << "Well, I am not inside refer :P...";
1367  foreach(QString ruid, refers.keys(uid))
1368  {
1369  refers.remove(ruid);
1370 
1371  if (entities.contains(ruid))
1372  {
1373  QnstGraphicsEntity* e = entities.value(ruid);
1374 
1375  if (e->isMedia())
1376  adjustMedia((QnstGraphicsMedia*) e);
1377  }
1378  }
1379 
1380  if (refers.contains(uid))
1381  {
1382  qDebug() << "Removing" + uid + "from refers.";
1383  refers.remove(uid);
1384  }
1385  }
1386  // End update
1387  }
1388  }
1389  }
1390  else if (importBases.contains(uid))
1391  {
1392  foreach(QnstConnector* cc, connectors.values())
1393  {
1394  if (cc->getnstUid() == importBases[uid])
1395  connectors.remove(cc->getName());
1396  }
1397 
1398  foreach(QnstConnector* cc, connectors2.values())
1399  {
1400  if (cc->getnstUid() == importBases[uid])
1401  connectors2.remove(cc->getnstId());
1402  }
1403 
1404  importBases.remove(uid);
1405 
1406  // foreach(QnstGraphicsBind* b, binds.values())
1407  // {
1408  // adjustBind(b);
1409  // }
1410  }
1411  else if (connectors2.contains(uid))
1412  {
1413  connectors.remove(connectors2[uid]->getName());
1414  connectors2.remove(uid);
1415  }
1416  else if ((cONN = getConnectorByRoleUid(uid)) != NULL)
1417  {
1418  cONN->removeAction(uid);
1419  cONN->removeCondition(uid);
1420  }
1421  else if (bindParamUIDToBindUID.contains(uid))
1422  {
1423  if(bindParamUIDToBindUID.contains(uid))
1424  {
1425  if(entities.contains(bindParamUIDToBindUID[uid]))
1426  {
1427  QnstGraphicsEntity* e = entities[bindParamUIDToBindUID[uid]];
1428 
1429  QnstGraphicsBind *bind = dynamic_cast<QnstGraphicsBind*>(e);
1430  if (e)
1431  {
1432  bind->removeUId(uid);
1433  }
1434  else
1435  {
1436  qWarning() << "[QNST] Warning! The parent of bindParam is not a \
1437  bind!";
1438  }
1439  }
1440  else
1441  {
1442  qWarning() << "[QNST] Warning! Trying to remove a bindParam that is \
1443  mapped inside an entity!";
1444  }
1445 
1446  // We will remove it from map does not matter what!
1447  bindParamUIDToBindUID.remove(uid);
1448  }
1449  else
1450  qWarning() << "[QNST] Warning! Trying to remove a bindParam that is \
1451  not inside bindParamUIDToBindUID";
1452  }
1453  else
1454  {
1455  qDebug() << "Warning! Calling removeEntity to a entity that does not exist in view!";
1456  }
1457 
1458  deletePendingEntities();
1459 }
1460 
1461 void QnstView::changeEntity(const QString uid,
1462  const QMap<QString, QString> &properties,
1463  bool adjust)
1464 {
1465  qDebug() << "[QNST]" << ":" << "Changing entity '"+uid+"'"
1466  << properties;
1467 
1468  if (selected != NULL)
1469  {
1470  selected->setSelected(false);
1471  selected->adjust();
1472  }
1473  selected = NULL;
1474 
1475  if (links.contains(uid))
1476  {
1477  changeLink(links[uid], properties);
1478  }
1479  else if (entities.contains(uid))
1480  {
1481  QnstGraphicsEntity* entity = entities[uid];
1482 
1483  switch(entity->getnstType())
1484  {
1485  case Qnst::Body:
1486  {
1487  entity->setnstId(properties["id"]);
1488  entity->setProperties(properties);
1489 
1490  entity->adjust();
1491  break;
1492  }
1493 
1494  case Qnst::Context:
1495  case Qnst::Switch:
1496  {
1497  if (properties["id"] != "")
1498  entity->setnstId(properties["id"]);
1499 
1500  entity->setProperties(properties);
1501  // \todo refer
1502  break;
1503  }
1504 
1505  // if the entity type is MEDIA
1506  case Qnst::Audio:
1507  case Qnst::Text:
1508  case Qnst::Video:
1509  case Qnst::Image:
1510  case Qnst::NCLua:
1511  case Qnst::Settings:
1512  case Qnst::Media:
1513  case Qnst::Html:
1514  case Qnst::NCL:
1515  {
1516  QnstGraphicsMedia *media = dynamic_cast <QnstGraphicsMedia *>(entity);
1517  if(media)
1518  {
1519  media->setnstId(properties["id"]);
1520  media->setProperties(properties);
1521 
1522  if (properties["referUID"] != "")
1523  {
1524  if (entities.contains(properties["referUID"]))
1525  media->setSource(((QnstGraphicsMedia*)
1526  entities[properties["referUID"]])->getSource());
1527  }
1528 
1529  QString src = media->getSource();
1530  media->setnstType(QnstUtil::getnstTypeFromMime(properties["type"]));
1531 
1532  if(src == "")
1533  {
1534  // do nothing
1535  }
1536  else {
1537  int start = src.lastIndexOf(".");
1538  if(start >= 0)
1539  {
1540  QString ext = QFileInfo(src).suffix().toLower();
1541  media->setnstType(QnstUtil::getnstTypeFromExtension(ext));
1542  }
1543  }
1544 
1545  if(adjust)
1546  {
1547  adjustMedia(media);
1548 
1549  // \fixme It's not necessary to adjust all medias
1550 // foreach (QnstGraphicsEntity* e, entities.values())
1551 // {
1552 
1553 // QnstGraphicsMedia* m = dynamic_cast<QnstGraphicsMedia*>(e);
1554 // if (m)
1555 // adjustMedia(m);
1556 
1557 // }
1558  }
1559  }
1560  break;
1561  }
1562 
1563  case Qnst::Port:
1564  {
1565  entity->setnstId(properties["id"]);
1566 
1567  entity->setProperties(properties);
1568 
1569  foreach (QString key, refers.keys(entity->getnstUid()))
1570  {
1571  if (entities.contains(key))
1572  entities[key]->setnstId(entity->getnstId());
1573  }
1574 
1575  QnstGraphicsPort *port = dynamic_cast<QnstGraphicsPort*> (entity);
1576  // \todo updateToolTip!!
1577  if(port)
1578  adjustPort(port);
1579  }
1580  break;
1581 
1582  case Qnst::Area:
1583  case Qnst::Property:
1584  {
1585  entity->setnstId(properties["id"]);
1586 
1587  entity->setProperties(properties);
1588 
1589  foreach (QString key, refers.keys(entity->getnstUid()))
1590  {
1591  if (entities.contains(key))
1592  entities[key]->setnstId(entity->getnstId());
1593  }
1594  break;
1595  }
1596 
1597  case Qnst::SwitchPort:
1598  {
1599  if(properties.contains("id"))
1600  entity->setnstId(properties["id"]);
1601 
1602  entity->setProperties(properties);
1603 
1604  entity->adjust();
1605  break;
1606  }
1607 
1608  case Qnst::Mapping:
1609  {
1610  entity->setProperties(properties);
1611 
1612  QnstGraphicsMapping *mapping = dynamic_cast<QnstGraphicsMapping*> (entity);
1613  adjustMapping(mapping);
1614  break;
1615  }
1616 
1617  case Qnst::Link:
1618  {
1619  entity->setProperties(properties);
1620  // \todo Update Link!!
1621  break;
1622  }
1623 
1624  case Qnst::Bind:
1625  case Qnst::Action:
1626  case Qnst::Condition:
1627  {
1628  QnstGraphicsBind *bind = dynamic_cast<QnstGraphicsBind *> (entity);
1629 
1630  if(bind)
1631  {
1632  bind->setProperties(properties);
1633 
1634  adjustBind(bind);
1635  }
1636  break;
1637  }
1638 
1639  default:
1640  // do nothing
1641  break;
1642  }
1643 
1644  entity->updateToolTip();
1645  }
1646  else
1647  {
1648  qWarning() << "Trying to change an Entity that does not exist!";
1649 
1650  if (properties["TYPE"] == "importBase")
1651  {
1652  changeImportBase(uid, properties);
1653  }
1654  else if (connectors2.contains(uid))
1655  {
1656  changeConnector(connectors2[uid], properties);
1657  }
1658  else if (properties["TYPE"] == "simpleCondition")
1659  {
1660  changeCondition(uid, properties);
1661  }
1662  else if (properties["TYPE"] == "simpleAction")
1663  {
1664  changeAction(uid, properties);
1665  }
1666  else if (properties["TYPE"] == "bindParam")
1667  {
1668  changeBindParam(uid, properties);
1669  }
1670  else if (properties["TYPE"] == "connectorParam")
1671  {
1672  changeConnectorParam(uid, properties);
1673  }
1674 
1675  }
1676 
1677  deletePendingEntities();
1678 }
1679 
1680 void QnstView::selectEntity(const QString uid)
1681 {
1682  qDebug() << "[QNST]" << ":" << "Selecting entity '"+uid+"'";
1683 
1684  if (entities.contains(uid))
1685  {
1686  QnstGraphicsEntity* entity = entities[uid];
1687 
1688  if (entity != selected)
1689  {
1690  if (selected != NULL)
1691  {
1692  selected->setSelected(false);
1693  selected->adjust();
1694  }
1695 
1696  selected = entity;
1697 
1698  selected->setSelected(true);
1699  selected->adjust();
1700  }
1701  }
1702 }
1703 
1704 void QnstView::addImportBase(const QString &uid,
1705  const QMap<QString, QString> &properties)
1706 {
1707  QString connUID = QUuid::createUuid().toString();
1708 
1709  importBases[uid] = connUID;
1710 
1711  if (properties["documentURI"] != "" &&
1712  properties["projectURI"] != "" &&
1713  properties["alias"] != "")
1714  {
1715  int n = properties["projectURI"].lastIndexOf("/");
1716 
1717  QFile* file = new QFile(properties["projectURI"].left(n)+QDir::separator()+properties["documentURI"]);
1718 
1719  if (file->exists())
1720  {
1721  if (file->open(QIODevice::ReadOnly))
1722  {
1723  QDomDocument* domdoc = new QDomDocument();
1724  if (domdoc->setContent(file))
1725  readImportBase(connUID, domdoc->firstChildElement(), properties["alias"]);
1726  }
1727  }
1728 
1729  delete file;
1730 
1731  // foreach(QnstGraphicsBind* b, binds.values())
1732  // {
1733  // adjustBind(b);
1734  // }
1735  }
1736 }
1737 
1738 
1739 void QnstView::changeImportBase(const QString &uid,
1740  const QMap<QString, QString> &properties)
1741 {
1742  foreach(QnstConnector* cc, connectors.values())
1743  {
1744  if (cc->getnstUid() == importBases[uid])
1745  connectors.remove(cc->getName());
1746  }
1747 
1748  foreach(QnstConnector* cc, connectors2.values())
1749  {
1750  if (cc->getnstUid() == importBases[uid])
1751  connectors2.remove(cc->getnstId());
1752  }
1753 
1754  if (properties["documentURI"] != "" &&
1755  properties["projectURI"] != "" &&
1756  properties["alias"] != "")
1757  {
1758  int n = properties["projectURI"].lastIndexOf("/");
1759  QFile* file = new QFile(properties["projectURI"].left(n)+QDir::separator()+properties["documentURI"]);
1760 
1761  if (file->exists())
1762  {
1763  if (file->open(QIODevice::ReadOnly))
1764  {
1765 
1766  QDomDocument* domdoc = new QDomDocument();
1767 
1768  if (domdoc->setContent(file))
1769  {
1770  readImportBase(importBases[uid], domdoc->firstChildElement(), properties["alias"]);
1771  }
1772  }
1773  }
1774 
1775  delete file;
1776  }
1777 
1778  // foreach(QnstGraphicsBind* b, binds.values())
1779  // {
1780  // adjustBind(b);
1781  // }
1782 }
1783 
1784 void QnstView::readImportBase(const QString &uid,
1785  QDomElement element,
1786  const QString &alias)
1787 {
1788  if (element.tagName() == "causalConnector")
1789  {
1790  QDomNodeList list = element.childNodes();
1791 
1792  QnstConnector* conn = new QnstConnector();
1793  conn->setnstId(alias+"#"+element.attribute("id"));
1794  conn->setName(alias+"#"+element.attribute("id"));
1795  conn->setnstUid(uid);
1796 
1797  for (unsigned int i=0;i<list.length();i++)
1798  {
1799  if (list.item(i).isElement())
1800  {
1801  QDomElement e = list.item(i).toElement();
1802 
1803  readConnector(e, conn);
1804  }
1805  }
1806 
1807  connectors[conn->getName()] = conn;
1808  connectors2[conn->getnstId()] = conn;
1809 
1810  }
1811  else
1812  {
1813  QDomNodeList list = element.childNodes();
1814 
1815  for (unsigned int i=0;i<list.length();i++)
1816  {
1817  if (list.item(i).isElement())
1818  {
1819  QDomElement e = list.item(i).toElement();
1820 
1821  readImportBase(uid, e, alias);
1822  }
1823  }
1824  }
1825 }
1826 
1827 void QnstView::readConnector(QDomElement element, QnstConnector* conn)
1828 {
1829  if (element.tagName() == "connectorParam")
1830  {
1831  if (element.attribute("name") != "")
1832  conn->addParam(QUuid::createUuid().toString(), element.attribute("name"));
1833  }
1834 
1835  if (element.tagName() == "simpleCondition" ||
1836  element.tagName() == "attributeAssessment")
1837  {
1838  if (element.attribute("role") != "")
1839  {
1840  QString UID = QUuid::createUuid().toString();
1841 
1842  conn->addCondition(UID, element.attribute("role"));
1843 
1844  QDomNamedNodeMap attributes = element.attributes();
1845 
1846  for (int i=0;i<attributes.size();i++)
1847  {
1848  QString name = attributes.item(i).toAttr().name();
1849  QString value = attributes.item(i).toAttr().value();
1850 
1851  if (value.contains("$"))
1852  {
1853  conn->addConditionParam(UID,name,value.replace('$',""));
1854  }
1855  }
1856  }
1857  }
1858 
1859  if (element.tagName() == "simpleAction")
1860  {
1861  if (element.attribute("role") != "")
1862  {
1863  QString UID = QUuid::createUuid().toString();
1864 
1865  conn->addAction(UID, element.attribute("role"));
1866 
1867  QDomNamedNodeMap attributes = element.attributes();
1868 
1869  for (int i=0;i<attributes.size();i++)
1870  {
1871  QString name = attributes.item(i).toAttr().name();
1872  QString value = attributes.item(i).toAttr().value();
1873 
1874  if (value.contains("$"))
1875  {
1876  conn->addActionParam(UID,name,value.replace('$',""));
1877  }
1878  }
1879  }
1880 
1881 
1882  }
1883 
1884  QDomNodeList list = element.childNodes();
1885 
1886  for (unsigned int i=0;i<list.length();i++)
1887  {
1888  if (list.item(i).isElement())
1889  {
1890  QDomElement e = list.item(i).toElement();
1891  readConnector(e, conn);
1892  }
1893  }
1894 }
1895 
1896 void QnstView::adjustEntity(QnstGraphicsEntity *entity)
1897 {
1898  QnstType type = entity->getnstType();
1899  entity->adjust();
1900 
1901  switch(type)
1902  {
1903  case Qnst::Link:
1904  {
1905  adjustLink((QnstGraphicsLink*)link);
1906  break;
1907  }
1908 
1909  case Qnst::Mapping:
1910  {
1911  adjustMapping((QnstGraphicsMapping*)entity);
1912  break;
1913  }
1914 
1915  case Qnst::Area:
1916  case Qnst::Property:
1917  {
1918  QnstGraphicsEntity *entityParent = entity->getnstGraphicsParent();
1919 
1920  if(entityParent->isMedia())
1921  adjustMedia((QnstGraphicsMedia*) entityParent);
1922 
1923  // Update the medias that refer to this one.
1924  foreach (QString key, refers.keys(entityParent->getnstUid()))
1925  {
1926  if (entities.contains(key) && entities[key]->isMedia())
1927  adjustMedia((QnstGraphicsMedia*) entities[key]);
1928  }
1929  break;
1930  }
1931  }
1932 }
1933 
1934 void QnstView::adjustContext(QnstGraphicsContext* entity)
1935 {
1936 
1937 }
1938 
1939 // \todo refactory
1940 void QnstView::adjustMedia(QnstGraphicsMedia* entity)
1941 {
1942  QString referUID = entity->getReferUID();
1943  QString refer = entity->getRefer();
1944 
1945 // qDebug() << "===================================== ID" << entity->getnstId();
1946 // qDebug() << "===================================== REFER" << refer;
1947 // qDebug() << "===================================== REFERUID" << referUID;
1948 
1949  if (!refer.isEmpty() && !referUID.isEmpty())
1950  {
1951  if (entities.contains(referUID)) // media already refer to other media
1952  {
1953  QnstGraphicsMedia* origin =
1954  dynamic_cast<QnstGraphicsMedia*>(entities[referUID]);
1955 
1956  if (origin)
1957  {
1958  entity->setnstType(origin->getnstType());
1959  entity->setSource(origin->getSource());
1960 
1961  // cleaning interface without origin
1962  foreach(QnstGraphicsEntity* rinterface,
1963  entity->getnstGraphicsEntities())
1964  {
1965  if (rinterface->getncgType() == Qncg::Interface)
1966  {
1967  if (refers.contains(rinterface->getnstUid()))
1968  {
1969  bool validReference = false;
1970 
1971  foreach(QnstGraphicsEntity* interface,
1972  origin->getnstGraphicsEntities())
1973  {
1974  if (interface->getnstUid() == refers[rinterface->getnstUid()])
1975  {
1976  validReference = true;
1977  break;
1978  }
1979  }
1980 
1981  if (!validReference)
1982  {
1983  entity->removenstGraphicsEntity(rinterface);
1984 
1985  refers.remove(rinterface->getnstUid());
1986  entities.remove(rinterface->getnstUid());
1987  toDelete.push_back(rinterface);
1988  }
1989  }
1990  }
1991  }
1992 
1993  // copying interfaces from origin to entity
1994  foreach (QnstGraphicsEntity* child, origin->getnstGraphicsEntities())
1995  {
1996  bool hasRefer = false;
1997  QnstGraphicsInterface *interface = dynamic_cast <QnstGraphicsInterface*> (child);
1998 
1999  if(interface && !interface->isRefer())
2000  {
2001  foreach(QnstGraphicsEntity* rinterface,
2002  entity->getnstGraphicsEntities())
2003  {
2004  if (refers.value(rinterface->getnstUid()) == interface->getnstUid() ||
2005  refers.value(interface->getnstUid()) == rinterface->getnstUid())
2006  {
2007  hasRefer = true;
2008  break;
2009  }
2010  }
2011 
2012  if (!hasRefer)
2013  {
2015  QnstUtil::makeGraphicsEntity(interface->getnstType(), entity);
2016 
2017  copy->setnstId(interface->getnstId());
2018 
2019  copy->setTop(interface->getTop());
2020  copy->setLeft(interface->getLeft());
2021  copy->setWidth(interface->getWidth());
2022  copy->setHeight(interface->getHeight());
2023  copy->setRefer(true);
2024  copy->adjust();
2025 
2026  refers[copy->getnstUid()] = interface->getnstUid();
2027  entities[copy->getnstUid()] = copy;
2028  }
2029  }
2030  }
2031 
2032  if (entity->getInstance() == "instSame")
2033  {
2034  //cleaning
2035  foreach(QnstGraphicsEntity* interface,
2036  origin->getnstGraphicsEntities())
2037  {
2038  if (interface->getncgType() == Qncg::Interface)
2039  {
2040  if (refers.contains(interface->getnstUid()))
2041  {
2042  bool validReference = false;
2043 
2044  foreach(QnstGraphicsEntity* rinterface,
2045  entity->getnstGraphicsEntities())
2046  {
2047  if (rinterface->getnstUid() == refers[interface->getnstUid()])
2048  {
2049  validReference = true;
2050  break;
2051  }
2052  }
2053 
2054  if (!validReference)
2055  {
2056  origin->removenstGraphicsEntity(interface);
2057 
2058  refers.remove(interface->getnstUid());
2059  entities.remove(interface->getnstUid());
2060 
2061 // delete interface;
2062  toDelete.push_back(interface);
2063  }
2064  }
2065  }
2066  }
2067 
2068  foreach(QnstGraphicsEntity* rinterface,
2069  entity->getnstGraphicsEntities())
2070  {
2071  if (!refers.contains(rinterface->getnstUid()))
2072  {
2073  bool containsRef = false;
2074 
2075  foreach(QnstGraphicsEntity* interface,
2076  origin->getnstGraphicsEntities())
2077  {
2078  if (refers.value(interface->getnstUid(),"NULL") == rinterface->getnstUid())
2079  {
2080  containsRef = true;
2081  break;
2082  }
2083  }
2084 
2085  if (!containsRef)
2086  {
2088  QnstUtil::makeGraphicsEntity(rinterface->getnstType(), origin);
2089 
2090  copy->setnstId(rinterface->getnstId());
2091 
2092  copy->setTop(rinterface->getTop());
2093  copy->setLeft(rinterface->getLeft());
2094  copy->setWidth(rinterface->getWidth());
2095  copy->setHeight(rinterface->getHeight());
2096  copy->setRefer(true);
2097  copy->adjust();
2098 
2099  refers[copy->getnstUid()] = rinterface->getnstUid();
2100  entities[copy->getnstUid()] = copy;
2101  }
2102  }
2103  }
2104  }
2105  else
2106  {
2107  foreach(QnstGraphicsEntity* interface, origin->getnstGraphicsEntities())
2108  {
2109  if (refers.contains(interface->getnstUid()))
2110  {
2111  bool containsRef = false;
2112 
2113  foreach(QnstGraphicsEntity* rinterface,
2114  entity->getnstGraphicsEntities())
2115  {
2116  if (refers.value(interface->getnstUid()) == rinterface->getnstUid())
2117  {
2118  containsRef = true;
2119  break;
2120  }
2121  }
2122 
2123  if (containsRef)
2124  {
2125  origin->removenstGraphicsEntity(interface);
2126 
2127  refers.remove(interface->getnstUid());
2128  entities.remove(interface->getnstUid());
2129  toDelete.push_back(interface);
2130  }
2131  }
2132  }
2133  }
2134 
2135  refers[entity->getnstUid()] = origin->getnstUid();
2136  }
2137  }
2138  else
2139  {
2140  foreach(QnstGraphicsEntity* interface, entity->getnstGraphicsEntities())
2141  {
2143  dynamic_cast<QnstGraphicsInterface*>(interface);
2144 
2145  if (i != 0)
2146  {
2147  if (i->isRefer())
2148  {
2149  entity->removenstGraphicsEntity(interface);
2150 
2151  refers.remove(interface->getnstUid());
2152  entities.remove(interface->getnstUid());
2153  // delete interface;
2154  toDelete.push_back(interface);
2155  }
2156  }
2157  }
2158 
2159  entity->setnstType(Qnst::Media);
2160  entity->setSource("");
2161  entity->setReferUID("");
2162  }
2163  }
2164  else // I do not refer to any media, so remove all references
2165  {
2166  qWarning() << "I do not refer to any media, so remove all references";
2167  if (refers.contains(entity->getnstUid()))
2168  {
2169  qWarning() << "Refers.contains" << entity->getnstUid();
2170  foreach(QnstGraphicsEntity* interface, entity->getnstGraphicsEntities())
2171  {
2172  if (refers.contains(interface->getnstUid()))
2173  {
2174  entity->removenstGraphicsEntity(interface);
2175 
2176  refers.remove(interface->getnstUid());
2177  entities.remove(interface->getnstUid());
2178 
2179 // delete interface;
2180  toDelete.push_back(interface);
2181  }
2182  else
2183  {
2184  if (refers.contains(entity->getnstUid()))
2185  {
2186  foreach(QString rUid, refers.keys(interface->getnstUid()))
2187  {
2188  if (entities.contains(rUid))
2189  {
2190  QnstGraphicsEntity* e = entities.value(rUid);
2191  QnstGraphicsEntity* p = e->getnstGraphicsParent();
2192 
2193  p->removenstGraphicsEntity(e);
2194 
2195  refers.remove(e->getnstUid());
2196  entities.remove(e->getnstUid());
2197 
2198 // delete e;
2199  toDelete.push_back(e);
2200  }
2201  }
2202  }
2203  }
2204  }
2205  }
2206  else
2207  {
2208  if (refers.keys(entity->getnstUid()).size() == 0)
2209  {
2210  foreach(QnstGraphicsEntity* interface, entity->getnstGraphicsEntities())
2211  {
2213  dynamic_cast<QnstGraphicsInterface*>(interface);
2214 
2215  if (i)
2216  {
2217  if (i->isRefer())
2218  {
2219  entity->removenstGraphicsEntity(interface);
2220 
2221  entities.remove(interface->getnstUid());
2222  refers.remove(interface->getnstUid());
2223 
2224 // delete interface;
2225  toDelete.push_back(interface);
2226  }
2227  }
2228  }
2229  }
2230  }
2231 
2232  if (refers.contains(entity->getnstUid()))
2233  {
2234  entity->setnstType(Qnst::Media);
2235  entity->setSource("");
2236 
2237  refers.remove(entity->getnstUid());
2238  }
2239  }
2240 
2241  entity->adjust();
2242 }
2243 
2244 // \todo refactory
2245 void QnstView::adjustPort(QnstGraphicsPort* entity)
2246 {
2247  QnstGraphicsEntity* parent = entity->getnstGraphicsParent();
2248 
2249  if (parent != NULL)
2250  {
2251  // removing previous edge
2252  foreach(QnstGraphicsEntity* e, parent->getnstGraphicsEntities())
2253  {
2254  if (e->getnstType() == Qnst::Reference)
2255  {
2256  QnstGraphicsEdge* edge = (QnstGraphicsEdge*) e;
2257 
2258  if (entity == edge->getEntityA())
2259  {
2260  if (edge->getEntityA()->getncgType() == Qncg::Node ||
2261  edge->getEntityA()->getncgType() == Qncg::Interface )
2262  {
2263  ((QnstGraphicsEntityWithEdges*) edge->getEntityA())->removenstGraphicsEdge(edge);
2264  }
2265 
2266  if (edge->getEntityB()->getncgType() == Qncg::Node ||
2267  edge->getEntityB()->getncgType() == Qncg::Interface)
2268  {
2269  ((QnstGraphicsEntityWithEdges*) edge->getEntityB())->removenstGraphicsEdge(edge);
2270  }
2271 
2272  parent->removenstGraphicsEntity(edge);
2273  delete (edge);
2274  break;
2275  }
2276  }
2277  } // end foreach
2278 
2279  // adding new edge
2280  if (entity->getInterfaceUid() != "")
2281  {
2282  // changing
2283  if (entities.contains(entity->getInterfaceUid()))
2284  {
2285  QnstGraphicsEntity* entitya = (QnstGraphicsEntity*) entity;
2286  QnstGraphicsEntity* entityb = (QnstGraphicsEntity*) entities[entity->getInterfaceUid()];
2287 
2288  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
2289  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
2290 
2291  if (parenta != NULL && parentb != NULL)
2292  {
2293  if (entitya != entityb && parenta == parentb->getnstGraphicsParent())
2294  {
2296  edge->setEntityA(entitya);
2297  edge->setEntityB(entityb);
2298  edge->adjust();
2299 
2300  parenta->addnstGraphicsEntity(edge);
2301 
2302  ((QnstGraphicsInterface*) entitya)->addnstGraphicsEdge(edge);
2303  ((QnstGraphicsInterface*) entityb)->addnstGraphicsEdge(edge);
2304  }
2305  }
2306  }
2307  }
2308  else if (entity->getComponentUid() != "")
2309  {
2310  // changing
2311  if (entities.contains(entity->getComponentUid()))
2312  {
2313  QnstGraphicsEntity* entitya = (QnstGraphicsEntity*) entity;
2314  QnstGraphicsEntity* entityb = (QnstGraphicsEntity*) entities[entity->getComponentUid()];
2315 
2316  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
2317  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
2318 
2319  if (parenta != NULL && parentb != NULL)
2320  {
2321  if (entitya != entityb && parenta == parentb)
2322  {
2324  edge->setEntityA(entitya);
2325  edge->setEntityB(entityb);
2326  edge->adjust();
2327 
2328  parenta->addnstGraphicsEntity(edge);
2329 
2330  ((QnstGraphicsInterface*) entitya)->addnstGraphicsEdge(edge);
2331  ((QnstGraphicsNode*) entityb)->addnstGraphicsEdge(edge);
2332  }
2333  }
2334  }
2335  }
2336  }
2337 
2338  entity->adjust();
2339 }
2340 
2341 // \todo refactory
2342 void QnstView::adjustMapping(QnstGraphicsMapping* entity)
2343 {
2344  if (entities.contains(entity->getComponentUid()) &&
2345  entities.contains(entity->getSwitchPortUid()))
2346  {
2347  QnstGraphicsEdge* edge = (QnstGraphicsEdge*) entity;
2348 
2349  if (edge->getEntityA() != NULL)
2350  {
2351  if (edge->getEntityA()->getncgType() == Qncg::Node ||
2352  edge->getEntityA()->getncgType() == Qncg::Interface )
2353  {
2354  ((QnstGraphicsEntityWithEdges*) edge->getEntityA())->removenstGraphicsEdge(edge);
2355  }
2356  }
2357 
2358  if (edge->getEntityB() != NULL)
2359  {
2360  if (edge->getEntityB()->getncgType() == Qncg::Node ||
2361  edge->getEntityB()->getncgType() == Qncg::Interface )
2362  {
2363  ((QnstGraphicsEntityWithEdges*) edge->getEntityB())->removenstGraphicsEdge(edge);
2364 
2365  }
2366  }
2367 
2368  if(entities.contains(entity->getSwitchPortUid()))
2369  {
2370  QnstGraphicsEntity* parent =
2371  entities[entity->getSwitchPortUid()]->getnstGraphicsParent();
2372  parent->addnstGraphicsEntity(edge);
2373 
2374  if (!parent->getnstGraphicsEntities().contains(edge))
2375  parent->addnstGraphicsEntity(edge);
2376 
2377  edge->setEntityA(entities[entity->getSwitchPortUid()]);
2378 
2379  if (entity->getInterfaceUid() != "" &&
2380  entities.contains(entity->getInterfaceUid()))
2381  {
2382  edge->setEntityB(entities[entity->getInterfaceUid()]);
2383  }
2384  else
2385  {
2386  edge->setEntityB(entities[entity->getComponentUid()]);
2387  }
2388 
2389  ((QnstGraphicsInterface*) edge->getEntityA())->addnstGraphicsEdge(entity);
2390  ((QnstGraphicsNode*) edge->getEntityB())->addnstGraphicsEdge(entity);
2391 
2392  edge->adjust();
2393  }
2394  }
2395  // entities does not contains componentUID or switchPortUID
2396  else
2397  {
2398  QnstGraphicsEdge* edge = (QnstGraphicsEdge*) entity;
2399 
2400  if (edge->getEntityA() != NULL)
2401  {
2402  if (edge->getEntityA()->getncgType() == Qncg::Node ||
2403  edge->getEntityA()->getncgType() == Qncg::Interface )
2404  {
2405  ((QnstGraphicsEntityWithEdges*) edge->getEntityA())->removenstGraphicsEdge(edge);
2406  }
2407  }
2408 
2409  if (edge->getEntityB() != NULL)
2410  {
2411  if (edge->getEntityB()->getncgType() == Qncg::Node ||
2412  edge->getEntityB()->getncgType() == Qncg::Interface )
2413  {
2414  ((QnstGraphicsEntityWithEdges*) edge->getEntityB())->removenstGraphicsEdge(edge);
2415  }
2416  }
2417 
2418  QnstGraphicsEntity* parent = edge->getnstGraphicsParent();
2419  parent->removenstGraphicsEntity(edge);
2420  }
2421 }
2422 
2423 void QnstView::changeLink(QnstGraphicsLink* entity,
2424  const QMap<QString, QString> &properties)
2425 {
2426  if (entity != NULL)
2427  {
2428  if (properties["id"] != "")
2429  {
2430  entity->setnstId(properties["id"]);
2431  }
2432 
2433  if (properties["xconnector"] != "")
2434  {
2435  entity->setxConnector(properties["xconnector"]);
2436  entity->setxConnectorUID(properties["xconnectorUID"]);
2437  }
2438 
2439  adjustLink(entity);
2440  }
2441 }
2442 
2443 void QnstView::adjustLink(QnstGraphicsLink* entity)
2444 {
2445  // TODO
2446 }
2447 
2448 void QnstView::adjustBind(QnstGraphicsBind* bind)
2449 {
2450  QnstGraphicsLink *link = NULL;
2451  QnstGraphicsEntity *target = NULL;
2452 
2453  link = bind->getLink();
2454 
2455  // set the connector of bind
2456  if(connectors.contains(link->getxConnector()))
2457  bind->setConn(connectors[link->getxConnector()]);
2458 
2459  if(bind->getInterfaceUid() != "" && entities.contains(bind->getInterfaceUid()))
2460  target = entities[bind->getInterfaceUid()];
2461  else if(entities.contains(bind->getComponentUid()))
2462  target = entities[bind->getComponentUid()];
2463 
2464  //Remove old
2465  if(bind->getTarget())
2466  {
2467  ((QnstGraphicsEntityWithEdges*)bind->getTarget())->removenstGraphicsEdge(bind);
2468  }
2469 
2470  //Set new
2471  if(target)
2472  ((QnstGraphicsEntityWithEdges*)target)->addnstGraphicsEdge(bind);
2473 
2474  if(link)
2475  {
2476  link->removenstGraphicsEdge(bind);
2477  link->addnstGraphicsEdge(bind);
2478  }
2479 
2480  bind->setLink(link);
2481  bind->setTarget(target);
2482 
2483  // adjusting bind
2484  adjustAngles(bind);
2485 
2486  //check if the bind is valid
2487  if(link &&
2488  connectors.contains(link->getxConnector()))
2489  {
2490  QnstConnector *connector = connectors[link->getxConnector()];
2491  if(!connector->getConditions().values().contains(bind->getRole()) &&
2492  !connector->getActions().values().contains(bind->getRole()))
2493  {
2494  bind->setInvalid(true);
2495  }
2496  else
2497  bind->setInvalid(false);
2498  }
2499  else
2500  {
2501  bind->setInvalid(true);
2502  }
2503 
2504  bind->adjust();
2505  // \todo interface
2506 }
2507 
2508 void QnstView::addConnector(const QString &uid,
2509  const QMap<QString, QString> &properties)
2510 {
2511  if (!connectors2.contains(uid))
2512  {
2513  QnstConnector* entity = new QnstConnector();
2514  entity->setnstUid(uid);
2515 
2516  if (properties["id"] != "")
2517  {
2518  entity->setName(properties["id"]);
2519  entity->setnstId(properties["id"]);
2520  }
2521 
2522  connectors2[uid] = entity;
2523 
2524  foreach(QnstConnector* c, connectors.values())
2525  {
2526  if (c->getnstUid() == entity->getnstUid())
2527  {
2528  connectors.remove(connectors.key(c));
2529  break;
2530  }
2531  }
2532 
2533  if (entity->getnstId() != "")
2534  connectors[entity->getnstId()] = entity;
2535  }
2536 }
2537 
2538 void QnstView::adjustAll()
2539 {
2540  traceConnectors();
2541  traceConnectors2();
2542 
2543  foreach(QnstGraphicsEntity *entity, entities.values())
2544  {
2545  switch(entity->getnstType())
2546  {
2547  case Qnst::Action:
2548  case Qnst::Condition:
2549  case Qnst::Bind:
2550  {
2551  QnstGraphicsBind *bind = dynamic_cast <QnstGraphicsBind *>(entity);
2552  if(bind)
2553  adjustBind(bind);
2554  break;
2555  }
2556  // if the entity type is MEDIA
2557  case Qnst::Audio:
2558  case Qnst::Text:
2559  case Qnst::Video:
2560  case Qnst::Image:
2561  case Qnst::NCLua:
2562  case Qnst::Settings:
2563  case Qnst::Media:
2564  case Qnst::Html:
2565  case Qnst::NCL:
2566  {
2567  QnstGraphicsMedia *media = dynamic_cast <QnstGraphicsMedia *>(entity);
2568  if(media)
2569  adjustMedia(media);
2570  break;
2571  }
2572  default:
2573  // nothing todo
2574  break;
2575  }
2576  }
2577 }
2578 
2579 void QnstView::changeConnector(QnstConnector* entity,
2580  const QMap<QString, QString> &properties)
2581 {
2582  qWarning() << "QnstView::changeConnector" << entity << properties;
2583  if (properties["id"] != "")
2584  {
2585  entity->setName(properties["id"]);
2586  entity->setnstId(properties["id"]);
2587  }
2588 
2589  foreach(QnstConnector* c, connectors.values())
2590  {
2591  if (c->getnstUid() == entity->getnstUid())
2592  {
2593  connectors.remove(connectors.key(c));
2594  break;
2595  }
2596  }
2597 
2598  if (entity->getnstId() != "")
2599  connectors[entity->getnstId()] = entity;
2600 }
2601 
2602 void QnstView::addCondition(const QString &uid,
2603  const QMap<QString, QString> &properties)
2604 {
2605  if (connectors2.contains(properties["connector"]))
2606  {
2607  QnstConnector* connector = connectors2[properties["connector"]];
2608 
2609  if (properties["role"] != "")
2610  connector->addCondition(uid, properties["role"]);
2611 
2612  foreach(QString key, properties.keys())
2613  {
2614  if (key.startsWith("param"))
2615  {
2616  QString num = key.replace("param","");
2617 
2618  connector->addConditionParam(uid, properties.value("attr"+num), properties.value(key));
2619  }
2620  }
2621  }
2622  else
2623  qWarning() << "[QNST] Trying yo add a condition to a connector that does not exist.";
2624 }
2625 
2626 void QnstView::changeCondition(const QString &uid,
2627  const QMap<QString, QString> &properties)
2628 {
2629  if (connectors2.contains(properties["connector"]))
2630  {
2631  QnstConnector* connector = connectors2[properties["connector"]];
2632 
2633  if (connector->getConditions().contains(uid))
2634  connector->removeCondition(uid);
2635 
2636  if (properties["role"] != "")
2637  {
2638  qWarning() << "CHANGING CONDITION" << properties["role"];
2639  connector->addCondition(uid, properties["role"]);
2640 
2641  foreach(QString key, properties.keys())
2642  {
2643  if (key.startsWith("param"))
2644  {
2645  QString num = key.replace("param","");
2646 
2647  connector->addConditionParam(uid, properties.value("attr"+num), properties.value(key));
2648  }
2649  }
2650  }
2651  }
2652  else
2653  qWarning() << "[QNST] Trying yo change a condition in a connector that does not exist.";
2654 }
2655 
2656 void QnstView::addAction(const QString &uid,
2657  const QMap<QString, QString> &properties)
2658 {
2659  if (connectors2.contains(properties["connector"]))
2660  {
2661  QnstConnector* connector = connectors2[properties["connector"]];
2662 
2663  if (properties["role"] != "")
2664  connector->addAction(uid, properties["role"]);
2665 
2666  foreach(QString key, properties.keys())
2667  {
2668  if (key.startsWith("param"))
2669  {
2670  QString num = key.replace("param","");
2671 
2672  connector->addActionParam(uid, properties.value("attr"+num), properties.value(key));
2673  }
2674  }
2675  }
2676 }
2677 
2678 void QnstView::changeAction(const QString &uid,
2679  const QMap<QString, QString> &properties)
2680 {
2681  if (connectors2.contains(properties["connector"]))
2682  {
2683  QnstConnector* connector = connectors2[properties["connector"]];
2684 
2685  if (connector->getActions().contains(uid))
2686  connector->getActions().remove(uid);
2687 
2688  if (properties["role"] != "")
2689  connector->addAction(uid, properties["role"]);
2690  }
2691 }
2692 
2693 void QnstView::changeBindParam(const QString &uid,
2694  const QMap<QString, QString> &properties)
2695 {
2696  if (entities.contains(properties.value("parent")))
2697  {
2698  QnstGraphicsEntity* e = entities[properties.value("parent")];
2699 
2700  QnstGraphicsBind* bind = (QnstGraphicsBind*) e;
2701  bind->setParam(properties.value("name",""), properties.value("value",""));
2702  }
2703 }
2704 
2705 void QnstView::addConnectorParam(const QString &uid,
2706  const QString &parent,
2707  const QMap<QString, QString> &properties)
2708 {
2709  if (connectors2.contains(parent))
2710  {
2711  QnstConnector* conn = connectors2[parent];
2712  conn->addParam(uid, properties["name"]);
2713  }
2714 }
2715 
2716 void QnstView::changeConnectorParam(const QString &uid,
2717  const QMap<QString, QString> &properties)
2718 {
2719  if (connectors2.contains(properties["parent"]))
2720  {
2721  QnstConnector* conn = connectors2[properties["parent"]];
2722  conn->addParam(uid, properties["name"]);
2723  }
2724 }
2725 
2726 void QnstView::requestEntityAddition(QnstGraphicsEntity* entity, bool undo)
2727 {
2728  qDebug() << "[QNST]" << ":" << "Requesting entity addition '"+entity->getnstUid()+"'";
2729  // qDebug() << links.keys();
2730 
2731  QMap<QString, QString> properties;
2732  QMap <QString, QString> additionalData;
2733  bool ok = false;
2734 
2735  if (entity != NULL)
2736  {
2737  entities[entity->getnstUid()] = entity;
2738 
2739  // Loading additional data
2740  additionalData = entity->getUsrData();
2741  foreach(QString key, additionalData.keys())
2742  {
2743  if(!properties.contains(key))
2744  properties.insert(key, additionalData.value(key));
2745  }
2746  //end loading additional data
2747 
2748 
2749  // \fixme Should this come only after the switch/case ?
2750  entity->getProperties(properties);
2751 
2752  switch(entity->getnstType())
2753  {
2754  case Qnst::Body:
2755  {
2756  if (undo){ scene->addRoot(entity); }
2757 
2758  properties["TYPE"] = "body";
2759  ok = true;
2760  break;
2761  }
2762 
2763  case Qnst::Context:
2764  {
2765  if (entity->getnstId() == "" && !undo)
2766  updateEntityWithUniqueNstId(entity);
2767 
2768  properties["TYPE"] = "context";
2769  properties["id"] = entity->getnstId();
2770 
2771  ok = true;
2772  break;
2773  }
2774 
2775  case Qnst::Switch:
2776  {
2777  if (entity->getnstId() == "" && !undo)
2778  updateEntityWithUniqueNstId(entity);
2779 
2780  properties["TYPE"] = "switch";
2781  properties["id"] = entity->getnstId();
2782  ok = true;
2783  break;
2784  }
2785 
2786  // if the entity type is MEDIA
2787  case Qnst::Audio:
2788  case Qnst::Text:
2789  case Qnst::Video:
2790  case Qnst::Image:
2791  case Qnst::NCLua:
2792  case Qnst::Settings:
2793  case Qnst::Html:
2794  case Qnst::NCL:
2795  case Qnst::Media:
2796  {
2797  if (entity->getnstId() == "" && !undo)
2798  updateEntityWithUniqueNstId(entity);
2799 
2800  QnstGraphicsMedia *media = dynamic_cast<QnstGraphicsMedia *>(entity);
2801 
2802  if(media)
2803  {
2804  properties["TYPE"] = "media";
2805  properties["id"] = entity->getnstId();
2806 
2807  ok = true;
2808  }
2809  break;
2810  }
2811 
2812  case Qnst::Port:
2813  {
2814  if (entity->getnstId() == "" && !undo)
2815  updateEntityWithUniqueNstId(entity);
2816 
2817  QnstGraphicsPort *port = dynamic_cast <QnstGraphicsPort *> (entity);
2818 
2819  properties["TYPE"] = "port";
2820  properties["id"] = entity->getnstId();
2821 
2822  // \fixme Do I really need the following code?
2823  if(port)
2824  {
2825  foreach(QnstGraphicsEdge* edge, port->getnstGraphicsEdges())
2826  {
2827  if (edge->getnstType() == Qnst::Reference)
2828  {
2829  properties["COMPONENT"] = edge->getEntityA()->getnstUid();
2830  properties["component"] = edge->getEntityA()->getnstId();
2831 
2832  if (edge->getEntityB()->getnstType() == Qnst::Port ||
2833  edge->getEntityB()->getnstType() == Qnst::Property ||
2834  edge->getEntityB()->getnstType() == Qnst::Area)
2835  {
2836  properties["INTERFACE"] = edge->getEntityB()->getnstUid();;
2837  properties["interface"] = edge->getEntityB()->getnstId();;
2838  }
2839  }
2840  }
2841 
2842  ok = true;
2843  }
2844  break;
2845  }
2846 
2847  case Qnst::Area:
2848  {
2849  if (entity->getnstId() == "" && !undo)
2850  updateEntityWithUniqueNstId(entity);
2851 
2852  properties["TYPE"] = "area";
2853  properties["id"] = entity->getnstId();
2854 
2855  // \fixme Do I really need the following code?
2856  if(entity->getnstGraphicsParent()->isMedia())
2857  {
2858  QnstGraphicsMedia *media =
2859  dynamic_cast <QnstGraphicsMedia *>(entity->getnstGraphicsParent());
2860 
2861  if(media != NULL)
2862  adjustMedia(media);
2863  }
2864 
2865  foreach (QString key,
2866  refers.keys(entity->getnstGraphicsParent()->getnstUid()))
2867  {
2868  if (entities.contains(key))
2869  {
2870  if (entities[key]->isMedia())
2871  adjustMedia((QnstGraphicsMedia*) entities[key]);
2872  }
2873  }
2874 
2875  ok = true;
2876  break;
2877  }
2878 
2879  case Qnst::Property:
2880  {
2881  properties["TYPE"] = "property";
2882 
2883  // \fixme Do I really need the following code?
2884  if(entity->getnstGraphicsParent()->isMedia())
2885  {
2886  QnstGraphicsMedia *media =
2887  dynamic_cast <QnstGraphicsMedia *>(entity->getnstGraphicsParent());
2888 
2889  if(media != NULL)
2890  adjustMedia(media);
2891  }
2892 
2893  foreach (QString key,
2894  refers.keys(entity->getnstGraphicsParent()->getnstUid()))
2895  {
2896  if (entities.contains(key))
2897  {
2898  if (entities[key]->isMedia())
2899  adjustMedia((QnstGraphicsMedia*) entities[key]);
2900  }
2901  }
2902 
2903  ok = true;
2904  break;
2905  }
2906 
2907  case Qnst::Aggregator:
2908  {
2909  qWarning() << "Trying to add an Aggregator!!! This is not supported \
2910  anymore!!";
2911 
2912  // \fixme This should be deprecated!!
2913  // entities[entity->getnstUid()] = entity;
2914  break;
2915  }
2916 
2917  case Qnst::Link:
2918  {
2919  QnstGraphicsLink *link = dynamic_cast<QnstGraphicsLink*>(entity);
2920 
2921  // \fixme Do I really need the following code?
2922  if(link)
2923  {
2924  if (entity->getnstId() == "" && !undo)
2925  updateEntityWithUniqueNstId(entity);
2926 
2927  properties["TYPE"] = "link";
2928  properties["id"] = entity->getnstId();
2929  properties["xconnector"] = link->getxConnector();
2930 
2931  entities[entity->getnstUid()] = entity;
2932  links[entity->getnstUid()] = link;
2933 
2934  ok = true;
2935  }
2936  break;
2937  }
2938 
2939  case Qnst::Bind:
2940  case Qnst::Condition:
2941  case Qnst::Action:
2942  {
2943  if (!binds.contains(entity->getnstUid()))
2944  {
2945  QnstGraphicsBind* bind = dynamic_cast <QnstGraphicsBind*>(entity);
2946  if(bind)
2947  {
2948  properties["TYPE"] = "bind";
2949 
2950  // \fixme Do I really need the following code?
2951  if(bind->getLink() != NULL)
2952  {
2953  properties["connector"] = bind->getLink()->getxConnector();
2954  properties["linkUID"] = bind->getLink()->getnstUid();
2955  properties["link"] = bind->getLink()->getnstId();
2956  }
2957  else
2958  {
2959  qWarning() << "[QNST] Warning!!! Bind is not associated to link!";
2960  return;
2961  }
2962 
2963  if (bind->isCondition())
2964  {
2965  properties["role"] =
2966  QnstUtil::getStrFromBindType(bind->getType());
2967  properties["condition"] = bind->getRole();
2968  }
2969  else
2970  {
2971  properties["action"] = bind->getRole();
2972  properties["role"] =
2973  QnstUtil::getStrFromBindType(bind->getType());
2974  }
2975 
2976  properties["component"] = bind->getComponent();
2977  properties["interface"] = bind->getInterface();
2978 
2979  binds[bind->getnstUid()] = bind;
2980 
2981  ok = true;
2982  }
2983  }
2984  break;
2985  }
2986 
2987  case Qnst::SwitchPort:
2988  {
2989  if (entity->getnstId() == "" && !undo)
2990  updateEntityWithUniqueNstId(entity);
2991 
2992  properties["TYPE"] = "switchPort";
2993  properties["id"] = entity->getnstId();
2994 
2995  ok = true;
2996  break;
2997  }
2998 
2999  default:
3000  // do nothing
3001  break;
3002  }
3003 
3004  if(ok)
3005  {
3006  entity->updateToolTip();
3007 
3008  if(entity->getnstType() == Qnst::Body)
3009  {
3010  emit entityAdded(entity->getnstUid(), "", properties);
3011  }
3012  else
3013  {
3014  emit entityAdded(entity->getnstUid(),
3015  entity->getnstGraphicsParent()->getnstUid(),
3016  properties);
3017  }
3018 
3019  if (!undo)
3020  {
3021  QnstAddCommand* cmd = new QnstAddCommand(this, entity);
3022  history.push(cmd);
3023  }
3024  }
3025  }
3026 }
3027 
3028 // \todo refactory
3029 void QnstView::requestEntityRemotion(QnstGraphicsEntity* entity, bool undo,
3030  bool rmRefs, bool notify)
3031 {
3032  qDebug() << "[QNST]" << ":" << "Requesting entity remotion '" +
3033  entity->getnstUid() + "'" +
3034  entity->getnstType() + "=" +
3035  QnstUtil::getStrFromNstType(entity->getnstType());
3036 
3037  // traceEntities();
3038 
3039  if (entity != NULL)
3040  {
3041  Qncg::EntityType qncgType = entity->getncgType();
3042  bool mustRemoveFromParent = false;
3043 
3044  // By now, we are handling undo only for node and interface!!
3045  if( entity->getncgType() == Qncg::Node ||
3046  entity->getncgType() == Qncg::Interface )
3047  {
3048  if (!undo)
3049  {
3050  QnstRemoveCommand* cmd = new QnstRemoveCommand(this, entity);
3051  history.push(cmd);
3052  }
3053  }
3054 
3055  QString UID = entity->getnstUid();
3056 
3057  switch (qncgType)
3058  {
3059  case Qncg::Node:
3060  {
3061  QnstGraphicsNode *node = dynamic_cast <QnstGraphicsNode*>(entity);
3062 
3063  if(node)
3064  removeEdgesOfEntity(node, false); // Remove the edges of this entity
3065  else
3066  qWarning() << "Could not make a cast to QnstGraphicsNode*";
3067 
3068  // Remove recursively
3069  foreach(QnstGraphicsEntity* e, entity->getnstGraphicsEntities())
3070  {
3071  if (e->getnstType() != Qnst::Edge &&
3072  e->getnstType() != Qnst::Condition &&
3073  e->getnstType() != Qnst::Mapping &&
3074  e->getnstType() != Qnst::Action &&
3075  e->getnstType() != Qnst::Reference)
3076  {
3077  requestEntityRemotion(e, true, false);
3078  }
3079  }
3080 
3081  mustRemoveFromParent = true;
3082  break;
3083  }
3084 
3085  case Qncg::Interface:
3086  {
3087  QnstGraphicsInterface *interface =
3088  dynamic_cast <QnstGraphicsInterface*>(entity);
3089 
3090  if(interface)
3091  removeEdgesOfEntity(interface, false); // Remove the edges of this entity
3092  else
3093  qWarning() << "Could not make a cast to QnstGraphicsInterface*";
3094 
3095  mustRemoveFromParent = true;
3096  break;
3097  }
3098 
3099  case Qncg::Edge:
3100  {
3101  QnstGraphicsEdge *edge = dynamic_cast<QnstGraphicsEdge *>(entity);
3102 
3103  if(edge)
3104  removeEdge(edge, notify);
3105  break;
3106  }
3107 
3108  default:
3109  // do nothing?
3110  mustRemoveFromParent = true;
3111  break;
3112  }
3113 
3114  // Everything is ok, now only remove the entity from its parent
3115  if(mustRemoveFromParent)
3116  {
3117  //Remove the entity of its parent
3118  QnstGraphicsEntity* parent = entity->getnstGraphicsParent();
3119  if (parent != NULL)
3120  parent->removenstGraphicsEntity(entity);
3121  else
3122  scene->removeRoot(entity);
3123 
3124  if (selected == entity)
3125  selected = NULL;
3126 
3127  if (clipboard == entity)
3128  clipboard = NULL;
3129 
3130  if (entity->getnstType() == Qnst::Link)
3131  {
3132  if (links.contains(entity->getnstUid()))
3133  {
3134  links.remove(entity->getnstUid());
3135  }
3136  }
3137 
3138  entities.remove(entity->getnstUid());
3139 
3140  if (entity->getnstType() == Qnst::Link)
3141  {
3142  if (links.contains(entity->getnstUid()))
3143  {
3144  links.remove(entity->getnstUid());
3145  }
3146  }
3147 
3148  if(notify) //\fixme We need a better way to handle that!!!
3149  emit entityRemoved(entity->getnstUid());
3150 
3151  delete entity;
3152 
3153  if (qncgType == Qncg::Interface)
3154  {
3155  if (refers.contains(UID))
3156  {
3157  refers.remove(UID);
3158  }
3159  else
3160  {
3161  if (parent != NULL && parent->isMedia())
3162  {
3163  adjustMedia((QnstGraphicsMedia*)parent);
3164 
3165  foreach(QString rUid, refers.keys(parent->getnstUid()))
3166  {
3167  if (entities.contains(rUid))
3168  {
3169  QnstGraphicsEntity* e = entities.value(rUid);
3170 
3171  if (e->isMedia())
3172  adjustMedia((QnstGraphicsMedia*)e);
3173  }
3174  }
3175  }
3176  }
3177  }
3178  else
3179  {
3180  foreach(QString ruid, refers.keys(UID))
3181  {
3182  refers.remove(ruid);
3183 
3184  if (entities.contains(ruid))
3185  {
3186  QnstGraphicsEntity* e = entities.value(ruid);
3187 
3188  if (e->isMedia())
3189  {
3190  qDebug() << "=================== un, hello!";
3191  adjustMedia((QnstGraphicsMedia*) e);
3192  }
3193  }
3194  }
3195 
3196  if (refers.contains(UID))
3197  {
3198  qWarning() << "Removing" + UID + "from refers.";
3199  refers.remove(UID);
3200  }
3201  }
3202  }
3203  }
3204 
3205  deletePendingEntities();
3206 }
3207 
3208 void QnstView::removeEdgesOfEntity(QnstGraphicsEntityWithEdges *entity,
3209  bool notify)
3210 {
3211  foreach(QnstGraphicsEdge* edge, entity->getnstGraphicsEdges())
3212  {
3213  requestEntityRemotion(edge, false, false, notify);
3214  }
3215 }
3216 
3217 void QnstView::removeEdge(QnstGraphicsEdge *edge, bool notify)
3218 {
3219  if(edge->getEntityA())
3220  {
3221  if ( edge->getEntityA()->getncgType() == Qncg::Node ||
3222  edge->getEntityA()->getncgType() == Qncg::Interface )
3223  {
3224  ((QnstGraphicsEntityWithEdges*) edge->getEntityA())->removenstGraphicsEdge(edge);
3225  }
3226  }
3227 
3228  if( edge->getEntityB() )
3229  {
3230  if ( edge->getEntityB()->getncgType() == Qncg::Node ||
3231  edge->getEntityB()->getncgType() == Qncg::Interface )
3232  {
3233  ((QnstGraphicsEntityWithEdges*) edge->getEntityB())->removenstGraphicsEdge(edge);
3234  }
3235  }
3236 
3237  if (edge->getnstType() == Qnst::Condition ||
3238  edge->getnstType() == Qnst::Action ||
3239  edge->getnstType() == Qnst::Bind)
3240  {
3241  QnstGraphicsBind* bb = binds[edge->getnstUid()];
3242 
3243  if (bb != NULL)
3244  {
3245  QnstGraphicsLink* ll = (QnstGraphicsLink*) bb->getLink();
3246  if (ll != NULL)
3247  {
3248  if (ll->getConditions().contains(bb->getnstUid()))
3249  ll->removeCondition(bb);
3250 
3251  if (ll->getActions().contains(bb->getnstUid()))
3252  ll->removeAction(bb);
3253  }
3254 
3255  binds.remove(bb->getnstUid());
3256  }
3257  }
3258  else if (edge->getnstType() == Qnst::Reference)
3259  {
3260  QnstGraphicsPort* p = (QnstGraphicsPort*) edge->getEntityA();
3261  p->setComponent("");
3262  p->setComponentUid("");
3263  p->setInterface("");
3264  p->setInterfaceUid("");
3265  // requestEntityChange(p);
3266  }
3267  else if (edge->getnstType() == Qnst::Mapping)
3268  {
3269  // Do nothing ??
3270  // QnstGraphicsEntity* parent = edge->getnstGraphicsParent();
3271  // parent->removenstGraphicsEntity(edge);
3272  // }
3273 
3274  // entities.remove(edge->getnstUid());
3275  // emit entityRemoved(edge->getnstUid());
3276  }
3277 
3278  QnstGraphicsEntity* parent = edge->getnstGraphicsParent();
3279  if (parent)
3280  {
3281  parent->removenstGraphicsEntity(edge);
3282  entities.remove(edge->getnstUid());
3283  }
3284 
3285  if (edge->getnstType() != Qnst::Reference)
3286  {
3287  if(notify)
3288  emit entityRemoved(edge->getnstUid());
3289  }
3290 
3291  if (selected == edge)
3292  selected = NULL;
3293 
3294  if (clipboard == edge)
3295  clipboard = NULL;
3296 
3297  // delete edge;
3298 }
3299 
3300 void QnstView::requestEntityPreparation(QnstGraphicsEntity* entity,
3301  QMap<QString, QString> properties)
3302 {
3303  QnstChangeCommand* cmd = new QnstChangeCommand(this, entity->getnstUid(),
3304  properties);
3305  history.push(cmd);
3306 
3307  emit viewChanged();
3308 }
3309 
3310 void QnstView::requestEntityChange(QnstGraphicsEntity* entity)
3311 {
3312  qDebug() << "[QNST]" << ":" << "Requesting entity change '" + entity->getnstUid() + "'";
3313 
3314  QMap<QString, QString> properties;
3315  QMap <QString, QString> additionalData;
3316  bool ok = false;
3317 
3318  if (entity != NULL)
3319  {
3320  // Load Additional data
3321  additionalData = entity->getUsrData();
3322  foreach(QString key, additionalData.keys())
3323  {
3324  if(!properties.contains(key))
3325  properties.insert(key, additionalData.value(key));
3326  }
3327  // end load of additional data
3328 
3329  entity->getProperties(properties);
3330 
3331  switch(entity->getnstType())
3332  {
3333  case Qnst::Body:
3334  {
3335  properties["TYPE"] = "body";
3336  ok = true;
3337  break;
3338  }
3339 
3340  case Qnst::Context:
3341  {
3342  properties["TYPE"] = "context";
3343  ok = true;
3344  break;
3345  }
3346 
3347  case Qnst::Switch:
3348  {
3349  properties["TYPE"] = "switch";
3350  ok = true;
3351  break;
3352  }
3353 
3354  // if the entity type is MEDIA
3355  case Qnst::Audio:
3356  case Qnst::Text:
3357  case Qnst::Video:
3358  case Qnst::Image:
3359  case Qnst::NCLua:
3360  case Qnst::Settings:
3361  case Qnst::Html:
3362  case Qnst::NCL:
3363  case Qnst::Media:
3364  {
3365  properties["TYPE"] = "media";
3366  ok = true;
3367  break;
3368  }
3369 
3370  // if the entity type is PORT
3371  case Qnst::Port:
3372  {
3373  properties["TYPE"] = "port";
3374 
3375  //\fixme DO I really need that?
3376  QnstGraphicsPort *port = dynamic_cast <QnstGraphicsPort *> (entity);
3377  foreach(QnstGraphicsEdge* edge, port->getnstGraphicsEdges())
3378  {
3379  if (edge->getnstType() == Qnst::Reference)
3380  {
3381  if (edge->getEntityB()->getnstType() == Qnst::Port ||
3382  edge->getEntityB()->getnstType() == Qnst::Property ||
3383  edge->getEntityB()->getnstType() == Qnst::Area)
3384  {
3385  properties["INTERFACE"] = edge->getEntityB()->getnstUid();
3386  properties["interface"] = edge->getEntityB()->getnstId();
3387 
3388  properties["COMPONENT"] = edge->getEntityB()->getnstGraphicsParent()->getnstUid();
3389  properties["component"] = edge->getEntityB()->getnstGraphicsParent()->getnstId();
3390  }
3391  else
3392  {
3393  properties["COMPONENT"] = edge->getEntityB()->getnstUid();
3394  properties["component"] = edge->getEntityB()->getnstId();
3395 
3396  properties["INTERFACE"] = "";
3397  properties["interface"] = "";
3398  }
3399 
3400  break; // there is only one match, so 'break'.
3401  }
3402  }
3403 
3404  ok = true;
3405  break;
3406  }
3407 
3408  case Qnst::Link:
3409  {
3410  properties["TYPE"] = "link";
3411  ok = true;
3412  break;
3413  }
3414 
3415  case Qnst::Area:
3416  case Qnst::Property:
3417  case Qnst::Aggregator:
3418  {
3419  // do nothing ??
3420  break;
3421  }
3422 
3423  case Qnst::SwitchPort:
3424  {
3425  properties["TYPE"] = "switchPort";
3426  ok = true;
3427  break;
3428  }
3429 
3430  case Qnst::BindParam:
3431  {
3432  // \todo
3433  }
3434 
3435  default:
3436  // do nothing
3437  break;
3438  }
3439 
3440  if(ok)
3441  {
3442  entity->updateToolTip();
3443 
3444  emit entityChanged(entity->getnstUid(), properties);
3445  }
3446 
3447  // Undo ??
3448  }
3449 }
3450 
3451 void QnstView::requestEntitySelection(QnstGraphicsEntity* entity)
3452 {
3453  qDebug() << "[QNST]" << ":"
3454  << "Requesting entity selection '" + entity->getnstUid() + "'";
3455 
3456  if (entity != NULL)
3457  {
3458  if (entity->isSelected())
3459  {
3460  if (selected != NULL)
3461  {
3462  selected->setSelected(false);
3463  selected->adjust();
3464  }
3465 
3466  selected = entity;
3467 
3468  if (!entity->isMedia() && refers.contains(entity->getnstUid()))
3469  {
3470  qDebug() << "========================" << "REF" << entity->getnstUid() << "->" << refers[entity->getnstUid()];
3471  emit entitySelected(refers[entity->getnstUid()]);
3472  }
3473  else
3474  {
3475  qDebug() << "========================" << entity->getnstUid();
3476  emit entitySelected(entity->getnstUid());
3477  }
3478  }
3479  }
3480 }
3481 
3482 void QnstView::performHelp()
3483 {
3484  // TODO
3485 }
3486 
3487 /*void QnstView::performUndo()
3488 {
3489  if (history.canUndo()){
3490  history.undo();
3491  }
3492 }
3493 
3494 void QnstView::performRedo()
3495 {
3496  if (history.canRedo()){
3497  history.redo();
3498  }
3499 }*/
3500 
3501 void QnstView::performCut()
3502 {
3503  if (selected != NULL)
3504  {
3505  if (selected->getnstType() != Qnst::Body)
3506  {
3507  if (clipboard != NULL)
3508  {
3509  delete clipboard; clipboard = NULL;
3510  }
3511 
3512  QnstGraphicsEntity* entity = selected;
3513 
3514  clipboard = QnstUtil::makeGraphicsEntity(entity->getnstType());
3515 
3516  if (clipboard != NULL)
3517  {
3518  clipboard->setnstId(entity->getnstId());
3519 
3520  clipboard->setTop(entity->getTop());
3521  clipboard->setLeft(entity->getLeft());
3522  clipboard->setWidth(entity->getWidth());
3523  clipboard->setHeight(entity->getHeight());
3524  clipboard->setnstGraphicsParent(NULL);
3525 
3526  clipboard->setUsrData(entity->getUsrData());
3527 
3528  foreach(QnstGraphicsEntity* e, entity->getnstGraphicsEntities())
3529  {
3530  performCopy(e, clipboard);
3531  }
3532 
3533  requestEntityRemotion(selected);
3534 
3535  foreach(QnstGraphicsEntity* e, entities.values())
3536  {
3537  if (e->getnstType() == Qnst::Body ||
3538  e->getnstType() == Qnst::Context ||
3539  e->getnstType() == Qnst::Switch)
3540  {
3541  e->menu->actionPaste->setEnabled(true);
3542  }
3543  }
3544 
3545  hasCutted = true;
3546  }
3547  }
3548  else
3549  {
3550  QMessageBox::warning(this, "Alert",
3551  "You cannot cut a &lt;body&gt; element!");
3552  }
3553  }
3554 }
3555 
3556 void QnstView::performCopy()
3557 {
3558  if (selected != NULL)
3559  {
3560  if (selected->getnstType() != Qnst::Body)
3561  {
3562  if (clipboard != NULL)
3563  {
3564  delete clipboard; clipboard = NULL;
3565  }
3566 
3567  QnstGraphicsEntity* entity = selected;
3568  clipboard = QnstUtil::makeGraphicsEntity(entity->getnstType());
3569 
3570  if (clipboard != NULL)
3571  {
3572  clipboard->setnstId(entity->getnstId());
3573  clipboard->setnstUid(entity->getnstUid());
3574 
3575  clipboard->setTop(entity->getTop());
3576  clipboard->setLeft(entity->getLeft());
3577  clipboard->setWidth(entity->getWidth());
3578  clipboard->setHeight(entity->getHeight());
3579 
3580  clipboard->setnstGraphicsParent(NULL);
3581  clipboard->setUsrData(entity->getUsrData());
3582 
3583  qDebug() << "[QNST]" << clipboard->getUsrData();
3584  foreach(QnstGraphicsEntity* e, entity->getnstGraphicsEntities())
3585  {
3586  performCopy(e, clipboard);
3587  }
3588 
3589  foreach(QnstGraphicsEntity* e, entities.values())
3590  {
3591  if (e->getnstType() == Qnst::Body ||
3592  e->getnstType() == Qnst::Context ||
3593  e->getnstType() == Qnst::Switch)
3594  {
3595  e->menu->actionPaste->setEnabled(true);
3596  }
3597  }
3598 
3599  hasCutted = false;
3600  }
3601 
3602  }
3603  else
3604  {
3605  QMessageBox::warning(this, "Alert",
3606  "You cannot copy a &lt;body&gt; element!");
3607  }
3608  }
3609 }
3610 
3611 void QnstView::performCopy(QnstGraphicsEntity* entity,
3612  QnstGraphicsEntity* parent)
3613 {
3614  QnstGraphicsEntity* copy = NULL;
3615 
3616  copy = QnstUtil::makeGraphicsEntity(entity->getnstType());
3617 
3618  if (copy != NULL)
3619  {
3620  copy->setnstId(entity->getnstId());
3621  copy->setnstUid(entity->getnstUid());
3622 
3623  copy->setTop(entity->getTop());
3624  copy->setLeft(entity->getLeft());
3625  copy->setWidth(entity->getWidth());
3626  copy->setHeight(entity->getHeight());
3627 
3628  parent->addnstGraphicsEntity(copy);
3629 
3630  qDebug() << "[QNST]" << entity->getUsrData();
3631  copy->setUsrData(entity->getUsrData());
3632 
3633  foreach(QnstGraphicsEntity* e, entity->getnstGraphicsEntities())
3634  {
3635  performCopy(e, copy);
3636  }
3637  }
3638 }
3639 
3640 void QnstView::performPaste()
3641 {
3642  if (clipboard != NULL)
3643  {
3644  QnstGraphicsEntity* copy = clipboard;
3645  qDebug() << "[QNST] performPaste() cliboard userdata = "
3646  << clipboard->getUsrData();
3647 
3648  QnstGraphicsEntity* parent = selected;
3649 
3650  if (copy != NULL && parent != NULL)
3651  {
3652  if (parent->getnstType() == Qnst::Context ||
3653  parent->getnstType() == Qnst::Switch ||
3654  parent->getnstType() == Qnst::Body)
3655  {
3656 
3657  int result = 1;
3658  if(!hasCutted) // if the user has cutted obviously he/she does not
3659  // want to make a reference
3660  {
3661  result = QMessageBox::question(
3662  this,
3663  tr("Copy"),
3664  tr("Would you like to make a reference instead?"),
3665  tr("Cancel"),
3666  tr("No"),
3667  tr("Yes"),
3668  1);
3669  }
3670 
3671  if (result == 0) // Cancel operation
3672  {
3673  return;
3674  }
3675  else // Make the copy
3676  {
3677  // result == 2 when the user asked to make a refer
3678  performPaste(copy, parent, (result == 2), false);
3679  }
3680  }
3681  }
3682  }
3683 }
3684 
3685 bool QnstView::updateEntityWithUniqueNstId(QnstGraphicsEntity *entity)
3686 {
3687  if(entity != NULL)
3688  {
3689  int n = 0;
3690  Qnst::EntityType type;
3691 
3692  // for any media, we will consider the same identifier prefix
3693  if(entity->isMedia())
3694  type = Qnst::Media;
3695  else
3696  type = entity->getnstType();
3697 
3698  // check if type is in the map
3699  if(!entityCounter.count(type))
3700  entityCounter[type] = 0;
3701 
3702  // change this check in future
3703  QString prefix = QnstUtil::getPrefixIdFromType(type);
3704 
3705  while(1) //
3706  {
3707  bool match = false;
3708 
3709  foreach(QnstGraphicsEntity* entity, entities.values())
3710  {
3711  if (entity->getnstId() == prefix + QString::number(n))
3712  {
3713  match = true;
3714  break;
3715  }
3716  }
3717 
3718  if (match)
3719  n++;
3720  else
3721  break;
3722  }
3723 
3724  entity->setnstId(QnstUtil::getPrefixIdFromType(type) +
3725  QString::number(n));
3726 
3727  return true;
3728  }
3729 
3730  return false;
3731 }
3732 
3733 void QnstView::performPaste(QnstGraphicsEntity* copy,
3734  QnstGraphicsEntity* parent,
3735  bool makeRefer, bool keepOriginalPos)
3736 {
3737  QnstGraphicsEntity* entity = QnstUtil::makeGraphicsEntity(copy->getnstType(),
3738  parent);
3739 
3740  if(entity != NULL)
3741  {
3742  // If I haven't cutted set a unique identifier to my entity
3743  if(!hasCutted)
3744  updateEntityWithUniqueNstId(entity);
3745  else
3746  {
3747  // \fixme Should we copy all properties?
3748  entity->setnstId(copy->getnstId());
3749  }
3750 
3751  // copy the position
3752  if(keepOriginalPos)
3753  {
3754  entity->setTop(copy->getTop());
3755  entity->setLeft(copy->getLeft());
3756  }
3757  else
3758  {
3759  entity->setTop(parent->getHeight()/2 - copy->getWidth()/2);
3760  entity->setLeft(parent->getWidth()/2 - copy->getHeight()/2);
3761  }
3762 
3763  // set the size
3764  entity->setWidth(copy->getWidth());
3765  entity->setHeight(copy->getHeight());
3766 
3767  // Should we make a Reference ??
3768  if (makeRefer)
3769  {
3770  performReference(entity, copy);
3771  }
3772  else if(entity->isMedia())
3773  {
3774  // \fixme Should we copy all properties?
3775  ((QnstGraphicsMedia*) entity)->setSource(copy->getUsrData()["src"]);
3776  }
3777 
3778  parent->addnstGraphicsEntity(entity);
3779 
3780  entity->adjust();
3781  entity->setUsrData(copy->getUsrData());
3782 
3783  requestEntityAddition(entity);
3784 
3785  if(entity->isMedia())
3786  {
3787  adjustMedia((QnstGraphicsMedia*) entity);
3788  }
3789 
3790  if (!makeRefer)
3791  {
3792  foreach(QnstGraphicsEntity* e, copy->getnstGraphicsEntities())
3793  {
3794  performPaste(e, entity, makeRefer, true);
3795  }
3796  }
3797  }
3798 }
3799 
3800 void QnstView::performReference(QnstGraphicsEntity* entity,
3801  QnstGraphicsEntity* referred)
3802 {
3803  if(entity != NULL)
3804  {
3805  // \fixme We should copy all properties
3806  if(entity->isMedia())
3807  {
3808  //Reference
3809  ((QnstGraphicsMedia*) entity)->setInstance("new");
3810  ((QnstGraphicsMedia*) entity)->setRefer(((QnstGraphicsMedia*) referred)->getnstId());
3811  ((QnstGraphicsMedia*) entity)->setReferUID(((QnstGraphicsMedia*) referred)->getnstUid());
3812 
3813  adjustMedia((QnstGraphicsMedia*) entity);
3814  }
3815 
3816  // \todo Refer for context and switch
3817  }
3818 }
3819 
3820 void QnstView::performDelete()
3821 {
3822  if (selected != NULL)
3823  {
3824  if(selected->getncgType() == Qncg::Interface &&
3825  ((QnstGraphicsInterface*)selected)->isRefer())
3826  {
3827  // ignore
3828  }
3829  else
3830  {
3831  requestEntityRemotion(selected);
3832  }
3833 
3834  scene->update();
3835  }
3836 }
3837 
3838 void QnstView::performExport()
3839 {
3840  QString location = QFileDialog::getSaveFileName(NULL, "Export...", "", tr("Images (*.png)"));
3841 
3842  if (location != ""){
3843  qreal top = 0;
3844  qreal left = 0;
3845  qreal width = scene->width();
3846  qreal height = scene->height();
3847 
3848  foreach (QnstGraphicsEntity* entity, scene->getRoots())
3849  {
3850  if (entity->getTop() > top)
3851  top = entity->getTop();
3852 
3853  if (entity->getLeft() > left)
3854  left = entity->getLeft();
3855 
3856  if (entity->getWidth() < width)
3857  width = entity->getWidth();
3858 
3859  if (entity->getHeight() < height)
3860  height = entity->getHeight();
3861  }
3862 
3863  QImage image(width, height, QImage::Format_ARGB32_Premultiplied);
3864 
3865  QPainter painter(&image);
3866 
3867  scene->render(&painter, QRect(), QRect(left-25,top-25,width+50,height+50));
3868 
3869  painter.end();
3870 
3871  image.save(location, "PNG");
3872  }
3873 }
3874 
3875 void QnstView::performZoomIn()
3876 {
3877  if (zoomStep > 0)
3878  {
3879  zoomStep--;
3880 
3881  resetMatrix();
3882 
3883  scale(1 - zoomStep*0.05, 1 - zoomStep*0.05);
3884  }
3885 }
3886 
3887 void QnstView::performZoomOut()
3888 {
3889  if (zoomStep*0.05 < 0.9)
3890  {
3891  zoomStep++;
3892 
3893  resetMatrix();
3894 
3895  scale(1 - zoomStep*0.05, 1 - zoomStep*0.05);
3896  }
3897 }
3898 
3899 void QnstView::performZoomReset()
3900 {
3901  zoomStep = 0;
3902  resetMatrix();
3903 }
3904 
3905 void QnstView::performFullscreen()
3906 {
3907  // TODO
3908 }
3909 
3910 void QnstView::performBringfront()
3911 {
3912  // TODO
3913 }
3914 
3915 void QnstView::performBringforward()
3916 {
3917  // TODO
3918 }
3919 
3920 void QnstView::performSendback()
3921 {
3922  // TODO
3923 }
3924 
3925 void QnstView::performSendbackward()
3926 {
3927  // TODO
3928 }
3929 
3930 void QnstView::performHide()
3931 {
3932  // TODO
3933 }
3934 
3935 void QnstView::performProperties()
3936 {
3937  // TODO
3938 }
3939 
3940 void QnstView::mouseMoveEvent(QMouseEvent* event)
3941 {
3942  if (linking)
3943  {
3944  if (lastLinkMouseOver != NULL)
3945  {
3946  lastLinkMouseOver->setMouseHover(false);
3947  lastLinkMouseOver = NULL;
3948  }
3949 
3950  QList<QGraphicsItem *> itemsa = scene->items(link->getLine().p1());
3951 
3952  if (itemsa.count() && itemsa.first() == link)
3953  {
3954  itemsa.removeFirst();
3955  }
3956 
3957  if (itemsa.count())
3958  {
3959  QnstGraphicsEntity* entitya = (QnstGraphicsEntity*) itemsa.first();
3960  entitya->setMouseHover(true);
3961  }
3962 
3963  QList<QGraphicsItem*> itemsb = scene->items(link->getLine().p2());
3964 
3965  if (itemsb.count() && itemsb.first() == link)
3966  {
3967  itemsb.removeFirst();
3968  }
3969 
3970  if (itemsb.count())
3971  {
3972  QnstGraphicsEntity* entityb = (QnstGraphicsEntity*) itemsb.first();
3973  entityb->setMouseHover(true);
3974 
3975  lastLinkMouseOver = entityb;
3976  }
3977 
3978  link->setLine(QLineF(link->getLine().p1(), mapToScene(event->pos())));
3979  }
3980 
3981  QGraphicsView::mouseMoveEvent(event);
3982 }
3983 
3984 void QnstView::mousePressEvent(QMouseEvent* event)
3985 {
3986  if (modified)
3987  {
3988  if (link != NULL)
3989  {
3990  delete (link);
3991  link = NULL;
3992  }
3993 
3994  link = new QnstViewLink();
3995  scene->addItem(link);
3996  link->setLine(QLineF(mapToScene(event->pos()), mapToScene(event->pos())));
3997  link->adjust();
3998 
3999  linking = true;
4000  }
4001  else
4002  {
4003  QGraphicsView::mousePressEvent(event);
4004 
4005  if (!event->isAccepted())
4006  {
4007  if (event->button() == Qt::LeftButton)
4008  {
4009  if (selected != NULL)
4010  {
4011  selected->setSelected(false);
4012  selected->adjust();
4013  }
4014 
4015  selected = NULL;
4016  }
4017 
4018  event->accept();
4019  }
4020  }
4021 }
4022 
4023 void QnstView::mouseReleaseEvent(QMouseEvent* event)
4024 {
4025  if (linking)
4026  {
4027  QList<QGraphicsItem *> itemsa = scene->items(link->getLine().p1());
4028 
4029  if (itemsa.count() && itemsa.first() == link)
4030  itemsa.removeFirst();
4031 
4032  QList<QGraphicsItem*> itemsb = scene->items(link->getLine().p2());
4033 
4034  if (itemsb.count() && itemsb.first() == link)
4035  itemsb.removeFirst();
4036 
4037  if (itemsa.count() && itemsb.count())
4038  {
4039  QnstGraphicsEntity* entitya = (QnstGraphicsEntity*) itemsa.first();
4040  QnstGraphicsEntity* entityb = (QnstGraphicsEntity*) itemsb.first();
4041 
4042  if (entitya != entityb)
4043  {
4044  // if linking NODE to NODE
4045  if (entitya->getncgType() == Qncg::Node &&
4046  entityb->getncgType() == Qncg::Node)
4047  {
4048  addNodetoNodeEdge(entitya, entityb);
4049  }
4050  // if linking NODE to INTERFACE
4051  else if (entitya->getncgType() == Qncg::Node &&
4052  entityb->getncgType() == Qncg::Interface)
4053  {
4054  addNodetoInterfaceEdge(entitya, entityb);
4055  }
4056  // if linking INTERFACE to NODE
4057  else if (entitya->getncgType() == Qncg::Interface &&
4058  entityb->getncgType() == Qncg::Node)
4059  {
4060  addInterfacetoNodeEdge(entitya, entityb);
4061  }
4062  // if linking INTERFACE to INTERFACE
4063  else if (entitya->getncgType() == Qncg::Interface &&
4064  entityb->getncgType() == Qncg::Interface)
4065  {
4066  addInterfacetoInterfaceEdge(entitya, entityb);
4067  }
4068  }
4069 
4070  entitya->setMouseHover(false);
4071  entityb->setMouseHover(false);
4072  }
4073 
4074  if (link != NULL)
4075  {
4076  scene->removeItem(link);
4077  scene->update();
4078 
4079  delete link;
4080  link = NULL;
4081  }
4082 
4083  linking = false;
4084  }
4085 
4086  QnstGraphicsEntity *entity;
4087  foreach(entity, entities.values())
4088  {
4089  assert(entity != NULL);
4090  entity->setDraggable(false);
4091  }
4092 
4093  QGraphicsView::mouseReleaseEvent(event);
4094 }
4095 
4096 void QnstView::addNodetoNodeEdge(QnstGraphicsEntity* entitya,
4097  QnstGraphicsEntity* entityb)
4098 {
4099  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4100  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4101 
4102  if (parenta != NULL && parentb != NULL)
4103  {
4104  if (parenta == parentb)
4105  {
4106  // aggregator -> node
4107  if (entitya->getnstType() == Qnst::Link)
4108  {
4109  createActionWithDialog(entitya, entityb);
4110  }
4111  // node -> aggregator
4112  else if (entityb->getnstType() == Qnst::Link)
4113  {
4114  createConditionWithDialog(entitya, entityb);
4115  }
4116  // node -> node
4117  else
4118  {
4119  createLinkWithDialog(entitya, entityb);
4120  }
4121 
4122  modified = false;
4123  }
4124  }
4125 }
4126 
4127 void QnstView::addNodetoInterfaceEdge(QnstGraphicsEntity* entitya,
4128  QnstGraphicsEntity* entityb)
4129 {
4130  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4131  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4132 
4133  if (parenta != NULL && parentb != NULL)
4134  {
4135  if (parenta == parentb->getnstGraphicsParent())
4136  {
4137  // aggregator -> interface
4138  if (entitya->getnstType() == Qnst::Link)
4139  {
4140  createActionWithDialog(entitya, entityb);
4141  }
4142  // node -> interface
4143  else
4144  {
4145  createLinkWithDialog(entitya, entityb);
4146  }
4147 
4148  modified = false;
4149  }
4150  }
4151 }
4152 
4153 void QnstView::addInterfacetoNodeLink(QnstGraphicsEntity* entitya,
4154  QnstGraphicsEntity* entityb)
4155 {
4156  // interface -> aggreagator
4157  if (entityb->getnstType() == Qnst::Link)
4158  {
4159  createConditionWithDialog(entitya, entityb);
4160  }
4161  // interface -> node
4162  else
4163  {
4164  createLinkWithDialog(entitya, entityb);
4165  }
4166 }
4167 
4168 void QnstView::addInterfacetoNodeEdge(QnstGraphicsEntity* entitya,
4169  QnstGraphicsEntity* entityb)
4170 {
4171  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4172  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4173 
4174  if (parenta != NULL && parentb != NULL)
4175  {
4176  if (parenta == parentb)
4177  {
4178  if (entitya->getnstType() == Qnst::Port)
4179  {
4180  createReference(entitya, entityb);
4181  }
4182  else if (entitya->getnstType() == Qnst::SwitchPort)
4183  {
4184  createMapping(entitya, entityb);
4185  }
4186  }
4187  else if (parenta->getnstGraphicsParent() == parentb && parenta != entityb)
4188  {
4189  addInterfacetoNodeLink(entitya, entityb);
4190 
4191  modified = false;
4192  }
4193  }
4194 }
4195 
4196 void QnstView::addInterfacetoInterfaceEdge(QnstGraphicsEntity* entitya,
4197  QnstGraphicsEntity* entityb)
4198 {
4199  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4200  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4201 
4202  if (parenta != NULL && parentb != NULL)
4203  {
4204  if (parenta == parentb->getnstGraphicsParent())
4205  {
4206  if (entitya->getnstType() == Qnst::Port)
4207  {
4208  createReference(entitya, entityb);
4209  }
4210  else if (entitya->getnstType() == Qnst::SwitchPort)
4211  {
4212  createMapping(entitya, entityb);
4213  }
4214  }
4215  else if (parenta->getnstGraphicsParent() == parentb->getnstGraphicsParent())
4216  {
4217  createLinkWithDialog(entitya, entityb);
4218 
4219  modified = false;
4220  }
4221  }
4222 }
4223 
4224 QString QnstView::createNewConnector(QString condition, QString action)
4225 {
4226  QnstConnector* conn = new QnstConnector();
4227  conn->setName("newConnector"+QString::number(connectors.size()));
4228  conn->addCondition(QUuid::createUuid().toString(), "onBegin");
4229  conn->addCondition(QUuid::createUuid().toString(), "onEnd");
4230  conn->addCondition(QUuid::createUuid().toString(), "onSelection");
4231  conn->addCondition(QUuid::createUuid().toString(), "onResume");
4232  conn->addCondition(QUuid::createUuid().toString(), "onPause");
4233 
4234  conn->addAction(QUuid::createUuid().toString(), "start");
4235  conn->addAction(QUuid::createUuid().toString(), "stop");
4236  conn->addAction(QUuid::createUuid().toString(), "resume");
4237  conn->addAction(QUuid::createUuid().toString(), "pause");
4238  conn->addAction(QUuid::createUuid().toString(), "set");
4239 
4240  connectors[conn->getName()] = conn;
4241  connectors2[conn->getnstUid()] = conn;
4242 
4243  QMap<QString, QString> properties;
4244 
4245  properties["TYPE"] = "complex-connector";
4246 
4247  properties["id"] = conn->getName();
4248 
4249  if (!action.isEmpty())
4250  {
4251  properties["action"] = action;
4252 
4253  QString UID = conn->getActions().key(action, QUuid::createUuid().toString());
4254 
4255  properties["actionUID"] = UID;
4256  }
4257 
4258  if (!condition.isEmpty())
4259  {
4260  properties["condition"] = condition;
4261 
4262  QString UID = conn->getConditions().key(action, QUuid::createUuid().toString());
4263 
4264  properties["conditionUID"] = UID;
4265  }
4266 
4267  emit entityAdded(conn->getnstUid(), "", properties);
4268 
4269  return conn->getName();
4270 }
4271 
4272 QnstGraphicsLink* QnstView::createLink(QnstGraphicsEntity* entitya,
4273  QnstGraphicsEntity* entityb,
4274  QString connName)
4275 {
4276  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4277  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4278 
4279  if (parenta != NULL && parentb != NULL)
4280  {
4281  QnstGraphicsLink* linkDot = NULL;
4282 
4283  qreal xcenter = -1;
4284  qreal ycenter = -1;
4285 
4286  QPointF pointa(entitya->getLeft() + entitya->getWidth()/2,
4287  entitya->getTop() + entitya->getHeight()/2);
4288 
4289  QPointF pointb(entityb->getLeft() + entityb->getWidth()/2,
4290  entityb->getTop() + entityb->getHeight()/2);
4291 
4292  if(entitya->getncgType() == Qncg::Interface &&
4293  entityb->getncgType() == Qncg::Interface)
4294  {
4295  QnstGraphicsEntity* super = parenta->getnstGraphicsParent();
4296 
4297  linkDot = new QnstGraphicsLink((QnstGraphicsNode*) super);
4298  super->addnstGraphicsEntity(linkDot);
4299 
4300  pointa = super->mapFromItem(parenta, pointa);
4301  pointb = super->mapFromItem(parentb, pointb);
4302  }
4303  else if(entitya->getncgType() == Qncg::Node &&
4304  entityb->getncgType() == Qncg::Interface)
4305  {
4306  linkDot = new QnstGraphicsLink((QnstGraphicsNode*) parenta);
4307  parenta->addnstGraphicsEntity(linkDot);
4308 
4309  pointb = parenta->mapFromItem(parentb, pointb);
4310  }
4311  else if(entitya->getncgType() == Qncg::Interface &&
4312  entityb->getncgType() == Qncg::Node)
4313  {
4314  linkDot = new QnstGraphicsLink((QnstGraphicsNode*) parentb);
4315  parentb->addnstGraphicsEntity(linkDot);
4316 
4317  pointa = parentb->mapFromItem(parenta, pointa);
4318 
4319  }
4320  else
4321  {
4322  linkDot = new QnstGraphicsLink((QnstGraphicsNode*) parenta);
4323  parenta ->addnstGraphicsEntity(linkDot);
4324  }
4325 
4326  QLineF l(pointa, pointb);
4327 
4328  if (pointa.x() <= pointb.x() && pointa.y() <= pointb.y())
4329  {
4330  qreal angle = (l.angle() - 270);
4331  qreal rangle = angle*PI/180;
4332 
4333  if (angle > 45)
4334  {
4335  pointa.setX(pointa.x() + entitya->getWidth()/2);
4336  pointa.setY(pointa.y() + ((entitya->getWidth()/2)/tan(rangle)));
4337 
4338  pointb.setX(pointb.x() - entityb->getWidth()/2);
4339  pointb.setY(pointb. y() - ((entityb->getWidth()/2)/tan(rangle)));
4340  }
4341  else
4342  {
4343  pointa.setX(pointa.x() + ((entitya->getHeight()/2)*tan(rangle)));
4344  pointa.setY(pointa.y() + entitya->getHeight()/2);
4345 
4346  pointb.setX(pointb.x() - ((entityb->getHeight()/2)*tan(rangle)));
4347  pointb.setY(pointb.y() - entityb->getHeight()/2);
4348  }
4349 
4350  xcenter = pointa.x() + (pointb.x() - pointa.x())/2;
4351  ycenter = pointa.y() + (pointb.y() - pointa.y())/2;
4352  }
4353  else if (pointa.x() > pointb.x() && pointa.y() < pointb.y())
4354  {
4355  qreal angle = (270 - l.angle());
4356  qreal rangle = angle*PI/180;
4357 
4358  if (angle > 45)
4359  {
4360  pointa.setX(pointa.x() - entitya->getWidth()/2);
4361  pointa.setY(pointa.y() + ((entitya->getWidth()/2)/tan(rangle)));
4362 
4363  pointb.setX(pointb.x() + entityb->getWidth()/2);
4364  pointb.setY(pointb.y() - ((entityb->getWidth()/2)/tan(rangle)));
4365  }
4366  else
4367  {
4368  pointa.setX(pointa.x() - ((entitya->getHeight()/2)*tan(rangle)));
4369  pointa.setY(pointa.y() + entitya->getHeight()/2);
4370 
4371  pointb.setX(pointb.x() + ((entityb->getHeight()/2)*tan(rangle)));
4372  pointb.setY(pointb.y() - entityb->getHeight()/2);
4373  }
4374 
4375  xcenter = pointb.x() + (pointa.x() - pointb.x())/2;
4376  ycenter = pointa.y() + (pointb.y() - pointa.y())/2;
4377  }
4378  else if (pointa.x() < pointb.x() && pointa.y() > pointb.y())
4379  {
4380  qreal angle = l.angle();
4381  qreal rangle = angle*PI/180;
4382 
4383  if (angle < 45)
4384  {
4385  pointa.setX(pointa.x() + entitya->getWidth()/2);
4386  pointa.setY(pointa.y() - ((entitya->getWidth()/2)*tan(rangle)));
4387 
4388  pointb.setX(pointb.x() - entityb->getWidth()/2);
4389  pointb.setY(pointb.y() + ((entityb->getWidth()/2)*tan(rangle)));
4390  }
4391  else
4392  {
4393  pointa.setX(pointa.x() + ((entitya->getHeight()/2)/tan(rangle)));
4394  pointa.setY(pointa.y() - entitya->getHeight()/2);
4395 
4396  pointb.setX(pointb.x() - ((entityb->getHeight()/2)/tan(rangle)));
4397  pointb.setY(pointb.y() + entityb->getHeight()/2);
4398  }
4399 
4400  xcenter = pointa.x() + (pointb.x() - pointa.x())/2;
4401  ycenter = pointb.y() + (pointa.y() - pointb.y())/2;
4402  }
4403  else if (pointa.x() > pointb.x() && pointa.y() > pointb.y())
4404  {
4405  qreal angle = l.angle() - 90;
4406  qreal rangle = angle*PI/180;
4407 
4408  if (angle > 45)
4409  {
4410  pointa.setX(pointa.x() - entitya->getWidth()/2);
4411  pointa.setY(pointa.y() - ((entitya->getWidth()/2)/tan(rangle)));
4412 
4413  pointb.setX(pointb.x() + entityb->getWidth()/2);
4414  pointb.setY(pointb.y() + ((entityb->getWidth()/2)/tan(rangle)));
4415  }
4416  else
4417  {
4418  pointa.setX(pointa.x() - ((entitya->getHeight()/2)*tan(rangle)));
4419  pointa.setY(pointa.y() - entitya->getHeight()/2);
4420 
4421  pointb.setX(pointb.x() + ((entityb->getHeight()/2)*tan(rangle)));
4422  pointb.setY(pointb.y() + entityb->getHeight()/2);
4423  }
4424 
4425  xcenter = pointb.x() + (pointa.x() - pointb.x())/2;
4426  ycenter = pointb.y() + (pointa.y() - pointb.y())/2;
4427  }
4428 
4429  linkDot->setTop(ycenter - DEFAULT_AGGREGATOR_HEIGHT/2);
4430  linkDot->setLeft(xcenter - DEFAULT_AGGREGATOR_WIDTH/2);
4431  linkDot->setWidth(DEFAULT_AGGREGATOR_WIDTH);
4432  linkDot->setHeight(DEFAULT_AGGREGATOR_HEIGHT);
4433  linkDot->adjust();
4434 
4435  updateEntityWithUniqueNstId(linkDot); // set a unique Id
4436 
4437  linkDot->setxConnector(connName);
4438  if(connectors.contains(connName))
4439  linkDot->setxConnectorUID(connectors[connName]->getnstUid());
4440 
4441  requestEntityAddition(linkDot);
4442 
4443  return linkDot;
4444  }
4445 
4446  return NULL;
4447 }
4448 
4449 void QnstView::createReference(QnstGraphicsEntity* entitya,
4450  QnstGraphicsEntity* entityb)
4451 {
4452  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4453  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4454 
4455  if (parenta != NULL && parentb != NULL)
4456  {
4457  // removing previous reference
4458  foreach(QnstGraphicsEntity* entity, parenta->getnstGraphicsEntities())
4459  {
4460  if (entity->getnstType() == Qnst::Reference)
4461  {
4462  QnstGraphicsEdge* edge = (QnstGraphicsEdge*) entity;
4463 
4464  if (entitya == edge->getEntityA()){
4465  if (edge->getEntityA()->getncgType() == Qncg::Node)
4466  {
4467  ((QnstGraphicsNode*) edge->getEntityA())->removenstGraphicsEdge(edge);
4468  }
4469  else if (edge->getEntityA()->getncgType() == Qncg::Interface)
4470  {
4471  ((QnstGraphicsInterface*) edge->getEntityA())->removenstGraphicsEdge(edge);
4472  }
4473 
4474  if (edge->getEntityB()->getncgType() == Qncg::Node)
4475  {
4476  ((QnstGraphicsNode*) edge->getEntityB())->removenstGraphicsEdge(edge);
4477 
4478  }
4479  else if (edge->getEntityB()->getncgType() == Qncg::Interface)
4480  {
4481  ((QnstGraphicsInterface*) edge->getEntityB())->removenstGraphicsEdge(edge);
4482  }
4483 
4484  parenta->removenstGraphicsEntity(edge); delete (edge);
4485 
4486  break;
4487  }
4488  }
4489  }
4490 
4492  entity->setEntityA(entitya);
4493  entity->setEntityB(entityb);
4494  entity->adjust();
4495 
4496  parenta->addnstGraphicsEntity(entity);
4497 
4498  ((QnstGraphicsInterface*) entitya)->addnstGraphicsEdge(entity);
4499 
4500  if (entityb->getncgType() == Qncg::Node)
4501  ((QnstGraphicsNode*) entityb)->addnstGraphicsEdge(entity);
4502  else if (entityb->getncgType() == Qncg::Interface)
4503  ((QnstGraphicsInterface*) entityb)->addnstGraphicsEdge(entity);
4504 
4505  requestEntityChange(entitya);
4506  }
4507 }
4508 
4509 void QnstView::createMapping(QnstGraphicsEntity* entitya,
4510  QnstGraphicsEntity* entityb)
4511 {
4512  QnstGraphicsEntity* parenta = entitya->getnstGraphicsParent();
4513  QnstGraphicsEntity* parentb = entityb->getnstGraphicsParent();
4514 
4515  if (parenta != NULL && parentb != NULL)
4516  {
4517 
4518  QMap<QString, QString> properties;
4519 
4520  properties["TYPE"] = "mapping";
4521 
4522  QnstGraphicsMapping* entity = new QnstGraphicsMapping();
4523  entity->setEntityA(entitya);
4524  entity->setEntityB(entityb);
4525 
4526  ((QnstGraphicsInterface*) entitya)->addnstGraphicsEdge(entity);
4527 
4528  if (entityb->getncgType() == Qncg::Node)
4529  {
4530  properties["component"] = entityb->getnstId();
4531  properties["componentUID"] = entityb->getnstUid();
4532 
4533  entity->setComponent(properties["component"]);
4534  entity->setComponentUid(properties["componentUID"]);
4535 
4536  ((QnstGraphicsNode*) entityb)->addnstGraphicsEdge(entity);
4537  }
4538  else if (entityb->getncgType() == Qncg::Interface)
4539  {
4540  properties["component"] = parentb->getnstId();
4541  properties["componentUID"] = parentb->getnstUid();
4542  properties["interface"] = entityb->getnstId();
4543  properties["interfaceUID"] = entityb->getnstUid();
4544 
4545 
4546  entity->setComponent(properties["component"]);
4547  entity->setComponentUid(properties["componentUID"]);
4548  entity->setInterface(properties["interface"]);
4549  entity->setInterfaceUid(properties["interfaceUID"]);
4550 
4551  ((QnstGraphicsInterface*) entityb)->addnstGraphicsEdge(entity);
4552  }
4553 
4554  parenta->addnstGraphicsEntity(entity);
4555 
4556  entity->adjust();
4557 
4558  entity->setSwitchPortUid(entitya->getnstUid());
4559 
4560  entities[entity->getnstUid()] = entity;
4561 
4562  // parent is the strucUID from the switchPort entity in this case
4563  emit entityAdded(entity->getnstUid(), entitya->getnstUid(), properties);
4564  }
4565 }
4566 
4567 void QnstView::createActionWithDialog(QnstGraphicsEntity* entitya,
4568  QnstGraphicsEntity* entityb)
4569 {
4570  actionDialog->init(connectors, links[entitya->getnstUid()]);
4571 
4572  if (actionDialog->exec())
4573  {
4574  QString link = actionDialog->form.cbLink->currentText();
4575  QString act = actionDialog->form.cbAction->currentText();
4576 
4577  // creating connector
4578  QString connName;
4579 
4580  if (actionDialog->form.cbConnector->currentText() == "New...")
4581  connName = createNewConnector("", act);
4582  else
4583  connName = actionDialog->form.cbConnector->currentText();
4584 
4585  // creating link
4586  if (link == "New...")
4587  {
4588  createLink(entitya, entityb, connName);
4589  }
4590  else
4591  {
4592  QnstGraphicsLink* link = links[entitya->getnstUid()];
4593 
4594  // creating action bind
4595  QnstGraphicsBind* bind = createBind(link,
4596  entityb,
4597  "",
4598  act);
4599 
4600  // associating connector to bind
4601  if(connectors.contains(connName))
4602  bind->setConn(connectors[connName]);
4603 
4604  link->addAction(bind);
4605  }
4606  }
4607 }
4608 
4609 void QnstView::createConditionWithDialog(QnstGraphicsEntity* entitya,
4610  QnstGraphicsEntity* entityb)
4611 {
4612  conditionDialog->init(connectors, links[entityb->getnstUid()]);
4613 
4614  if (conditionDialog->exec())
4615  {
4616  QString link = conditionDialog->form.cbLink->currentText();
4617  QString cond = conditionDialog->form.cbCondition->currentText();
4618 
4619  // creating connector
4620  QString connName;
4621 
4622  if (conditionDialog->form.cbConnector->currentText() == "New...")
4623  connName = createNewConnector(cond, "");
4624  else
4625  connName = conditionDialog->form.cbConnector->currentText();
4626 
4627  // creating link
4628  if (link == "New...")
4629  {
4630  createLink(entitya, entityb, connName);
4631  }
4632  else
4633  {
4634  QnstGraphicsLink* link = links[entityb->getnstUid()];
4635  // creating condition bind
4636  QnstGraphicsBind* bind = createBind(link,
4637  entitya,
4638  cond,
4639  "");
4640 
4641  // associating connector to bind
4642  if(connectors.contains(connName))
4643  bind->setConn(connectors[connName]);
4644 
4645  link->addCondition(bind);
4646  }
4647  }
4648 }
4649 
4650 void QnstView::createLinkWithDialog(QnstGraphicsEntity* entitya,
4651  QnstGraphicsEntity* entityb)
4652 {
4653  linkDialog->init(connectors);
4654 
4655  if (linkDialog->exec())
4656  {
4657  QString con = linkDialog->form.cbCondition->currentText();
4658  QString act = linkDialog->form.cbAction->currentText();
4659 
4660  if (con != "" && act != "")
4661  {
4662  // creating connector
4663  QString connName;
4664 
4665  if (linkDialog->getCurrentConnector() == "New...")
4666  connName = createNewConnector(con, act);
4667  else
4668  connName = linkDialog->getCurrentConnector();
4669 
4670  // creating aggregator
4671  QnstGraphicsLink* link = createLink(entitya, entityb, connName);
4672 
4673  // creating condition bind
4674  QnstGraphicsBind* condition = createBind(link,
4675  entitya,
4676  con,
4677  "");
4678  // creating action bind
4679  QnstGraphicsBind* action = createBind(link,
4680  entityb,
4681  "",
4682  act);
4683 
4684  // associating connector to bind
4685  if(connectors.contains(connName))
4686  {
4687  action->setConn(connectors[connName]);
4688  condition->setConn(connectors[connName]);
4689  }
4690 
4691  link->addAction(action);
4692  link->addCondition(condition);
4693  }
4694  }
4695 }
4696 
4697 QnstGraphicsBind* QnstView::createBind(QnstGraphicsLink* link,
4698  QnstGraphicsEntity* target,
4699  QString condition,
4700  QString action,
4701  bool notifyCreation)
4702 {
4703  QnstGraphicsEntity* parent = link->getnstGraphicsParent();
4704 
4705  QnstGraphicsBind* bind = new QnstGraphicsBind(); // \fixme Use makeGraphics
4706  bind->setLink(link);
4707  bind->setTarget(target);
4708 
4709  parent->addnstGraphicsEntity(bind);
4710 
4711  // setting type and component/interface
4712  if (!condition.isEmpty())
4713  {
4714  bind->setRole(condition);
4715  bind->setType(QnstUtil::getBindTypeFromStr(condition));
4716  }
4717  else
4718  {
4719  bind->setRole(action);
4720  bind->setType(QnstUtil::getBindTypeFromStr(action));
4721  }
4722 
4723  link->addnstGraphicsEdge(bind);
4724 
4725  if(target != NULL)
4726  {
4727  if(target->getncgType() == Qncg::Node)
4728  {
4729  bind->setComponent(target->getnstId());
4730  bind->setComponentUid(target->getnstUid());
4731  }
4732  else if(target->getncgType() == Qncg::Interface)
4733  {
4734  QnstGraphicsEntity* targetParent = target->getnstGraphicsParent();
4735 
4736  bind->setComponent(targetParent->getnstId());
4737  bind->setComponentUid(targetParent->getnstUid());
4738  bind->setInterface(target->getnstId());
4739  bind->setInterfaceUid(target->getnstUid());
4740  }
4741 
4742  ((QnstGraphicsEntityWithEdges*)target)->addnstGraphicsEdge(bind);
4743  }
4744 
4745  connect(bind,
4746  SIGNAL(bindParamAdded(QString,
4747  QString,
4748  QMap<QString, QString>)),
4749 
4750  SLOT(requestBindParamAdjust(QString,
4751  QString,
4752  QMap<QString, QString>)));
4753 
4754  connect(bind,
4755  SIGNAL(bindParamUpdated(QString,
4756  QMap<QString,QString>,
4757  QMap<QString,QString>)),
4758 
4759  SLOT(updateBindParams(QString,
4760  QMap<QString,QString>,
4761  QMap<QString,QString>)));
4762 
4763  if(notifyCreation)
4764  requestEntityAddition(bind);
4765 
4766  adjustBind(bind);
4767 
4768  return bind;
4769 }
4770 
4771 void QnstView::keyPressEvent(QKeyEvent *event)
4772 {
4773  // CTRL+X - Cut
4774  if (event->modifiers() == Qt::ControlModifier && event->key() == Qt::Key_X)
4775  {
4776  performCut();
4777 
4778  event->accept();
4779  }
4780  // CTRL+C - Copy
4781  else if (event->modifiers() == Qt::ControlModifier &&
4782  event->key() == Qt::Key_C)
4783  {
4784  performCopy();
4785 
4786  event->accept();
4787  }
4788  // CTRL+V - Paste
4789  else if (event->modifiers() == Qt::ControlModifier &&
4790  event->key() == Qt::Key_V)
4791  {
4792  performPaste();
4793 
4794  event->accept();
4795  }
4796  // DELETE - Delete
4797  else if (event->key() == Qt::Key_Delete)
4798  {
4799  performDelete();
4800 
4801  event->accept();
4802  }
4803  // BACKSPACE - Delete
4804  else if (event->key() == Qt::Key_Backspace)
4805  {
4806  performDelete();
4807 
4808  event->accept();
4809  }
4810  // SHIFT - Enabling liking
4811  else if (event->key() == Qt::Key_Shift)
4812  {
4813  if (selected != NULL)
4814  {
4815  selected->setSelected(false);
4816  selected->adjust();
4817  }
4818 
4819  selected = NULL;
4820  modified = true;
4821 
4822  event->accept();
4823  }
4824  else if(event->key() == Qt::Key_Control)
4825  {
4826 // modified = true;
4827  QnstGraphicsEntity *entity;
4828  foreach(entity, entities.values())
4829  {
4830  entity->setDraggable(true);
4831  }
4832 
4833  event->accept();
4834  }
4835  //Ctrl + 0 -> reset to default zoom
4836  else if( event->modifiers() == Qt::ControlModifier &&
4837  event->key() == Qt::Key_0)
4838  {
4839  performZoomReset();
4840  }
4841  //Ctrl + + -> perform zoom in
4842  else if((event->modifiers() == Qt::ControlModifier ||
4843  event->modifiers() == (Qt::ShiftModifier | Qt::ControlModifier)) &&
4844  event->key() == Qt::Key_Plus)
4845  {
4846  performZoomIn();
4847 
4848  event->accept();
4849  }
4850  //Ctrl + - -> perform zoom out
4851  else if(event->modifiers() == Qt::ControlModifier &&
4852  event->key() == Qt::Key_Minus)
4853  {
4854  performZoomOut();
4855 
4856  event->accept();
4857  }
4858  //Ctrl + Z
4859  /* else if(event->modifiers() == Qt::ControlModifier &&
4860  event->key() == Qt::Key_Z)
4861  {
4862  performUndo();
4863 
4864  event->accept();
4865  }
4866  //Ctrl + Y
4867  else if(event->modifiers() == Qt::ControlModifier &&
4868  event->key() == Qt::Key_Y)
4869  {
4870  performRedo();
4871 
4872  event->accept();
4873  }*/
4874 
4875  if(!event->isAccepted())
4876  QGraphicsView::keyPressEvent(event);
4877 }
4878 
4879 void QnstView::keyReleaseEvent(QKeyEvent *event)
4880 {
4881  // SHIFT - Disabling linking
4882  if (event->key() == Qt::Key_Shift)
4883  {
4884  modified = false;
4885  }
4886  else if(event->key() == Qt::Key_Control)
4887  {
4888  QnstGraphicsEntity *entity;
4889  foreach(entity, entities.values())
4890  {
4891  entity->setDraggable(false);
4892  }
4893  }
4894 
4895  QGraphicsView::keyReleaseEvent(event);
4896 }
4897 
4898 void QnstView::wheelEvent(QWheelEvent * event)
4899 {
4900  if(event->modifiers() == Qt::ControlModifier)
4901  {
4902 #ifdef SMOOTH_ZOOM
4903  int numDegrees = event->delta() / 8;
4904  int numSteps = numDegrees / 15; // see QWheelEvent documentation
4905  _numScheduledScalings += numSteps;
4906  if (_numScheduledScalings * numSteps < 0) // if user moved the wheel in another direction, we reset previously scheduled scalings
4907  _numScheduledScalings = numSteps;
4908 
4909  QTimeLine *anim = new QTimeLine(350, this);
4910  anim->setUpdateInterval(20);
4911 
4912  connect(anim, SIGNAL(valueChanged(qreal)), SLOT(scalingTime(qreal)));
4913  connect(anim, SIGNAL(finished()), SLOT(animFinished()));
4914  anim->start();
4915  #else
4916  if (event->delta() > 0)
4917  performZoomIn();
4918  else
4919  performZoomOut();
4920  #endif
4921 
4922  event->accept();
4923  }
4924  else
4925  {
4926  // call the parent wheelEvent
4927  QGraphicsView::wheelEvent(event);
4928  }
4929 }
4930 #ifdef SMOOTH_ZOOM
4931 void QnstView::scalingTime(qreal x)
4932 {
4933  qreal factor = 1.0 + qreal(_numScheduledScalings) / 500.0;
4934  scale(factor, factor);
4935 }
4936 
4937 void QnstView::animFinished()
4938 {
4939  if (_numScheduledScalings > 0)
4940  _numScheduledScalings--;
4941  else
4942  _numScheduledScalings++;
4943  sender()->~QObject();
4944 }
4945 #endif
4946 
4947 void QnstView::focusOutEvent(QFocusEvent *event)
4948 {
4949  QnstGraphicsEntity *entity;
4950  foreach(entity, entities.values())
4951  {
4952  entity->setDraggable(false);
4953  }
4954 }
4955 
4956 void QnstView::adjustAngles(QnstGraphicsEdge* edge)
4957 {
4958  QnstGraphicsEntityWithEdges *entitya = (QnstGraphicsEntityWithEdges*)edge->getEntityA();
4959  QnstGraphicsEntityWithEdges *entityb = (QnstGraphicsEntityWithEdges*)edge->getEntityB();
4960 
4961  if(entitya == NULL || entityb == NULL) return; // do nothing
4962 
4963  int angle = 0;
4964  bool par = false;
4965  foreach (QnstGraphicsEdge *edge, entitya->getnstGraphicsEdges())
4966  {
4967  if(edge->getEntityB() == entityb)
4968  {
4969  if(par)
4970  {
4971  edge->setAngle(angle);
4972  par = false;
4973  }
4974  else
4975  {
4976  edge->setAngle(-angle);
4977  angle += 60;
4978  par = true;
4979  }
4980 
4981  edge->adjust();
4982  }
4983  }
4984 }
4985 
4986 void QnstView::requestBindParamAdjust(QString uid, QString parent,
4987  QMap<QString, QString> properties)
4988 {
4989  properties["TYPE"] = "bindParam";
4990 
4991  if (!properties["name"].isEmpty() && !properties["value"].isEmpty())
4992  {
4993  if (bindParamUIDToBindUID.contains(uid))
4994  {
4995  emit entityChanged(uid, properties);
4996  }
4997  else
4998  {
4999  bindParamUIDToBindUID[uid] = parent;
5000  emit entityAdded(uid, parent, properties );
5001  }
5002  }
5003  else if (!properties["name"].isEmpty())
5004  {
5005  bindParamUIDToBindUID.remove(uid);
5006 
5007  emit entityRemoved(uid);
5008  }
5009 }
5010 
5011 void QnstView::updateBindParams(QString bindUID, QMap<QString, QString> params,
5012  QMap<QString, QString> name_uids)
5013 {
5014  if (binds.contains(bindUID))
5015  {
5016  binds[bindUID]->setParams(params);
5017  binds[bindUID]->setNamesUIDs(name_uids);
5018  }
5019 }
5020 
5021 void QnstView::markError(QString uid, QString msg)
5022 {
5023  QnstGraphicsEntity *entity = NULL;
5024 
5025  if(entities.contains(uid))
5026  {
5027  entity = entities[uid];
5028  }else if (binds.contains(uid)){
5029  entity = (QnstGraphicsEntity*) binds[uid];
5030  }
5031 
5032  if (entity != NULL)
5033  {
5034  entity->setError(true);
5035  entity->setErrorMsg(msg);
5036  entity->updateToolTip();
5037  }
5038 }
5039 
5040 void QnstView::clearValidationErrors()
5041 {
5042  foreach(QnstGraphicsEntity *entity, entities.values())
5043  {
5044  assert(entity != NULL);
5045  entity->setError(false);
5046  }
5047 
5048  foreach(QnstGraphicsBind *bind, binds.values())
5049  {
5050  assert(bind != NULL);
5051  bind->setError(false);
5052  }
5053 }
5054 
5055 void QnstView::clearAllData()
5056 {
5057  if(scene->getRoots().size())
5058  scene->removeRoot(scene->getRoots().at(0));
5059 
5060  entities.clear();
5061  links.clear();
5062 
5063  refers.clear();
5064  importBases.clear();
5065 
5066  bindParamUIDToBindUID.clear();
5067 
5068  connectors.clear();
5069  connectors2.clear();
5070 
5071  deletePendingEntities();
5072 }
5073 
5074 void QnstView::traceRefers()
5075 {
5076  qDebug() << "#### TRACING REFER ####";
5077  foreach(QString key, refers.keys())
5078  {
5079  assert(refers[key] != NULL);
5080  if(entities.contains(key))
5081  qDebug() << key << refers[key];
5082  else
5083  qDebug() << "WARNING! This entity " + key + " is inside refer, but not in the entities map.";
5084  }
5085  qDebug() << "#### END TRACING REFER ####" << endl;
5086 }
5087 
5088 void QnstView::traceEntities()
5089 {
5090  qDebug() << "#### TRACING ENTITIES ####";
5091  foreach(QString key, entities.keys())
5092  {
5093  assert(entities[key] != NULL);
5094  assert(entities[key] != entities[key]->getnstGraphicsParent());
5095 
5096  qDebug() << key
5097  << QString().sprintf("%p", entities.value(key))
5098  << entities[key]->getnstType()
5099  << QnstUtil::getStrFromNstType(entities[key]->getnstType());
5100 
5101  if(entities[key]->getnstGraphicsParent())
5102  qDebug()<< QnstUtil::getStrFromNstType(entities[key]->getnstGraphicsParent()->getnstType());
5103 
5104  foreach(QnstGraphicsEntity * e, entities[key]->getnstGraphicsEntities())
5105  {
5106  qDebug() << "\t"
5107  << QString().sprintf("%p", e)
5108  << e->getnstType()
5109  << QnstUtil::getStrFromNstType(e->getnstType());
5110  }
5111  }
5112  qDebug() << "#### END TRACING ENTITIES ####" << endl;
5113 }
5114 
5115 void QnstView::traceConnectors()
5116 {
5117  qDebug() << "#### TRACING CONNECTORS ####";
5118  foreach(QString key, connectors.keys())
5119  {
5120  assert(connectors[key] != NULL);
5121 
5122 #ifdef Q_WS_MAC
5123  qDebug() << key << connectors[key] << connectors[key]->getConditions() << connectors[key]->getActions();
5124 #else
5125  qDebug() << key << (int)connectors[key] << connectors[key]->getConditions() << connectors[key]->getActions();
5126 #endif
5127  }
5128  qDebug() << "#### END TRACING CONNECTORS ####" << endl;
5129 }
5130 
5131 void QnstView::traceConnectors2()
5132 {
5133  qDebug() << "#### TRACING CONNECTORS2 ####";
5134  foreach(QString key, connectors2.keys())
5135  {
5136  assert(connectors2[key] != NULL);
5137 
5138 #ifdef Q_WS_MAC
5139  qDebug() << key << connectors2[key] << connectors2[key]->getConditions() << connectors2[key]->getActions();
5140 #else
5141  qDebug() << key << (int)connectors2[key] << connectors2[key]->getConditions() << connectors2[key]->getActions();
5142 #endif
5143  }
5144  qDebug() << "#### END TRACING CONNECTORS2 ####" << endl;
5145 }
5146 
5147 void QnstView::deletePendingEntities()
5148 {
5149  foreach(QnstGraphicsEntity* e, toDelete)
5150  {
5151  e->deleteLater();
5152  }
5153 
5154  toDelete.clear();
5155 }
5156 
5157 QnstConnector* QnstView::getConnectorByRoleUid(QString uid)
5158 {
5159  QnstConnector* conn = NULL;
5160 
5161  foreach(QnstConnector* c, connectors.values())
5162  {
5163  if (c->hasCondition(uid) || c->hasAction(uid))
5164  {
5165  conn = c;
5166  }
5167  }
5168 
5169  return conn;
5170 }