NCL Composer  0.1.5
 All Classes Functions Variables Pages
qnstcomposerplugin.cpp
1 /*
2  * Copyright 2011 TeleMidia/PUC-Rio.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see
16  * <http://www.gnu.org/licenses/>.
17  */
18 #include "qnstcomposerplugin.h"
19 
20 //
21 // ATTENTION: This code needs a refactoring.
22 //
23 
24 QnstComposerPlugin::QnstComposerPlugin(QObject* parent)
25 {
26  setParent(parent);
27 
28  createWidgets();
29  createConnections();
30 
31  n = 0;
32 
33  request = "";
34 
35  isSyncingFromTextual = false;
36 }
37 
38 QnstComposerPlugin::~QnstComposerPlugin()
39 {
40  delete(view);
41 }
42 
43 void QnstComposerPlugin::createWidgets()
44 {
45  view = new QnstView();
46 }
47 
48 void QnstComposerPlugin::createConnections()
49 {
50  connect(view, SIGNAL(entityAdded(QString,QString,QMap<QString,QString>)),
51  SLOT(notifyEntityAddedInView(QString,QString,QMap<QString,QString>)));
52 
53  connect(view, SIGNAL(entityRemoved(QString)),
54  SLOT(notifyEntityDeletedInView(QString)));
55 
56  connect(view, SIGNAL(entityChanged(QString,QMap<QString,QString>)),
57  SLOT(notifyEntityChangedInView(QString,QMap<QString,QString>)));
58 
59  connect(view, SIGNAL(entitySelected(QString)),
60  SLOT(requestEntitySelection(QString)));
61 
62  connect(view, SIGNAL(viewChanged()), SIGNAL(setCurrentProjectAsDirty()));
63 }
64 
66 {
67  QString data = project->getPluginData("br.puc-rio.telemidia.qnst");
68 
69  QString startEntitiesSep = "~~VIEW-DATA~~";
70  QString endEntitiesSep = "~~PLUGIN-DATA~~";
71 
72  int indexOfStartEntities = data.indexOf(startEntitiesSep);
73  int indexOfEndEntities = data.indexOf(endEntitiesSep);
74 
75  int indexOfStartEntitiesContent = indexOfStartEntities + startEntitiesSep.length();
76 
77 
78  QString mid = data.mid(indexOfStartEntitiesContent,
79  indexOfEndEntities - indexOfStartEntitiesContent);
80 
81  view->load(mid);
82 
83  startEntitiesSep = "~~PLUGIN-DATA~~";
84  endEntitiesSep = "$END_ENTITIES_LINES$";
85 
86  indexOfStartEntities = data.indexOf(startEntitiesSep);
87  indexOfEndEntities = data.indexOf(endEntitiesSep);
88 
89  indexOfStartEntitiesContent = indexOfStartEntities + startEntitiesSep.length();
90 
91 
92  mid = data.mid(indexOfStartEntitiesContent,
93  indexOfEndEntities - indexOfStartEntitiesContent);
94 
95  int lastp = 0;
96  int nextp = mid.indexOf("~");
97 
98  while(nextp > 0)
99  {
100  QString entitypair = mid.mid(lastp, nextp - lastp);
101 
102  QStringList list = entitypair.split("=");
103 
104  QString coreID = list[0], structuralID = list[1];
105 
106  entities[coreID] = structuralID;
107 
108  //Update user data
109  if(view->hasEntity(structuralID))
110  {
111  QnstEntity* nstEntity =
112  view->getEntity(structuralID);
113 
114  if(nstEntity != NULL)
115  {
116  QMap <QString, QString>::iterator begin, end, it;
117  QMap <QString, QString> userData;
118 
119  Entity *entity = project->getEntityById(coreID);
120  // if(entity != NULL)
121  //{
122  // entity->getAttributeIterator(begin, end);
123 
124  // for (it = begin; it != end; ++it)
125  // userData[it.key()] = it.value();
126 
127  // nstEntity->setUsrData(userData);
128  // }
129  }
130  }
131 
132  lastp = nextp+1;
133  nextp = mid.indexOf("~", nextp+1);
134  }
135 }
136 
138 {
139  return view;
140 }
141 
143 {
144  QByteArray data;
145 
146  data.append("$START_ENTITIES_LINES$");
147 
148  data.append("~~VIEW-DATA~~");
149  data.append(view->serialize());
150 
151  data.append("~~PLUGIN-DATA~~");
152  foreach(QString key, entities.keys()){
153  data.append(key+"="+entities[key]+"~");
154  }
155 
156  data.append("$END_ENTITIES_LINES$");
157 
158  emit setPluginData(data);
159 
160  return true;
161 }
162 
163 void QnstComposerPlugin::updateFromModel()
164 {
165  QMap <QString, int> top, left, width, height;
166 
167  //save previous positions
168  foreach (QString key, entities.keys())
169  {
170  QnstGraphicsEntity *entity =
171  dynamic_cast <QnstGraphicsEntity*>(view->getEntity(entities.value(key)));
172 
173  if(entity &&
174  entity->getnstId() != "")
175  {
176  top[entity->getnstId()] = entity->getTop();
177  left[entity->getnstId()]= entity->getLeft();
178  height[entity->getnstId()] = entity->getHeight();
179  width[entity->getnstId()] = entity->getWidth();
180  }
181  }
182 
183  foreach(QString coreID, entities.keys())
184  {
185  Entity *entity = project->getEntityById(coreID);
186  if(entity != NULL)
187  {
188  requestEntityRemotion(entity);
189  }
190  }
191  entities.clear();
192 
193  view->clearAllData();
194 
195  QStack <Entity *> stack;
196  stack.push(project);
197 
198  while(stack.size())
199  {
200  Entity *current = stack.top();
201  stack.pop();
202 
203  QVector <Entity *> children = current->getChildren();
204  for(int i = 0; i <children.size(); i++)
205  {
206  requestEntityAddition(children[i]);
207  stack.push(children[i]);
208  }
209  }
210 
211  // \fixme This second step is to ensure that all binds will be correctly drawn
212  // it should not be necessary if we fix the order we do the insertions!!
213  stack.push(project);
214  while(stack.size())
215  {
216  Entity *current = stack.top();
217  stack.pop();
218 
219  QVector <Entity *> children = current->getChildren();
220  for(int i = 0; i <children.size(); i++)
221  {
222  requestEntityChange(children[i]);
223  stack.push(children[i]);
224  }
225  }
226 
227  // Set saved positions!!
228  foreach (QString key, entities.keys())
229  {
230  QnstGraphicsEntity *entity =
231  dynamic_cast <QnstGraphicsEntity*>(view->getEntity(entities.value(key)));
232  if(entity && entity->getnstId() != "" && top.contains(entity->getnstId()))
233  {
234  entity->setTop(top[entity->getnstId()]);
235  entity->setLeft(left[entity->getnstId()]);
236  entity->setWidth(width[entity->getnstId()]);
237  entity->setHeight(height[entity->getnstId()]);
238  }
239  }
240 
241  view->adjustAll();
242 }
243 
244 void QnstComposerPlugin::onEntityAdded(QString pluginID, Entity *entity)
245 {
246  if(isSyncingFromTextual) return;
247 
248  if (pluginID != getPluginInstanceID()){
249  requestEntityAddition(entity);
250  }
251  else
252  {
253  if (request != "")
254  {
255  entities[entity->getUniqueId()] = request;
256  }
257  }
258 
259  //Add user data
260  /*if(entities.contains(entity->getUniqueId()))
261  {
262  QString structuralId = entities.value(entity->getUniqueId());
263 
264  if(view->hasEntity(structuralId))
265  {
266  QnstEntity *nsEntity = view->getEntity(structuralId);
267 
268  QMap <QString, QString>::iterator begin, end, it;
269  QMap <QString, QString> userData = nsEntity->getUsrData();
270  entity->getAttributeIterator(begin, end);
271  for (it = begin; it != end; ++it)
272  userData.insert(it.key(), it.value());
273 
274  nsEntity->setUsrData(userData);
275  }
276  else
277  qWarning() << "[QNST] QnsComposerPlugin::onEntityAdded entity "
278  << request << "is not in the view.";
279  }
280  else
281  qWarning() << "[QNST] QnsComposerPlugin::onEntityAdded Entity was not "
282  << "added"; */
283 
284  // \todo This must be incremental
285  view->clearValidationErrors();
286 }
287 
288 void QnstComposerPlugin::errorMessage(QString error)
289 {
290 
291 }
292 
293 void QnstComposerPlugin::onEntityChanged(QString pluginID, Entity *entity)
294 {
295  if(isSyncingFromTextual)
296  {
297  dirtyEntities.push_back(entity->getUniqueId());
298  return;
299  }
300 
301  if (pluginID != getPluginInstanceID())
302  requestEntityChange(entity);
303 
304  //Update user data
305  if(entities.contains(entity->getUniqueId()))
306  {
307  QString structuralId = entities.value(entity->getUniqueId());
308 
309  if(view->hasEntity(structuralId))
310  {
311  QnstEntity *nstEntity = view->getEntity(structuralId);
312 
313  if(nstEntity != NULL)
314  {
315  /*QMap <QString, QString>::iterator begin, end, it;
316  QMap <QString, QString> userData;
317  entity->getAttributeIterator(begin, end);
318  for (it = begin; it != end; ++it)
319  userData[it.key()] = it.value();
320 
321  nstEntity->setUsrData(userData);
322 
323  qDebug() << "[QNST] QnstComposerPlugin::onEntityChanged" << userData;*/
324  }
325  }
326  }
327 
328  // \todo This must be incremental
329  view->clearValidationErrors();
330 }
331 
332 void QnstComposerPlugin::onEntityRemoved(QString pluginID, QString entityID)
333 {
334  if(isSyncingFromTextual) return;
335 
336  if (pluginID != getPluginInstanceID())
337  {
338  requestEntityRemotion(getProject()->getEntityById(entityID));
339  entities.remove(entityID);
340  }
341 }
342 
343 void QnstComposerPlugin::changeSelectedEntity(QString pluginID, void* param)
344 {
345  if(isSyncingFromTextual) return;
346  QString* entityUID = (QString*) param;
347 
348  if(entityUID != NULL)
349  {
350  Entity *entity = getProject()->getEntityById(*entityUID);
351  if(entity != NULL)
352  {
353  requestEntitySelection(entity);
354  }
355  else
356  qWarning() << "QnstComposerPlugin is trying to select a entity that are not in the core"
357  << *entityUID;
358  }
359 }
360 
361 void QnstComposerPlugin::requestEntityAddition(Entity* entity)
362 {
363  qDebug() << "QnstComposerPlugin::requestEntityAddition" << entity->getType();
364 
365  QMap<QString, QString> properties;
366 
367  // get the qnst type based on NCL Composer Type
368  Qnst::EntityType type = QnstUtil::getnstTypeFromStr(entity->getType());
369  properties["TYPE"] = QnstUtil::getStrFromNstType(type);
370 
371  bool ok = false;
372 
373  switch (type)
374  {
375  case Qnst::Body:
376  {
377  entities[entity->getUniqueId()] = entity->getUniqueId();
378 
379  if (entity->getAttribute("id") != "")
380  properties["id"] = entity->getAttribute("id");
381 
382  ok = true;
383  break;
384  }
385 
386  case Qnst::Context:
387  {
388  entities[entity->getUniqueId()] = entity->getUniqueId();
389 
390  if (entity->getAttribute("id") != "")
391  properties["id"] = entity->getAttribute("id");
392 
393  if (entity->getAttribute("refer") != "")
394  properties["refer"] = entity->getAttribute("refer");
395 
396  ok = true;
397 
398  break;
399  }
400 
401  case Qnst::Switch:
402  {
403  entities[entity->getUniqueId()] = entity->getUniqueId();
404 
405  if (entity->getAttribute("id") != "")
406  properties["id"] = entity->getAttribute("id");
407 
408  if (entity->getAttribute("refer") != "")
409  properties["refer"] = entity->getAttribute("refer");
410 
411  ok = true;
412 
413  break;
414  }
415 
416  case Qnst::Media:
417  {
418  entities[entity->getUniqueId()] = entity->getUniqueId();
419 
420  properties["id"] = entity->getAttribute("id");
421  properties["src"] = entity->getAttribute("src");
422  properties["refer"] = entity->getAttribute("refer");
423  properties["instance"] = entity->getAttribute("instance");
424  properties["type"] = entity->getAttribute("type");
425  properties["descriptor"] = entity->getAttribute("descriptor");
426 
427  if (entity->getAttribute("refer") != "")
428  {
429  QString referUID = getUidById(properties["refer"]);
430  if(entities.contains(referUID))
431  properties["referUID"] = entities[referUID];
432  }
433  else
434  {
435  properties["referUID"] = "";
436  }
437 
438  // \fixme This must be made after the switch/case!!
439  if(entities.contains(entity->getParentUniqueId()))
440  {
441  view->addEntity(entity->getUniqueId(),
442  entities[entity->getParentUniqueId()],
443  properties);
444 
445  QList<Entity*> list;
446 
447  list = getProject()->getEntitiesbyType("port");
448 
449  // update properties?
450  foreach(Entity* e, list)
451  {
452  if (e->getAttribute("component") != "" &&
453  e->getAttribute("component") == properties["id"])
454  {
455  requestEntityChange(e);
456  }
457  }
458  }
459  break;
460  }
461 
462  case Qnst::Port:
463  {
464  entities[entity->getUniqueId()] = entity->getUniqueId();
465 
466  properties["id"] = entity->getAttribute("id");
467 
468  properties["component"] = entity->getAttribute("component");
469  if (entity->getAttribute("component") != "")
470  {
471  QString componentUID = getUidById(properties["component"]);
472  if(entities.contains(componentUID))
473  properties["componentUid"] = entities[componentUID];
474  }
475 
476  properties["interface"] = entity->getAttribute("interface");
477  if (entity->getAttribute("interface") != "")
478  {
479  QString interfaceUID = getUidById(properties["interface"]);
480  if(entities.contains(interfaceUID))
481  properties["interfaceUid"] = entities[interfaceUID];
482  }
483 
484  ok = true;
485 
486  break;
487  }
488 
489  case Qnst::Link:
490  {
491  entities[entity->getUniqueId()] = entity->getUniqueId();
492 
493  if (entity->getAttribute("id") != "")
494  properties["id"] = entity->getAttribute("id");
495 
496  if (entity->getAttribute("xconnector") != "")
497  {
498  properties["xconnector"] = entity->getAttribute("xconnector");
499 
500  QString xconnectorUID = getUidById(properties["xconnector"]);
501  if(entities.contains(xconnectorUID))
502  properties["xconnectorUID"] = entities[xconnectorUID];
503  else
504  properties["xconnectorUID"] = "";
505  }
506 
507  ok = true;
508 
509  break;
510  }
511 
512  case Qnst::Bind:
513  {
514  entities[entity->getUniqueId()] = entity->getUniqueId();
515 
516  properties["role"] = entity->getAttribute("role");
517  properties["component"] = entity->getAttribute("component");
518 
519  QString comUID = "";
520  if (entity->getAttribute("component") != "")
521  {
522  comUID = getUidById(properties["component"]);
523  if(entities.contains(comUID))
524  properties["componentUid"] = entities[comUID];
525  else
526  properties["componentUid"] = "";
527  }
528  else
529  {
530  properties["componentUid"] = "";
531  }
532 
533  properties["interface"] = entity->getAttribute("interface");
534 
535  if (entity->getAttribute("interface") != "")
536  {
537  Entity* cmp = getProject()->getEntityById(comUID);
538  if(cmp != NULL)
539  {
540  QString intUID = "";
541  foreach(Entity* c, cmp->getChildren())
542  {
543  if (c->getAttribute("id") == entity->getAttribute("interface") ||
544  c->getAttribute("name") == entity->getAttribute("interface"))
545  {
546  intUID = c->getUniqueId();
547  break;
548  }
549  }
550 
551  if(entities.contains(intUID))
552  properties["interfaceUid"] = entities[intUID];
553  else
554  properties["interfaceUid"] = "";
555  }
556  }
557  else
558  {
559  properties["interfaceUid"] = "";
560  }
561 
562  properties["linkUID"] = entities[entity->getParentUniqueId()];
563 
564  ok = true;
565  break;
566  }
567 
568  case Qnst::Property:
569  {
570  entities[entity->getUniqueId()] = entity->getUniqueId();
571 
572  properties["id"] = entity->getAttribute("name");
573 
574  ok = true;
575  break;
576  }
577 
578  case Qnst::Area:
579  {
580  entities[entity->getUniqueId()] = entity->getUniqueId();
581 
582  properties["id"] = entity->getAttribute("id");
583 
584  ok = true;
585  break;
586  }
587 
588  case Qnst::SwitchPort:
589  {
590  entities[entity->getUniqueId()] = entity->getUniqueId();
591 
592  properties["id"] = entity->getAttribute("id");
593 
594  ok = true;
595  break;
596  }
597 
598  case Qnst::Mapping:
599  {
600  entities[entity->getUniqueId()] = entity->getUniqueId();
601 
602  properties["component"] = entity->getAttribute("component");
603  if (entity->getAttribute("component") != "")
604  {
605  QString componentUID = getUidById(properties["component"]);
606  if(entities.contains(componentUID))
607  properties["componentUid"] = entities[componentUID];
608  }
609 
610  properties["interface"] = entity->getAttribute("interface");
611  if (entity->getAttribute("interface") != "")
612  {
613  QString interfaceUID = getUidById(properties["interface"]);
614  if(entities.contains(interfaceUID))
615  properties["interfaceUid"] = entities[interfaceUID];
616  }
617 
618  ok = true;
619  break;
620  }
621 
622  case Qnst::BindParam:
623  {
624  // \fixme Why we do not add to entities map ??
625  properties["name"] = entity->getAttribute("name");
626  properties["value"] = entity->getAttribute("value");
627 
628  ok = true;
629  break;
630  }
631 
632  default:
633  // do nothing!!
634  break;
635 
636  }
637 
638  if(ok)
639  {
640  // if it is body we are with no parent
641  if(type == Qnst::Body)
642  {
643  view->addEntity(entity->getUniqueId(), "", properties);
644  }
645  // otherwise, we need to set add with a parent
646  else
647  {
648  QString parentUID = entity->getParentUniqueId();
649  if(entities.contains(parentUID))
650  view->addEntity(entity->getUniqueId(), entities[parentUID], properties);
651  else
652  qWarning() << "QnstPlugin:: You are trying to add a "
653  << entity->getType()
654  << " inside an entity that does not exists.";
655  }
656  }
657  else
658  {
659  // Special cases!! We do not have Qnst::EntityType defined!!
660  if (entity->getType() == "causalConnector")
661  {
662  entities[entity->getUniqueId()] = entity->getUniqueId();
663 
664  requestCausalConnectorAddition(entity);
665  }
666  else if (entity->getType() == "simpleCondition")
667  {
668  entities[entity->getUniqueId()] = entity->getUniqueId();
669 
670  requestSimpleConditionAddition(entity);
671  }
672  else if (entity->getType() == "simpleAction")
673  {
674  entities[entity->getUniqueId()] = entity->getUniqueId();
675 
676  requestSimpleActionAddition(entity);
677  }
678  else if (entity->getType() == "importBase")
679  {
680  entities[entity->getUniqueId()] = entity->getUniqueId();
681  requestImportBaseAddition(entity);
682  }
683  else if (entity->getType() == "connectorParam")
684  {
685  entities[entity->getUniqueId()] = entity->getUniqueId();
686  requestConnectorParamAddition(entity);
687  }
688  }
689 }
690 
691 void QnstComposerPlugin::requestEntityRemotion(Entity* entity)
692 {
693  if (isEntityHandled(entity))
694  {
695  QString entityID = entity->getUniqueId();
696  if(entities.contains(entityID))
697  {
698  view->removeEntity(entities[entityID]);
699  entities.remove(entityID);
700  }
701  else
702  qWarning() << "You are trying to remove an entity that are not in the QnstComposerPlugin.";
703  }
704 }
705 
706 void QnstComposerPlugin::requestEntityChange(Entity* entity)
707 {
708  QMap<QString, QString> properties;
709 
710  // get the qnst type based on NCL Composer Type
711  int type = QnstUtil::getnstTypeFromStr(entity->getType());
712 
713  bool ok = false;
714 
715  switch (type)
716  {
717  case Qnst::Body:
718  {
719  if (entity->getAttribute("id") != "")
720  properties["id"] = entity->getAttribute("id");
721 
722  ok = true;
723  break;
724  }
725  case Qnst::Context:
726  case Qnst::Switch:
727  {
728  if (entity->getAttribute("id") != "")
729  properties["id"] = entity->getAttribute("id");
730 
731  if (entity->getAttribute("refer") != "")
732  properties["refer"] = entity->getAttribute("refer");
733 
734  ok = true;
735  break;
736  }
737 
738  case Qnst::Media:
739  {
740  properties["id"] = entity->getAttribute("id");
741  properties["src"] = entity->getAttribute("src");
742  properties["refer"] = entity->getAttribute("refer");
743  properties["instance"] = entity->getAttribute("instance");
744  properties["type"] = entity->getAttribute("type");
745  properties["descriptor"] = entity->getAttribute("descriptor");
746 
747  if(properties["refer"] != "")
748  {
749  QString referUID = getUidById(properties["refer"]);
750  if(entities.contains(referUID))
751  properties["referUID"] = entities[referUID];
752  }
753  else
754  {
755  properties["referUID"] = "";
756  }
757 
758  if(entities.contains(entity->getUniqueId()))
759  view->changeEntity( entities[entity->getUniqueId()],
760  properties);
761 
762  QList<Entity*> list;
763  list = getProject()->getEntitiesbyType("port");
764 
765  foreach(Entity* e, list){
766  if (e->getAttribute("component") != "")
767  {
768  if (e->getAttribute("component") == properties["id"])
769  {
770  requestEntityChange(e);
771  }
772  }
773  }
774 
775  ok = true;
776  break;
777  }
778 
779  case Qnst::Port:
780  {
781  properties["id"] = entity->getAttribute("id");
782  properties["component"] = entity->getAttribute("component");
783  if (entity->getAttribute("component") != "")
784  {
785  QString componentUID = getUidById(properties["component"]);
786  if(entities.contains(componentUID))
787  properties["componentUid"] = entities[componentUID];
788  }
789 
790  if (properties["componentUid"] != "")
791  {
792  properties["interface"] = entity->getAttribute("interface");
793  if (entity->getAttribute("interface") != "")
794  {
795  QString interfaceUID =
796  getUidByName(properties["interface"],
797  getProject()->getEntityById(
798  getUidById(properties["component"])));
799 
800  if(entities.contains(interfaceUID))
801  properties["interfaceUid"] = entities[interfaceUID];
802  }
803  }
804 
805  ok = true;
806  break;
807  }
808 
809  case Qnst::Link:
810  {
811  if (entity->getAttribute("id") != "")
812  properties["id"] = entity->getAttribute("id");
813 
814  if (entity->getAttribute("xconnector") != "")
815  {
816  properties["xconnector"] = entity->getAttribute("xconnector");
817  if(entities.contains(getUidById(properties["xconnector"])))
818  {
819  properties["xconnectorUID"] =
820  entities[getUidById(properties["xconnector"])];
821  }
822  else
823  properties["xconnectorUID"] = "";
824  }
825 
826  ok = true;
827  break;
828  }
829 
830  case Qnst::Bind:
831  case Qnst::Action:
832  case Qnst::Condition:
833  {
834  properties["TYPE"] = "bind";
835  properties["role"] = entity->getAttribute("role");
836  properties["component"] = entity->getAttribute("component");
837 
838  QString comUID = "";
839  if (entity->getAttribute("component") != "")
840  {
841  comUID = getUidById(properties["component"]);
842  if(entities.contains(comUID))
843  properties["componentUid"] = entities[comUID];
844  else
845  properties["componentUid"] = "";
846  }
847  else
848  {
849  properties["componentUid"] = "";
850  }
851 
852  properties["interface"] = entity->getAttribute("interface");
853  if (entity->getAttribute("interface") != "")
854  {
855  Entity* cmp = getProject()->getEntityById(comUID);
856 
857  if(cmp != NULL)
858  {
859  QString intUID = "";
860  foreach(Entity* c, cmp->getChildren())
861  {
862  if (c->getAttribute("id") == entity->getAttribute("interface") ||
863  c->getAttribute("name") == entity->getAttribute("interface"))
864  {
865  intUID = c->getUniqueId();
866  break;
867  }
868  }
869 
870  if(entities.contains(intUID))
871  properties["interfaceUid"] = entities[intUID];
872  else
873  properties["interfaceUid"] = "";
874  }
875  }
876  else
877  {
878  properties["interfaceUid"] = "";
879  }
880 
881  // get the parent
882  properties["linkUID"] = entities[entity->getParentUniqueId()];
883 
884  ok = true;
885  break;
886  }
887 
888  case Qnst::Area:
889  {
890  properties["TYPE"] = "area"; // Do I need that?
891  properties["id"] = entity->getAttribute("id");
892 
893  ok = true;
894  break;
895  }
896 
897  case Qnst::Property:
898  {
899  properties["TYPE"] = "property"; // Do I need that?
900  properties["id"] = entity->getAttribute("name");
901 
902  ok = true;
903  break;
904  }
905 
906  case Qnst::SwitchPort:
907  {
908  properties["id"] = entity->getAttribute("id");
909  ok = true;
910  break;
911  }
912 
913  case Qnst::Mapping:
914  {
915  properties["component"] = entity->getAttribute("component");
916  if (entity->getAttribute("component") != "")
917  {
918  QString componentUID = getUidById(properties["component"]);
919  if(entities.contains(componentUID))
920  properties["componentUid"] = entities[componentUID];
921  }
922 
923  properties["interface"] = entity->getAttribute("interface");
924  if (entity->getAttribute("interface") != "")
925  {
926  QString interfaceUID = getUidById(properties["interface"]);
927  if(entities.contains(interfaceUID))
928  properties["interfaceUid"] = entities[interfaceUID];
929  }
930 
931  ok = true;
932  break;
933  }
934 
935  case Qnst::BindParam:
936  {
937  properties["TYPE"] = "bindParam";
938 
939  properties["name"] = entity->getAttribute("name");
940  properties["value"] = entity->getAttribute("value");
941  properties["parent"] = entities[entity->getParentUniqueId()];
942 
943  ok = true;
944  break;
945  }
946  }
947 
948  if(ok)
949  {
950  if(entities.contains(entity->getUniqueId()))
951  view->changeEntity(entities[entity->getUniqueId()], properties);
952  else
953  qWarning() << "QnstPlugin:: You are trying to EDIT an entity that does not exists.";
954  }
955  else
956  {
957  // Special cases!! We do not have Qnst::EntityType defined!!
958  if (entity->getType() == "causalConnector")
959  {
960  requestCausalConnectorChange(entity);
961  }
962  // if the entity is of type SimpleCondition
963  else if (entity->getType() == "simpleCondition")
964  {
965  requestSimpleConditionChange(entity);
966  }
967  // if the entity is of type SimpleAction
968  else if (entity->getType() == "simpleAction")
969  {
970  requestSimpleActionChange(entity);
971  }
972  // if the entity is of type ImportBase
973  else if (entity->getType() == "importBase")
974  {
975  requestImportBaseChange(entity);
976  }
977  else if (entity->getType() == "connectorParam")
978  {
979  // \fixme Do what ?
980  }
981  }
982 }
983 
984 void QnstComposerPlugin::requestEntitySelection(Entity* entity)
985 {
986  if (entities.contains(entity->getUniqueId()) &&
987  lastSelected != entity->getUniqueId())
988  {
989  if (entity->getType() == "body" ||
990  entity->getType() == "context" ||
991  entity->getType() == "media" ||
992  entity->getType() == "switch" ||
993  entity->getType() == "port" ||
994  entity->getType() == "link" ||
995  entity->getType() == "area" ||
996  entity->getType() == "mapping" ||
997  entity->getType() == "bind" ||
998  entity->getType() == "switchPort" ||
999  entity->getType() == "property")
1000  {
1001  view->selectEntity(entities[entity->getUniqueId()]);
1002  }
1003  }
1004 }
1005 
1006 void QnstComposerPlugin::requestImportBaseAddition(Entity* entity)
1007 {
1008  qWarning() << "Adding requestImportBaseAddition " << entity;
1009  if (entity != NULL)
1010  {
1011  Entity* parent = entity->getParent();
1012 
1013  if (parent != NULL)
1014  {
1015  if (parent->getType() == "connectorBase")
1016  {
1017  QMap<QString, QString> properties;
1018 
1019  properties["TYPE"] = "importBase";
1020 
1021  if (entity->getAttribute("documentURI") != "")
1022  {
1023  properties["projectURI"] = getProject()->getLocation();
1024  properties["documentURI"] = entity->getAttribute("documentURI");
1025  }
1026 
1027  if (entity->getAttribute("alias") != "")
1028  properties["alias"] = entity->getAttribute("alias");
1029 
1030  // if(entities.contains(entity->getUniqueId()))
1031  view->addEntity( entity->getUniqueId(),
1032  parent->getUniqueId(),
1033  properties );
1034  }
1035  }
1036  }
1037 }
1038 
1039 void QnstComposerPlugin::requestImportBaseChange(Entity* entity)
1040 {
1041  if (entity != NULL)
1042  {
1043  Entity* parent = entity->getParent();
1044 
1045  if (parent != NULL)
1046  {
1047  if (parent->getType() == "connectorBase")
1048  {
1049  QMap<QString, QString> properties;
1050 
1051  properties["TYPE"] = "importBase";
1052 
1053  if (entity->getAttribute("documentURI") != "")
1054  {
1055  properties["projectURI"] = getProject()->getLocation();
1056  properties["documentURI"] = entity->getAttribute("documentURI");
1057  }
1058 
1059  if (entity->getAttribute("alias") != "")
1060  properties["alias"] = entity->getAttribute("alias");
1061 
1062  // if(entities.contains(entity->getUniqueId()))
1063 
1064  view->changeEntity(entity->getUniqueId(),properties);
1065  }
1066  }
1067  }
1068 }
1069 
1070 void QnstComposerPlugin::requestCausalConnectorAddition(Entity* entity)
1071 {
1072  QMap<QString, QString> properties;
1073 
1074  properties["TYPE"] = "causalConnector";
1075 
1076  if (entity->getAttribute("id") != "")
1077  properties["id"] = entity->getAttribute("id");
1078 
1079  if(entity->getParent()->getType() == "importBase")
1080  view->addEntity(entity->getUniqueId(), entity->getParentUniqueId(),
1081  properties);
1082  else
1083  view->addEntity(entity->getUniqueId(),"", properties);
1084 }
1085 
1086 void QnstComposerPlugin::requestCausalConnectorChange(Entity* entity)
1087 {
1088  QMap<QString, QString> properties;
1089 
1090  if (entity->getAttribute("id") != "")
1091  properties["id"] = entity->getAttribute("id");
1092 
1093  if(entities.contains(entity->getUniqueId()))
1094  view->changeEntity(entities[entity->getUniqueId()], properties);
1095 }
1096 
1097 void QnstComposerPlugin::requestSimpleConditionAddition(Entity* entity)
1098 {
1099  QMap<QString, QString> properties;
1100 
1101  properties["TYPE"] = "simpleCondition";
1102  Entity* conn = entity->getParent();
1103  while (conn->getType() != "causalConnector" && conn != getProject())
1104  {
1105  conn = conn->getParent();
1106  }
1107 
1108  if(entities.contains(conn->getUniqueId()))
1109  properties["connector"] = entities[conn->getUniqueId()];
1110  else
1111  properties["connector"] = "";
1112 
1113  if (entity->getAttribute("role") != "")
1114  {
1115  properties["role"] = entity->getAttribute("role");
1116  }
1117 
1118  QMap<QString, QString>::iterator begin;
1119  QMap<QString, QString>::iterator end;
1120 
1121  entity->getAttributeIterator(begin,end);
1122 
1123  int n = 0;
1124 
1125  while(begin != end)
1126  {
1127  QString name(begin.key());
1128  QString value(begin.value());
1129 
1130  if (value.startsWith("$"))
1131  {
1132  properties["attr"+QString::number(n)] = name;
1133  properties["value"+QString::number(n)] = value.replace('$',"");
1134  n++;
1135  }
1136 
1137  begin++;
1138  }
1139 
1140  if(entities.contains(conn->getUniqueId()))
1141  view->addEntity(entity->getUniqueId(),
1142  entities[conn->getUniqueId()], properties);
1143  else
1144  view->addEntity(entity->getUniqueId(), "", properties);
1145 }
1146 
1147 void QnstComposerPlugin::requestSimpleConditionChange(Entity* entity)
1148 {
1149  QMap<QString, QString> properties;
1150 
1151  properties["TYPE"] = "simpleCondition";
1152 
1153  Entity* conn = entity->getParent();
1154  while (conn->getType() != "causalConnector" && conn != getProject())
1155  {
1156  conn = conn->getParent();
1157  }
1158 
1159  if(entities.contains(conn->getUniqueId()))
1160  properties["connector"] = entities[conn->getUniqueId()];
1161  else
1162  properties["connector"] = "";
1163 
1164  if (entity->getAttribute("role") != "")
1165  properties["role"] = entity->getAttribute("role");
1166 
1167  QMap<QString, QString>::iterator begin;
1168  QMap<QString, QString>::iterator end;
1169 
1170  entity->getAttributeIterator(begin,end);
1171 
1172  int n = 0;
1173 
1174  while(begin != end)
1175  {
1176  QString name(begin.key());
1177  QString value(begin.value());
1178 
1179  if (value.startsWith("$"))
1180  {
1181  properties["attr"+QString::number(n)] = name;
1182  properties["value"+QString::number(n)] = value.replace('$',"");
1183  n++;
1184  }
1185 
1186  begin++;
1187  }
1188 
1189  if(entities.contains(entity->getUniqueId()))
1190  view->changeEntity(entities[entity->getUniqueId()], properties);
1191 }
1192 
1193 void QnstComposerPlugin::requestSimpleActionAddition(Entity* entity)
1194 {
1195  QMap<QString, QString> properties;
1196 
1197  properties["TYPE"] = "simpleAction";
1198 
1199  Entity* conn = entity->getParent();
1200  while (conn->getType() != "causalConnector" && conn != getProject())
1201  {
1202  conn = conn->getParent();
1203  }
1204 
1205  if(entities.contains(conn->getUniqueId()))
1206  properties["connector"] = entities[conn->getUniqueId()];
1207  else
1208  properties["connector"] = "";
1209 
1210  if (entity->getAttribute("role") != "")
1211  {
1212  properties["role"] = entity->getAttribute("role");
1213  }
1214 
1215  QMap<QString, QString>::iterator begin;
1216  QMap<QString, QString>::iterator end;
1217 
1218  entity->getAttributeIterator(begin,end);
1219 
1220  int n = 0;
1221 
1222  while(begin != end)
1223  {
1224  QString name(begin.key());
1225  QString value(begin.value());
1226 
1227  if (value.startsWith("$"))
1228  {
1229  properties["attr"+QString::number(n)] = name;
1230  properties["value"+QString::number(n)] = value.replace('$',"");
1231  n++;
1232  }
1233 
1234  begin++;
1235  }
1236 
1237  if(entities.contains(conn->getUniqueId()))
1238  view->addEntity(entity->getUniqueId(),
1239  entities[conn->getUniqueId()], properties);
1240  else
1241  view->addEntity(entity->getUniqueId(), "", properties);
1242 }
1243 
1244 void QnstComposerPlugin::requestSimpleActionChange(Entity* entity)
1245 {
1246  QMap<QString, QString> properties;
1247 
1248  properties["TYPE"] = "simpleAction";
1249 
1250  Entity* conn = entity->getParent();
1251  while (conn->getType() != "causalConnector" && conn != getProject())
1252  {
1253  conn = conn->getParent();
1254  }
1255 
1256  if(entities.contains(conn->getUniqueId()))
1257  properties["connector"] = entities[conn->getUniqueId()];
1258  else
1259  properties["connector"] = "";
1260 
1261  if (entity->getAttribute("role") != "")
1262  properties["role"] = entity->getAttribute("role");
1263 
1264  QMap<QString, QString>::iterator begin;
1265  QMap<QString, QString>::iterator end;
1266 
1267  entity->getAttributeIterator(begin,end);
1268 
1269  int n = 0;
1270 
1271  while(begin != end)
1272  {
1273  QString name(begin.key());
1274  QString value(begin.value());
1275 
1276  if (value.startsWith("$"))
1277  {
1278  properties["attr"+QString::number(n)] = name;
1279  properties["value"+QString::number(n)] = value.replace('$',"");
1280  n++;
1281  }
1282 
1283  begin++;
1284  }
1285 
1286  if(entities.contains(entity->getUniqueId()))
1287  view->changeEntity(entities[entity->getUniqueId()], properties);
1288 }
1289 
1290 void QnstComposerPlugin::requestConnectorParamAddition(Entity* entity)
1291 {
1292  QMap<QString, QString> properties;
1293 
1294  properties["TYPE"] = "connectorParam";
1295 
1296  properties["name"] = entity->getAttribute("name");
1297 
1298  QString parentUID = entity->getParentUniqueId();
1299  if(entities.contains(parentUID))
1300  view->addEntity(entity->getUniqueId(), entities[parentUID], properties);
1301  else
1302  qWarning() << "QnstPlugin:: You are trying to add an CONNECTORPARAM as child of an entity that does not exists.";
1303 
1304 }
1305 
1306 // \fixme this methos is not being called anywhere!!!
1307 void QnstComposerPlugin::requestConnectorParamChange(Entity* entity)
1308 {
1309  QMap<QString, QString> properties;
1310 
1311  properties["TYPE"] = "connectorParam";
1312 
1313  properties["name"] = entity->getAttribute("name");
1314  properties["parent"] = entities[entity->getParentUniqueId()];
1315 
1316  if(entities.contains(entity->getUniqueId()))
1317  view->changeEntity(entities[entity->getUniqueId()], properties);
1318 }
1319 
1320 void QnstComposerPlugin::notifyEntityAddedInView(const QString uid,
1321  const QString parent,
1322  QMap<QString, QString> properties)
1323 {
1324  Qnst::EntityType type = QnstUtil::getnstTypeFromStr(properties["TYPE"]);
1325 
1326  Entity* entity = NULL;
1327 
1328  QMap<QString, QString> attributes;
1329  bool mustEmitAddEntity = false;
1330 
1331  if(type != Qnst::Body)
1332  {
1333  entity = getProject()->getEntityById(entities.key(parent));
1334 
1335  if(entity == NULL)
1336  {
1337  qWarning() << "[QNST] Warning: trying to add an entity as child of an inexistent Entity";
1338  if(properties["TYPE"] == "importBase" ||
1339  properties["TYPE"] == "causalConnector" ||
1340  properties["TYPE"] == "connector" ||
1341  properties["TYPE"] == "complex-connector")
1342  { // In these cases we do not need a parent.
1343  qWarning() << "[QNST] " << properties["TYPE"] << " is a special case. So, we will not need a parent.";
1344  }
1345  else
1346  {
1347  qWarning() << "[QNST] The entityAdd is beging ignored!";
1348  return;
1349  }
1350  }
1351  }
1352 
1353  // Load specific properties for each type (and handle dependencies)
1354  switch(type)
1355  {
1356  case Qnst::Body:
1357  {
1358  requestBodyDependence();
1359  QList<Entity*> list = getProject()->getEntitiesbyType("ncl");
1360 
1361  if (!list.isEmpty())
1362  {
1363  entity = list.first();
1364 
1365  if (properties["id"] != "")
1366  attributes["id"] = properties["id"];
1367 
1368  mustEmitAddEntity = true;
1369  }
1370  break;
1371  }
1372 
1373  case Qnst::Context:
1374  {
1375  if (properties["id"] != "")
1376  attributes["id"] = properties["id"];
1377 
1378  if (properties["refer"] != "")
1379  attributes["refer"] = properties["refer"];
1380 
1381  mustEmitAddEntity = true;
1382  break;
1383  }
1384 
1385  case Qnst::Switch:
1386  {
1387  if (properties["id"] != "")
1388  attributes["id"] = properties["id"];
1389 
1390  if (properties["refer"] != "")
1391  attributes["refer"] = properties["refer"];
1392 
1393  mustEmitAddEntity = true;
1394  break;
1395  }
1396 
1397  case Qnst::Media:
1398  {
1399  if (properties["id"] != "")
1400  attributes["id"] = properties["id"];
1401 
1402  if (properties["src"] != "")
1403  {
1404  QString src = properties["src"];
1405  try
1406  {
1407  attributes["src"] = Utilities::relativePath(project->getLocation(),
1408  src, true);
1409  }
1410  catch(...)
1411  {
1412  attributes["src"] = properties["src"];
1413  }
1414  }
1415 
1416  if (properties["refer"] != "")
1417  attributes["refer"] = properties["refer"];
1418 
1419  if (properties["instance"] != "")
1420  attributes["instance"] = properties["instance"];
1421 
1422  if (properties["type"] != "")
1423  attributes["type"] = properties["type"];
1424 
1425  if (properties["descriptor"] != "")
1426  attributes["descriptor"] = properties["descriptor"];
1427 
1428  mustEmitAddEntity = true;
1429  break;
1430  }
1431  case Qnst::Port:
1432  {
1433  attributes["id"] = properties["id"];
1434  attributes["component"] = properties["component"];
1435 
1436  if(properties["interface"] != "")
1437  attributes["interface"] = properties["interface"];
1438 
1439  mustEmitAddEntity = true;
1440  break;
1441  }
1442 
1443  case Qnst::Link:
1444  {
1445  attributes["id"] = properties["id"];
1446  attributes["xconnector"] = properties["xconnector"];
1447 
1448  mustEmitAddEntity = true;
1449  request = uid;
1450  break;
1451  }
1452 
1453  case Qnst::Bind:
1454  {
1455  requestBindAddition(uid, parent, properties);
1456  mustEmitAddEntity = false; // the add is made inside requestBindAddition!!!
1457  break;
1458  }
1459 
1460  case Qnst::Area:
1461  {
1462  attributes["id"] = properties["id"];
1463  mustEmitAddEntity = true;
1464  break;
1465  }
1466 
1467  case Qnst::Property:
1468  {
1469  attributes["name"] = properties["id"];
1470 
1471  mustEmitAddEntity = true;
1472  break;
1473  }
1474 
1475  case Qnst::SwitchPort:
1476  {
1477  if (properties["id"] != "")
1478  attributes["id"] = properties["id"];
1479 
1480  mustEmitAddEntity = true;
1481  break;
1482  }
1483 
1484  case Qnst::Mapping:
1485  {
1486  if (properties["component"] != "")
1487  attributes["component"] = properties["component"];
1488 
1489  if (properties["interface"] != "")
1490  attributes["interface"] = properties["interface"];
1491 
1492  mustEmitAddEntity = true;
1493  break;
1494  }
1495 
1496  case Qnst::BindParam:
1497  {
1498  if (properties["name"] != "")
1499  attributes["name"] = properties["name"];
1500 
1501  if (properties["value"] != "")
1502  attributes["value"] = properties["value"];
1503 
1504  mustEmitAddEntity= true;
1505  break;
1506  }
1507 
1508  default:
1509  // do nothing
1510  break;
1511  }
1512 
1513  if(mustEmitAddEntity && entity != NULL) // Everything is ok, so add my new entity
1514  {
1515  request = uid;
1516  emit addEntity(properties["TYPE"],
1517  entity->getUniqueId(), attributes, false);
1518  request = "";
1519 
1520  }
1521  else
1522  {
1523  // Special cases!! We do not have Qnst::EntityType defined!!
1524  if (properties["TYPE"] == "connector")
1525  requestConnectorAddition(uid, parent, properties);
1526  else if (properties["TYPE"] == "complex-connector")
1527  requestComplexConnectorAddition(uid, parent, properties);
1528  }
1529 }
1530 
1531 void QnstComposerPlugin::notifyEntityDeletedInView(const QString uid)
1532 {
1533  if (entities.key(uid, "nil") != "nil")
1534  {
1535  emit removeEntity(getProject()->getEntityById(entities.key(uid)), false);
1536  entities.remove(entities.key(uid));
1537  }
1538 }
1539 
1540 void QnstComposerPlugin::notifyEntityChangedInView(const QString uid,
1541  QMap<QString, QString> properties)
1542 {
1543  Qnst::EntityType type = QnstUtil::getnstTypeFromStr(properties["TYPE"]);
1544 
1545  QMap<QString, QString> attributes;
1546  Entity* entity = getProject()->getEntityById(entities.key(uid));
1547 
1548  bool mustSetAttributes = false;
1549 
1550  if(entity == NULL)
1551  {
1552  qWarning() << "[QNST] Error!!! Trying to change a entity that does not exist in the model";
1553  }
1554 
1555  switch (type)
1556  {
1557  case Qnst::Body:
1558  {
1559  if (properties["id"] != "")
1560  attributes["id"] = properties["id"];
1561 
1562  mustSetAttributes = true;
1563  break;
1564  }
1565 
1566  case Qnst::Context:
1567  case Qnst::Switch:
1568  {
1569  if (properties["id"] != "")
1570  attributes["id"] = properties["id"];
1571 
1572  if (properties["refer"] != "")
1573  attributes["refer"] = properties["refer"];
1574 
1575  mustSetAttributes = true;
1576  break;
1577  }
1578 
1579  case Qnst::Media:
1580  {
1581  if (properties["id"] != "")
1582  attributes["id"] = properties["id"];
1583 
1584  if (properties["src"] != "")
1585  attributes["src"] = properties["src"];
1586 
1587  if (properties["refer"] != "")
1588  attributes["refer"] = properties["refer"];
1589 
1590  if (properties["instance"] != "")
1591  attributes["instance"] = properties["instance"];
1592 
1593  if (properties["type"] != "")
1594  attributes["type"] = properties["type"];
1595 
1596  if (properties["descriptor"] != "")
1597  attributes["descriptor"] = properties["descriptor"];
1598 
1599  mustSetAttributes = true;
1600  break;
1601  }
1602 
1603  case Qnst::Port:
1604  {
1605  attributes["id"] = properties["id"];
1606 
1607  if(properties["component"] != "")
1608  attributes["component"] = properties["component"];
1609 
1610  if(properties["interface"] != "")
1611  attributes["interface"] = properties["interface"];
1612 
1613  mustSetAttributes = true;
1614  break;
1615  }
1616 
1617  case Qnst::BindParam:
1618  {
1619  if (properties["name"] != "")
1620  attributes["name"] = properties["name"];
1621 
1622  if (properties["value"] != "")
1623  attributes["value"] = properties["value"];
1624 
1625  mustSetAttributes = true;
1626  break;
1627  }
1628 
1629  case Qnst::Mapping:
1630  {
1631  if (properties["component"] != "")
1632  attributes["component"] = properties["component"];
1633 
1634  if (properties["interface"] != "")
1635  attributes["interface"] = properties["interface"];
1636 
1637  mustSetAttributes = true;
1638  break;
1639  }
1640 
1641  case Qnst::SwitchPort:
1642  {
1643 
1644  if (properties["id"] != "")
1645  attributes["id"] = properties["id"];
1646 
1647  mustSetAttributes = true;
1648  break;
1649  }
1650  case Qnst::Area:
1651  case Qnst::Property:
1652  // \todo Changing of property and area.
1653  break;
1654 
1655  default:
1656  break;
1657  }
1658 
1659  if(mustSetAttributes)
1660  {
1661  emit setAttributes(entity, attributes, false);
1662  }
1663 
1664  // \fixme By now, we are also setting additional data, but maybe this is not
1665  // necessary.
1666  QString coreID = entities.key(uid);
1667  QnstEntity *qnstEntity = view->entities.value(uid);
1668  if(qnstEntity != NULL)
1669  {
1670  //Disabled for now
1671  //QMap <QString, QString> props;
1672  //qnstEntity->getProperties(props);
1673  //emit setAttributes(project->getEntityById(coreID),
1674  // props, false);
1675  }
1676 }
1677 
1678 void QnstComposerPlugin::requestEntitySelection(const QString uid)
1679 {
1680  if (entities.key(uid, "nil") != "nil")
1681  {
1682  lastSelected = entities.key(uid);
1683 
1684  emit sendBroadcastMessage("changeSelectedEntity",
1685  new QString(entities.key(uid)));
1686  }
1687 }
1688 
1689 void QnstComposerPlugin::requestBodyDependence()
1690 {
1691  QList<Entity*> list = getProject()->getEntitiesbyType("ncl");
1692 
1693  if (list.isEmpty())
1694  {
1695  Entity* project = getProject();
1696  if (project != NULL)
1697  {
1698  QMap<QString, QString> attributes;
1699  emit addEntity("ncl", project->getUniqueId(), attributes, false);
1700  }
1701  }
1702 }
1703 
1704 void QnstComposerPlugin::requestConnectorAddition(const QString uid,
1705  const QString parent,
1706  const QMap<QString, QString> &properties)
1707 {
1708  requestConnectorDependence();
1709 
1710  qWarning() << "QnstComposerPlugin::requestConnectorAddition";
1711 
1712  QList<Entity*> list = getProject()->getEntitiesbyType("connectorBase");
1713 
1714  if (!list.isEmpty())
1715  {
1716  Entity* entity = list.first();
1717 
1718  if (entity != NULL)
1719  {
1720  QMap<QString, QString> attributes;
1721 
1722  attributes["id"] = properties["id"];
1723 
1724  request = uid;
1725  emit addEntity("causalConnector", entity->getUniqueId(), attributes, false);
1726  request = "";
1727 
1728  // condition
1729  QMap<QString, QString> cattributes;
1730  cattributes["role"] = properties["condition"];
1731  cattributes["max"] = "unbounded";
1732 
1733  emit addEntity("simpleCondition", entities.key(uid), cattributes, false);
1734 
1735  // action
1736  QMap<QString, QString> aattributes;
1737  aattributes["role"] = properties["action"].toLower();
1738  aattributes["max"] = "unbounded";
1739 
1740  emit addEntity("simpleAction", entities.key(uid), aattributes, false);
1741  }
1742  }
1743 }
1744 
1745 void QnstComposerPlugin::requestComplexConnectorAddition(const QString uid,
1746  const QString parent,
1747  const QMap<QString, QString> &properties)
1748 {
1749  requestConnectorDependence();
1750 
1751  QList<Entity*> list = getProject()->getEntitiesbyType("connectorBase");
1752 
1753  if (!list.isEmpty())
1754  {
1755  Entity* entity = list.first();
1756 
1757  if (entity != NULL)
1758  {
1759  QMap<QString, QString> attributes;
1760 
1761  attributes["id"] = properties["id"];
1762 
1763  request = uid;
1764  emit addEntity("causalConnector", entity->getUniqueId(), attributes, false);
1765  request = "";
1766 
1767  QMap<QString, QString> fakemap;
1768  fakemap["operator"] = "or";
1769  emit addEntity("compoundCondition", entities.key(uid), fakemap, false);
1770 
1771  fakemap["operator"] = "par";
1772  emit addEntity("compoundAction", entities.key(uid), fakemap, false);
1773 
1774  QString cpcUID;
1775  QString cpaUID;
1776 
1777  Entity *cmp = getProject()->getEntityById(entities.key(uid));
1778  if(cmp != NULL)
1779  {
1780  foreach(Entity* child, cmp->getChildren())
1781  {
1782  if (child->getType() == "compoundCondition")
1783  cpcUID = child->getUniqueId();
1784 
1785  if (child->getType() == "compoundAction")
1786  cpaUID = child->getUniqueId();
1787  }
1788  }
1789 
1790  // condition
1791  if (properties["condition"] != "" && cpcUID != "")
1792  {
1793  QMap<QString, QString> cattributes;
1794  cattributes["role"] = properties["condition"];
1795  cattributes["max"] = "unbounded";
1796 
1797  request = properties["conditionUID"];
1798  emit addEntity("simpleCondition", cpcUID, cattributes, false);
1799  request = "";
1800  }
1801 
1802  // action
1803  if (properties["action"] != "" && cpaUID != "")
1804  {
1805  QMap<QString, QString> aattributes;
1806  aattributes["role"] = properties["action"].toLower();
1807  aattributes["max"] = "unbounded";
1808 
1809  request = properties["actionUID"];
1810  emit addEntity("simpleAction", cpaUID, aattributes, false);
1811  request = "";
1812  }
1813  }
1814  }
1815 }
1816 
1817 void QnstComposerPlugin::requestConnectorDependence()
1818 {
1819  requestConnectorBaseDependence();
1820 
1821  QList<Entity*> list = getProject()->getEntitiesbyType("connectorBase");
1822 
1823  if (list.isEmpty())
1824  {
1825  Entity* parent = NULL;
1826 
1827  if (!getProject()->getEntitiesbyType("head").isEmpty())
1828  parent = getProject()->getEntitiesbyType("head").first();
1829 
1830  if (parent != NULL)
1831  {
1832  QMap<QString, QString> attributes;
1833 
1834  emit addEntity("connectorBase", parent->getUniqueId(), attributes, false);
1835  }
1836  }
1837 }
1838 
1839 void QnstComposerPlugin::requestConnectorBaseDependence()
1840 {
1841  QList<Entity*> list = getProject()->getEntitiesbyType("head");
1842 
1843  if (list.isEmpty())
1844  {
1845  Entity* parent = NULL;
1846 
1847  if (!getProject()->getEntitiesbyType("ncl").isEmpty())
1848  parent = getProject()->getEntitiesbyType("ncl").first();
1849 
1850  if (parent != NULL)
1851  {
1852  QMap<QString, QString> attributes;
1853 
1854  emit addEntity("head", parent->getUniqueId(), attributes, false);
1855  }
1856  }
1857 }
1858 
1859 void QnstComposerPlugin::requestBindAddition(const QString uid,
1860  const QString parent,
1861  const QMap<QString, QString> &properties)
1862 {
1863  // checking connector
1864  QList<Entity*> connectors = getProject()->getEntitiesbyType("causalConnector");
1865 
1866  QString connUID = "";
1867 
1868  foreach(Entity* conn, connectors)
1869  {
1870  if (conn->getAttribute("id") == properties["connector"])
1871  {
1872  connUID = conn->getUniqueId();
1873  break;
1874  }
1875  }
1876 
1877  QString cpcUID = "";
1878  QString cpaUID = "";
1879 
1880  if (connUID != "")
1881  {
1882  Entity *cmp = getProject()->getEntityById(connUID);
1883  if(cmp != NULL)
1884  {
1885  foreach(Entity* child, cmp->getChildren())
1886  {
1887  if (child->getType() == "compoundCondition")
1888  cpcUID = child->getUniqueId();
1889 
1890  if (child->getType() == "compoundAction")
1891  cpaUID = child->getUniqueId();
1892  }
1893  }
1894  }
1895 
1896  if (cpcUID != "" && cpaUID != "")
1897  {
1898  if (properties["condition"] != "")
1899  {
1900  bool hasCond = false;
1901  Entity *cmp = getProject()->getEntityById(cpcUID);
1902  if(cmp != NULL)
1903  {
1904  foreach(Entity* child, cmp->getChildren())
1905  {
1906  if (child->getAttribute("role") == properties["condition"])
1907  {
1908  hasCond = true;
1909  break;
1910  }
1911  }
1912  }
1913 
1914  if (!hasCond)
1915  {
1916  QMap<QString, QString> cattributes;
1917 
1918  cattributes["role"] = properties["condition"];
1919 
1920  emit addEntity("simpleCondition", cpcUID, cattributes, false);
1921  }
1922  }
1923 
1924  if (properties["action"] != "")
1925  {
1926  bool hasAct = false;
1927 
1928  Entity *cmp = getProject()->getEntityById(cpaUID);
1929  if(cmp != NULL)
1930  {
1931  foreach(Entity* child, cmp->getChildren())
1932  {
1933  if (child->getAttribute("role") == properties["action"].toLower())
1934  {
1935  hasAct = true;
1936  break;
1937  }
1938  }
1939  }
1940 
1941  if (!hasAct)
1942  {
1943  QMap<QString, QString> aattributes;
1944  aattributes["role"] = properties["action"].toLower();
1945 
1946  emit addEntity("simpleAction", cpaUID, aattributes, false);
1947  }
1948  }
1949  }
1950 
1951  //checking link
1952  QList<Entity*> links = getProject()->getEntitiesbyType("link");
1953 
1954  QString liknUID = "";
1955 
1956  foreach(Entity* link, links)
1957  {
1958  if (link->getAttribute("id") == properties["link"])
1959  {
1960  liknUID = link->getUniqueId();
1961  break;
1962  }
1963  }
1964 
1965  if (liknUID == "")
1966  {
1967  QMap<QString, QString> linkattributes;
1968 
1969  linkattributes["id"] = properties["link"];
1970  linkattributes["xconnector"] = properties["connector"];
1971 
1972  if (properties["linkUID"] != "")
1973  request = properties["linkUID"];
1974  else
1975  request = QUuid::createUuid().toString();
1976 
1977  // \todo This could results in a Null pointer.
1978  emit addEntity("link",
1979  getProject()->getEntityById(entities.key(parent))->getUniqueId(),
1980  linkattributes, false);
1981  request = "";
1982 
1983  liknUID = getUidById(linkattributes["id"]);
1984  }
1985 
1986  // add bind
1987  if (properties["condition"] != "")
1988  {
1989  // bind condition
1990  QMap<QString, QString> cattributes;
1991 
1992  cattributes["role"] = properties["condition"];
1993  cattributes["component"] = properties["component"];
1994 
1995  if (properties["interface"] != "")
1996  cattributes["interface"] = properties["interface"];
1997 
1998  request = uid;
1999  emit addEntity("bind", liknUID, cattributes, false);
2000  request = "";
2001 
2002  }
2003  else if (properties["action"] != "")
2004  {
2005  // bind action
2006  QMap<QString, QString> aattributes;
2007 
2008  aattributes["role"] = properties["action"].toLower();
2009  aattributes["component"] = properties["component"];
2010 
2011  if (properties["interface"] != "")
2012  aattributes["interface"] = properties["interface"];
2013 
2014  request = uid;
2015  emit addEntity("bind", liknUID, aattributes, false);
2016  request = "";
2017  }
2018 }
2019 
2020 QString QnstComposerPlugin::getUidById(QString id)
2021 {
2022  return getUidById(id, getProject());
2023 }
2024 
2025 QString QnstComposerPlugin::getUidById(QString id, Entity* entity)
2026 {
2027  QString uid = "";
2028 
2029  if (entity->getAttribute("id") == id)
2030  return entity->getUniqueId();
2031 
2032  foreach(Entity* child, entity->getChildren())
2033  {
2034  QString result = getUidById(id, child);
2035 
2036  if (result != "")
2037  {
2038  uid = result;
2039  break;
2040  }
2041  }
2042 
2043  return uid;
2044 }
2045 
2046 QString QnstComposerPlugin::getUidByName(QString name, Entity* entity)
2047 {
2048  QString uid = "";
2049 
2050  if (entity->getAttribute("name") == name)
2051  return entity->getUniqueId();
2052 
2053  foreach(Entity* child, entity->getChildren())
2054  {
2055  QString result = getUidByName(name, child);
2056 
2057  if (result != "")
2058  {
2059  uid = result;
2060  break;
2061  }
2062  }
2063 
2064  return uid;
2065 }
2066 
2067 
2068 void QnstComposerPlugin::cacheNCLIds()
2069 {
2070  Entity *current;
2071  QString coreUID, structuralID, nclID;
2072 
2073  nclIDtoStructural.clear();
2074  previousCoreID.clear();
2075  foreach(coreUID, entities.keys())
2076  {
2077  structuralID = entities.value(coreUID);
2078  current = project->getEntityById(coreUID);
2079  if(current != NULL)
2080  {
2081  nclID = getNCLIdFromEntity(current);
2082  if(!nclID.isEmpty() && !nclID.isNull())
2083  {
2084  nclIDtoStructural.insert(nclID, structuralID);
2085  previousCoreID.push_back(coreUID);
2086  }
2087  }
2088  }
2089 }
2090 
2091 QString QnstComposerPlugin::insertNCLIDIfEmpty(Entity *entity)
2092 {
2093  const QString defaultID = "idBody000";
2094  QString id = entity->getAttribute("id");
2095  if(id.isEmpty() || id.isNull())
2096  {
2097  QMap <QString, QString> attrsTmp;
2098  QMap <QString, QString>::iterator begin, end, it;
2099  entity->getAttributeIterator(begin, end);
2100  for (it = begin; it != end; ++it)
2101  {
2102  attrsTmp.insert(it.key(), it.value());
2103  }
2104  attrsTmp.insert("id", defaultID); // \fixme this id should be unique
2105  emit setAttributes(entity, attrsTmp, false);
2106  return defaultID;
2107  }
2108  return id;
2109 }
2110 
2111 QString QnstComposerPlugin::getNCLIdFromEntity(Entity *entity)
2112 {
2113  QString nclID;
2114  if(entity != NULL)
2115  {
2116  if(entity->getType() == "body") // forces an ID if it not exists for body!
2117  nclID = insertNCLIDIfEmpty(entity);
2118 
2119  if(entity->hasAttribute("id"))
2120  nclID = entity->getAttribute("id");
2121  else if(entity->hasAttribute("name"))
2122  nclID = entity->getAttribute("name");
2123 
2124  else if(entity->hasAttribute("alias"))
2125  nclID = entity->getAttribute("alias");
2126  else
2127  nclID = QUuid::createUuid().toString();
2128 
2129  // This nclId will contains its id (or name) and all the perspective of an
2130  // element.
2131  Entity *parent = entity->getParent();
2132  while(parent != NULL && parent->hasAttribute("id"))
2133  {
2134  nclID = parent->getAttribute("id") + "#" + nclID;
2135  parent = parent->getParent();
2136  }
2137  }
2138  return nclID;
2139 }
2140 
2141 bool QnstComposerPlugin::isEntityHandled(Entity *entity)
2142 {
2143  if(entity != NULL)
2144  {
2145  QString type = entity->getType();
2146 
2147  // \todo This could be a map or an array
2148  if(type == "body" || type == "context" || type == "media" ||
2149  type == "switch" || type == "port" || type == "link" || type == "bind" ||
2150  type == "area" || type == "property" || type == "causalConnector" ||
2151  type == "switchPort" || type == "mapping" || type == "importBase"||
2152  type == "bindParam" || type == "connectorParam" ||
2153  type == "simpleCondition" || type == "simpleAction")
2154 
2155  return true;
2156  }
2157  return false;
2158 }
2159 
2160 void QnstComposerPlugin::syncNCLIdsWithStructuralIds()
2161 {
2162  QMap <QString, QString> nclIDtoCoreID;
2163  QList <QString> nclCoreID_Ordered, alreadyUpdatedCoreId;
2164  QStack <Entity*> stack;
2165  Entity *currentEntity;
2166  QString currentNCLId;
2167 
2168  QString nclID, structuralID, coreID;
2169 
2170  // I will keep all nclIDs -> coreIDs that I'm interested in nclIDtoCoreID map.
2171  stack.push(project);
2172  while(stack.size())
2173  {
2174  currentEntity = stack.front();
2175  stack.pop_front();
2176 
2177  currentNCLId = getNCLIdFromEntity(currentEntity);
2178 
2179  if(isEntityHandled(currentEntity) &&
2180  !currentNCLId.isEmpty() && !currentNCLId.isNull())
2181  {
2182  nclIDtoCoreID.insert(currentNCLId, currentEntity->getUniqueId());
2183  nclCoreID_Ordered.push_back(currentEntity->getUniqueId());
2184  }
2185 
2186  QVector<Entity *> children = currentEntity->getChildren();
2187  for(int i = 0; i < children.size(); i++)
2188  {
2189  stack.push_back(children.at(i));
2190  }
2191  }
2192 
2193 // qDebug() << "#### nclIDtoCoreID " << nclCoreID_Ordered;
2194 // qDebug() << "#### previousCoreID " << previousCoreID;
2195 
2196  foreach(coreID, nclCoreID_Ordered)
2197  {
2198  if(previousCoreID.contains(coreID)) // if previousCoreID is still in the core
2199  {
2200  currentEntity = project->getEntityById(coreID);
2201  if(currentEntity != NULL)
2202  {
2203 // if(dirtyEntities.contains(currentEntity->getUniqueId()))
2204  requestEntityChange(currentEntity); //just update it
2205 
2206  alreadyUpdatedCoreId.push_back(coreID);
2207  }
2208  }
2209  }
2210 
2211 // qDebug() << "Entities before sync" << entities;
2212 // qDebug() << "nclIDtoCoreID" << nclIDtoCoreID.keys();
2213 // qDebug() << "nclIDtoStructural" << nclIDtoStructural.keys();
2214  //for each old entity that are in the structural (not necessarily in the core)
2215  foreach (nclID, nclIDtoStructural.keys())
2216  {
2217  structuralID = nclIDtoStructural.value(nclID);
2218  if(nclIDtoCoreID.contains(nclID))
2219  {
2220  // gets the new coreId for currentStructuralId
2221  coreID = nclIDtoCoreID.value(nclID);
2222 
2223  if(alreadyUpdatedCoreId.contains(coreID))// this entity is already up to date.
2224  continue;
2225 
2226  // remove the previous mention to coreID
2227  entities.remove(entities.key(structuralID));
2228  // update the map with the new coreID
2229  entities[coreID] = structuralID;
2230  currentEntity = project->getEntityById(coreID);
2231  if(currentEntity != NULL)
2232  {
2233  requestEntityChange(currentEntity);
2234  alreadyUpdatedCoreId.push_back(coreID);
2235  }
2236  }
2237  else
2238  {
2239  if(alreadyUpdatedCoreId.contains(entities.key(structuralID)))
2240  continue;
2241 
2242  // keep track of all entities that must be removed from structural
2243  view->removeEntity(structuralID);
2244  entities.remove(entities.key(structuralID));
2245  }
2246  }
2247 
2248  // search for the entities that are in the core, but not in the structural
2249  // view
2250  for(int i = 0; i < nclCoreID_Ordered.size(); i++)
2251  {
2252  coreID = nclCoreID_Ordered.at(i);
2253  if(alreadyUpdatedCoreId.contains(coreID))// this entity is already up to date.
2254  continue;
2255 
2256  currentEntity = project->getEntityById(coreID);
2257  if(!entities.contains(coreID) && currentEntity != NULL)
2258  {
2259  requestEntityAddition(currentEntity);
2260  }
2261  }
2262 
2263 // qDebug() << "Entities after sync" << entities;
2264 }
2265 
2266 void QnstComposerPlugin::textualStartSync(QString, void*)
2267 {
2268  // qDebug() << "QnstComposerPlugin::textualStartSync";
2269  // cacheNCLIds();
2270  dirtyEntities.clear();
2271  isSyncingFromTextual = true;
2272 }
2273 
2274 void QnstComposerPlugin::textualFinishSync(QString, void*)
2275 {
2276  qDebug() << "QnstComposerPlugin::textualFinishSync";
2277  isSyncingFromTextual = false;
2278  // syncNCLIdsWithStructuralIds();
2279  updateFromModel();
2280 }
2281 
2282 void QnstComposerPlugin::clearValidationError(QString, void *param)
2283 {
2284  view->clearValidationErrors();
2285 }
2286 
2287 void QnstComposerPlugin::validationError(QString pluginID, void *param)
2288 {
2289  if(isSyncingFromTextual)
2290  return;
2291 
2292  if(param)
2293  {
2294  pair <QString, QString> *p = (pair <QString, QString> *)param;
2295 
2296  if (entities.contains(p->first))
2297  view->markError(entities.value(p->first), p->second);
2298  }
2299 }