applicationview.cpp
1 /*
2  name: tools/editor/applicationview.cpp
3 
4  This file is part of ARCS - Augmented Reality Component System
5  (version 2-current), written by Jean-Yves Didier
6  for IBISC Laboratory (http://www.ibisc.univ-evry.fr)
7 
8  Copyright (C) 2013 Université d'Evry-Val d'Essonne
9 
10  This program is free software: you can redistribute it and/or modify
11  it under the terms of the GNU General Public License as published by
12  the Free Software Foundation, either version 2 of the License, or
13  (at your option) any later version.
14 
15  This program is distributed in the hope that it will be useful,
16  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  GNU General Public License for more details.
19 
20  You should have received a copy of the GNU General Public License
21  along with this program. If not, see <http://www.gnu.org/licenses/>.
22 
23 
24  Please send bugreports with examples or suggestions to
25  jean-yves.didier__at__ibisc.univ-evry.fr
26 */
27 
28 
29 #include "applicationview.h"
30 #include <QVBoxLayout>
31 #include <QLabel>
32 #include <QComboBox>
33 #include <QMenu>
34 #include <QTreeWidget>
35 #include <QFileDialog>
36 #include <QMessageBox>
37 #include <QInputDialog>
38 
39 #include <QDrag>
40 #include <QMimeData>
41 
42 
43 #include <arcs/arcsfactory.h>
44 
45 #include "newcomponentdialog.h"
46 #include "editcomponentwidget.h"
47 #include "applicationitems.h"
48 #include "sheetview.h"
49 
50 ApplicationView::ApplicationView(ARCSApplicationComponent *aac, QWidget *parent) :
51  QDockWidget("Application view", parent)
52 {
53  if (aac)
54  application = aac;
55  else
56  application = new ARCSApplicationComponent();
57 
58  setProperty("appId", reinterpret_cast<quint64>(application) );
59 
60  connect(this,SIGNAL(addWidget(QWidget*)),parent,SLOT(addNewTabWidget(QWidget*)));
61 
62  setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
63  setFloating(false);
64  //application = new ARCSApplicationComponent();
65 
66  setWidget(new QWidget());
67  QVBoxLayout* vl = new QVBoxLayout();
68  widget()->setLayout(vl);
69  vl->addWidget(new QLabel("Application mode :"));
70 
71 
72  modeList= new QComboBox(this);
73  modeList->addItem("Base",QVariant(ARCS::ARCS_APP_BASE));
74  modeList->addItem("Event",QVariant(ARCS::ARCS_APP_EVENT));
75  modeList->addItem("Thread",QVariant(ARCS::ARCS_APP_THREAD));
76  modeList->addItem("Thread event",QVariant(ARCS::ARCS_APP_THREADEVENT));
77  modeList->addItem("Gui",QVariant(ARCS::ARCS_APP_GUI));
78 
79  vl->addWidget(modeList);
80  modeList->setCurrentIndex(0);
81 
82  connect(modeList,SIGNAL(currentIndexChanged(int)),this,SLOT(setApplicationMode(int)));
83 
84  buildTreeView();
85  vl->addWidget(treeView);
86 
87 
88  connect(treeView,SIGNAL(itemPressed(QTreeWidgetItem*,int)),this,SLOT(handleTreeViewClic(QTreeWidgetItem*,int)));
89  connect(treeView,SIGNAL(itemDoubleClicked(QTreeWidgetItem*,int)),this,SLOT(handleTreeViewDoubleClic(QTreeWidgetItem*,int)));
90 
91  selectedCandidate = 0;
92  updateApplication();
93 }
94 
95 ApplicationView::~ApplicationView()
96 {
97  // Here application view is closed.
98  emit requestAppIdDestroy(property("appId"));
99 }
100 
101 
103 {
104  if (application->getCurrentMode() == ARCS::ARCS_APP_NONE)
105  application->setCurrentMode(ARCS::ARCS_APP_EVENT);
106 
107  if (application->getProcessCount() == 0)
108  {
109  // il faut ajouter à l'application un process.
111  ARCSProcess* prc = new ARCSProcess();
112  prc->setContext(application->getContext());
113  application->addProcess(prc);
114  processList->addChild(new ProcessItem());
115  }
116  else
117  {
118  int i,j,k;
119  // we should get all components.
120  QStringList components = application->getContext()->getComponentList();
121 
122  componentList->takeChildren();
123  processList->takeChildren();
124 
125 
126  for(i=0; i < components.count(); i++)
127  {
128  QTreeWidgetItem* cItem = new ComponentItem(components[i],application->getContext()->getComponent(components[i])->getType());
129  componentList->addChild(cItem);
130  }
131  componentList->sortChildren(0,Qt::AscendingOrder);
132 
134 
135  // then we should get all processes.
136  k = application->getProcessCount();
137  for (i=0; i< k;i++)
138  {
139  ARCSProcess* proc = application->getProcess(i);
140  ProcessItem* procItem = new ProcessItem() ;
141  processList->addChild(procItem);
142  procItem->setController(proc->getControllerId());
143 
144  QStringList sheets = proc->getSheetNames();
145  for (j=0; j < sheets.count(); j++)
146  {
147  procItem->addChild(new SheetItem(sheets[j]));
148  }
149  }
150  }
151  treeView->expandAll();
152  modeList->setCurrentIndex(modeList->findData(QVariant(application->getCurrentMode())));
153 
154 }
155 
156 void ApplicationView::setApplicationMode(int mode)
157 {
158  application->setCurrentMode(static_cast<ARCS::ARCSAppFlag>(modeList->itemData(mode).toInt()));
159 }
160 
161 
162 void ApplicationView::buildTreeView()
163 {
164  treeView = new QTreeWidget(this);
165  treeView->setHeaderLabel("application");
166 
167  QTreeWidgetItem* appItem = new QTreeWidgetItem(QStringList("application"));
168  appItem->setIcon(0,QIcon(":icons/document-open-remote.png"));
169  QTreeWidgetItem* ctxItem = new QTreeWidgetItem(QStringList("context"));
170  appItem->addChild(ctxItem);
171  processList = new QTreeWidgetItem(QStringList("processes"));
172  appItem->addChild(processList);
173  processList->setIcon(0,QIcon(":icons/system-run.png"));
174 
175  componentList = new QTreeWidgetItem(QStringList("components"));
176  componentList->setIcon(0,QIcon(":icons/code-block.png"));
177  ctxItem->addChild(componentList);
178  QTreeWidgetItem* constantList = new QTreeWidgetItem(QStringList("constants"));
179  ctxItem->addChild(constantList);
180  constantList->setIcon(0,QIcon(":icons/irc-join-channel.png"));
181 
182  treeView->insertTopLevelItem(0,appItem);
183 
184 
185 
186 
187  // fondamentalement les actions devraient être effectivement groupées de manière différente
188  // par rapport au treeview.
189 
190  //QMenu* menu = new QMenu(treeView);
191  QAction* actionDefault = new QAction("Set as active application",this);
192  connect(actionDefault, SIGNAL(triggered()),this,SLOT(requestDefaultOwnership()));
193  QAction* action = new QAction("Add library",this);
194  connect(action,SIGNAL(triggered()),this,SLOT(addLibrary()));
195  QAction* action2 = new QAction("Add component",this);
196  connect(action2,SIGNAL(triggered()),this,SLOT(addComponent()));
197  removeComponentAction = new QAction("Remove component",this);
198  connect(removeComponentAction,SIGNAL(triggered()),this,SLOT(removeComponent()));
199  renameComponentAction = new QAction("Rename component...",this);
200  connect(renameComponentAction,SIGNAL(triggered()),this,SLOT(renameComponent()));
201  editComponentAction = new QAction("Edit component",this);
202  connect(editComponentAction,SIGNAL(triggered()),this,SLOT(editComponent()));
203  QAction* action3 = new QAction("Add process",this);
204  connect(action3,SIGNAL(triggered()),this,SLOT(addProcess()));
205  attachControllerAction = new QAction("Attach controller...",this);
206  connect(attachControllerAction,SIGNAL(triggered()),this,SLOT(attachController()));
207 
208  addSheetAction = new QAction("Add sheet",this);
209  connect(addSheetAction,SIGNAL(triggered()),this,SLOT(addSheet()));
210  editSheetAction = new QAction("Edit sheet",this);
211  connect(editSheetAction, SIGNAL(triggered()),this,SLOT(editSheet()));
212  removeSheetAction = new QAction("Remove sheet",this);
213  connect(removeSheetAction, SIGNAL(triggered()),this,SLOT(removeSheet()));
214  renameSheetAction = new QAction("Rename sheet",this);
215  connect(renameSheetAction, SIGNAL(triggered()),this,SLOT(renameSheet()));
216 
217  moveProcessUpAction= new QAction("Move Process up", this);
218  connect(moveProcessUpAction,SIGNAL(triggered()),this,SLOT(moveProcessUp()));
219  moveProcessDownAction= new QAction("Move Process down", this);
220  connect(moveProcessDownAction,SIGNAL(triggered()),this,SLOT(moveProcessDown()));
221 
222  removeProcessAction= new QAction("Delete Process", this);
223  connect(removeProcessAction,SIGNAL(triggered()),this,SLOT(removeProcess()));
224 
225  sheetSeparatorAction = new QAction(this);
226  sheetSeparatorAction->setSeparator(true);
227 
228  processSeparatorAction = new QAction(this);
229  processSeparatorAction->setSeparator(true);
230 
231  componentSeparatorAction = new QAction(this);
232  componentSeparatorAction->setSeparator(true);
233 
234 
235  treeView->addAction(actionDefault);
236  treeView->addAction(action);
237  treeView->addAction(action2);
238  treeView->addAction(processSeparatorAction);
239  treeView->addAction(moveProcessUpAction);
240  treeView->addAction(moveProcessDownAction);
241  treeView->addAction(removeProcessAction);
242  treeView->addAction(componentSeparatorAction);
243  treeView->addAction(renameComponentAction);
244  treeView->addAction(removeComponentAction);
245  treeView->addAction(editComponentAction);
246  treeView->addAction(attachControllerAction);
247  treeView->addAction(action3);
248  treeView->addAction(addSheetAction);
249  treeView->addAction(sheetSeparatorAction);
250  treeView->addAction(editSheetAction);
251  treeView->addAction(renameSheetAction);
252  treeView->addAction(removeSheetAction);
253  /*editComponentAction->setVisible(false);
254  removeComponentAction->setVisible(false);
255  moveProcessUpAction->setVisible(false);
256  moveProcessDownAction->setVisible(false);
257  removeProcessAction->setVisible(false);
258  removeSheetAction->setVisible(false);*/
259 
260  treeView->setContextMenuPolicy(Qt::ActionsContextMenu);
261  //items.append();
262 }
263 
264 void ApplicationView::addLibrary()
265 {
266  QString res = QFileDialog::getOpenFileName(this,"Get a library",QString(),QString("*.so"));
267  if (res.isEmpty())
268  return ;
269 
270  /*bool loaded =*/ ARCSFactory::getInstance()->loadLibrary(res);
271 
272  //if (!loaded)
273 
274  /* QList<QTreeWidgetItem*> items = treeView->findItems("context",Qt::MatchExactly) ;
275  if (items.count() == 0)
276  {
277  QMessageBox::critical(this,"Pas d'élément library ","");
278  return ;
279  }
280  items.at(0)->addChild(new QTreeWidgetItem(QStringList(res)));*/
281 }
282 
283 
284 
286 {
287  NewComponentDialog dlg(application->getContext(),this);
288  if (dlg.exec())
289  {
290  QTreeWidgetItem* cItem = new ComponentItem(dlg.getName(),dlg.getType());
291  componentList->addChild(cItem);
292  componentList->sortChildren(0,Qt::AscendingOrder);
293 
295 
296  ARCSContext* ctx = application->getContext();
297  ctx->createComponent(dlg.getName(),dlg.getType());
298  }
299 }
300 
301 
302 void ApplicationView::handleTreeViewClic(QTreeWidgetItem *item, int /*column*/)
303 {
304  selectedCandidate = item;
305  bool status;
306 
307  status = (item->type() == ComponentItem::Type) ;
308  componentSeparatorAction->setVisible(status);
309  removeComponentAction->setVisible(status);
310  editComponentAction->setVisible(status);
311  renameComponentAction->setVisible(status);
312 
313  if (status)
314  {
315  // voir pour mettre un drag en place.
316  QDrag *drag = new QDrag(this);
317  QMimeData *mimeData = new QMimeData;
318 
319  /* a voir en fonction des données à transférer */
320  mimeData->setText(selectedCandidate->text(1));
321  drag->setMimeData(mimeData);
322  /*Qt::DropAction dropAction =*/ drag->exec();
323  }
324 
325  status = (item->type() == ProcessItem::Type) ;
326  processSeparatorAction->setVisible(status);
327  attachControllerAction->setVisible(status);
328  addSheetAction->setVisible(status);
329  moveProcessUpAction->setVisible(status);
330  moveProcessDownAction->setVisible(status);
331  removeProcessAction->setVisible(status);
332 
333  status = (item->type() == SheetItem::Type);
334  sheetSeparatorAction->setVisible(status);
335  editSheetAction->setVisible(status);
336  removeSheetAction->setVisible(status);
337  renameSheetAction->setVisible(status);
338 
339 
340 
341 }
342 
343 
344 void ApplicationView::handleTreeViewDoubleClic(QTreeWidgetItem* item, int /*column*/)
345 {
346  selectedCandidate = item;
347 
348  if (item->type() == SheetItem::Type)
349  editSheet();
350 
351  if (item->type() == ComponentItem::Type)
352  editComponent();
353 
354 }
355 
356 
357 
358 void ApplicationView::removeComponent()
359 {
360  if (selectedCandidate)
361  {
362  ComponentItem* ci = dynamic_cast<ComponentItem*> (selectedCandidate);
363  if (ci)
364  {
365  application->removeComponent(ci->getName());
366  emit requestUpdate();
368  }
369  delete selectedCandidate;
370  }
371 }
372 
373 void ApplicationView::renameComponent()
374 {
375  if (selectedCandidate)
376  {
377  ComponentItem* ci = dynamic_cast<ComponentItem*> (selectedCandidate);
378  if (ci)
379  {
380  QString newName;
381  do
382  {
383  newName = QInputDialog::getText(this,"Rename Component",
384  "Please give a new name to the component. \n (Be aware that if you choose a name that already exists, we will ask you again to pick a new name)");
385  }
386  while(application->getContext()->getComponentList().contains(newName));
387 
388  if (newName.isEmpty())
389  return ;
390 
391 
392 
393  if (application->getContext()->renameComponent(ci->getName(),newName))
394  {
395  emit requestUpdate();
397  }
398  }
399  }
400 }
401 
402 
403 void ApplicationView::editComponent()
404 {
405  if (selectedCandidate)
406  {
407  ComponentItem* ci = dynamic_cast<ComponentItem*> (selectedCandidate);
408  if (ci)
409  {
410  ARCSContext* ctx = application->getContext();
411  ARCSAbstractComponent* aac = ctx->getComponent(ci->getName());
412  EditComponentWidget* ecw = new EditComponentWidget(aac,this);
413  ecw->setProperty("appId",this->property("appId"));
414  emit addWidget(ecw);
415  }
416  }
417 }
418 
419 
420 
421 void ApplicationView::addProcess()
422 {
423  processList->addChild(new ProcessItem());
424 }
425 
426 void ApplicationView::removeProcess()
427 {
428  if (selectedCandidate)
429  {
430  ProcessItem* pi = dynamic_cast<ProcessItem*>(selectedCandidate);
431  if (pi)
432  {
433  int idx = processList->indexOfChild(selectedCandidate);
434  application->removeProcess(idx);
435  processList->removeChild(selectedCandidate);
436  }
437  }
438 }
439 
440 void ApplicationView::closeEvent(QCloseEvent *event)
441 {
442  QDockWidget::closeEvent(event);
443  deleteLater();
444 }
445 
446 
447 void ApplicationView::attachController()
448 {
449  if (selectedCandidate)
450  {
451  ProcessItem* pi = dynamic_cast<ProcessItem*>(selectedCandidate);
452  if (pi)
453  {
454  ARCSContext* ctx = application->getContext();
455  QStringList components = ctx->getComponentList();
456  QStringList controllers;
457  for (int i=0; i < components.count(); i++)
458  {
459  ARCSAbstractComponent* aac = ctx->getComponent(components[i]);
460  if ( aac->getType() == "StateMachine" )
461  {
462  controllers << aac->getProperty("id").toString();
463  }
464  }
465  if (!controllers.count())
466  {
467  QMessageBox::information(this,"Controllers not found","Controllers not found");
468  return ;
469  }
470  bool ok;
471  QString res = QInputDialog::getItem(this,"Attaching a controller","Please pick one controller in the list below",controllers,0,false,&ok);
472  if (ok && !res.isEmpty())
473  {
474  pi->setController(res);
475  // here we are missing informations about the process
476  int idx=0;
477  while ( processList->child(idx) != pi ) { idx++; }
478  application->getProcess(idx)->setController(res);
479  }
480  }
481  }
482 }
483 
484 
485 void ApplicationView::editSheet()
486 {
487  if (selectedCandidate)
488  {
489  SheetItem* ci = dynamic_cast<SheetItem*> (selectedCandidate);
490  if (ci)
491  {
492  //ARCSContext* ctx = application->getContext();
493  //ARCSAbstractComponent* aac = ctx->getComponent(ci->getName());
494  ProcessItem* pi = dynamic_cast<ProcessItem*> (ci->parent());
495  // first, look for process id.
496  int idx=0;
497  // might go out of bounds if not correctly checked.
498  while ( processList->child(idx) != pi ) { idx++; }
499  ARCSProcess* process = application->getProcess(idx);
500 
501  ARCSSheet& st = process->getSheet(ci->getName());
502  SheetView * sv = new SheetView(st, this);
503  sv->setWindowTitle("Sheet: " + st.getName());
504  sv->setProperty("appId",this->property("appId"));
505  connect(sv,SIGNAL(requestApplicationUpdate()), this, SLOT(updateApplication()));
506  connect(this,SIGNAL(requestUpdate()),sv,SLOT(updateSheet()));
507  emit addWidget(sv);
508 
509  }
510  }
511 }
512 
514 {
515  if (selectedCandidate)
516  {
517  SheetItem* si = dynamic_cast<SheetItem*>(selectedCandidate);
518  if (si)
519  {
520  ProcessItem* pi = dynamic_cast<ProcessItem*> (si->parent());
521  // first, look for process id.
522  int idx=processList->indexOfChild(pi);
523  ARCSProcess* process = application->getProcess(idx);
524  QStringList sheetList = process->getSheetNames();
525 
526  QString newSheetName;
527  do
528  {
529  newSheetName = QInputDialog::getText(this,"Rename Sheet",
530  "Please give a new name to the sheet. \n (Be aware that if you choose a name that already exists, we will ask you again to pick a new name)");
531  }
532  while(sheetList.contains(newSheetName));
533  if (newSheetName.isEmpty())
534  return ;
535 
536  // we should ask for deletion of widgets with this sheet name.
537  emit requestWidgetDestroy(property("appId"),"Sheet: " + si->getName());
538  //process
539  //process->removeSheet(si->getName());
540  QString oldSheetName = si->getName();
541  process->renameSheet(oldSheetName, newSheetName);
542  si->setName(newSheetName);
543 
545 
546  // first we should obtain the controller.
547  // then we have to look if this controller is shared: it may be a source of troubles.
548  // if it is the case, then we will warn the user.
549  // in the other case, we just should rename sheet in transitions.
550  QString controllerName = pi->getController();
551 
552  if (controllerName.isEmpty())
553  return ;
554 
555  int controllerShared = 0;
556  for (int i=0; i< application->getProcessCount(); i++)
557  {
558  if (application->getProcess(i)->getControllerId() == controllerName)
559  controllerShared++;
560  }
561 
562  if (controllerShared > 1)
563  {
564  if ( QMessageBox::question(this,"Shared controller",
565  "The sheet you renamed is referenced in the process controller, which is shared.\n" \
566  "Would you like to apply changes in the controller anyway ?",
567  QMessageBox::Yes,QMessageBox::No) == QMessageBox::No)
568  return;
569  }
570  ARCSControllerComponent* acc = process->getController();
571  acc->getStateMachine()->renameSheet(oldSheetName,newSheetName );
572  }
573  }
574 
575 }
576 
577 void ApplicationView::removeSheet()
578 {
579  if (selectedCandidate)
580  {
581  SheetItem* si = dynamic_cast<SheetItem*>(selectedCandidate);
582  if (si)
583  {
584  ProcessItem* pi = dynamic_cast<ProcessItem*> (si->parent());
585  // first, look for process id.
586  int idx=pi->indexOfChild(si);
587  ARCSProcess* process = application->getProcess(idx);
588 
589  // we should ask for deletion of widgets with this sheet name.
590  emit requestWidgetDestroy(property("appId"),"Sheet: " + si->getName());
591  process->removeSheet(si->getName());
592  pi->removeChild(si);
593  }
594  }
595 }
596 
597 void ApplicationView::moveProcessUp()
598 {
599  if(selectedCandidate)
600  {
601  ProcessItem* pi = dynamic_cast<ProcessItem*>(selectedCandidate);
602  if (pi)
603  {
604  int idx=processList->indexOfChild(selectedCandidate);
605 
606  if (idx > 0)
607  {
608  QTreeWidgetItem* item = processList->takeChild(idx);
609  processList->insertChild(idx-1,item);
610  application->swapProcesses(idx,idx-1);
611  }
612  }
613  }
614 }
615 
616 
617 
618 void ApplicationView::moveProcessDown()
619 {
620  if(selectedCandidate)
621  {
622  ProcessItem* pi = dynamic_cast<ProcessItem*>(selectedCandidate);
623  if (pi)
624  {
625  int idx=processList->indexOfChild(selectedCandidate);
626 
627  if (idx < processList->childCount()-1 )
628  {
629  QTreeWidgetItem* item = processList->takeChild(idx);
630  processList->insertChild(idx+1,item);
631  application->swapProcesses(idx,idx+1);
632  }
633  }
634  }
635 }
636 
637 void ApplicationView::addSheet()
638 {
639  if (selectedCandidate)
640  {
641  ProcessItem* pi = dynamic_cast<ProcessItem*>(selectedCandidate);
642  if (pi)
643  {
644  // first, look for process id.
645  int idx=0;
646  // might go out of bounds if not correctly checked.
647  while ( processList->child(idx) != selectedCandidate ) { idx++; }
648  ARCSProcess* process = application->getProcess(idx);
649 
650 
651  bool ok;
652  QString sheetName;
653  do {
654  sheetName = QInputDialog::getText(this,"Adding a new sheet", "Please give a sheet name", QLineEdit::Normal, QString(), &ok );
655  if (!ok)
656  return;
657 
658  if (process->getSheetNames().contains(sheetName))
659  {
660  ok = false;
661  QMessageBox::critical(this,"Sheet name error","This sheet name already exists for this component",QMessageBox::Ok,0);
662  }
663 
664  } while (!ok);
665  std::cout << "context pointer" << application->getContext() << std::endl;
666  ARCSSheet sheet(application->getContext());
667  sheet.setName(sheetName);
668 
669  process->addSheet(sheetName,sheet);
670 
671  pi->addChild(new SheetItem(sheetName));
672 
673  }
674 
675  }
676 
677 
678 }
QStringList getSheetNames()
Definition: arcsprocess.h:94
For applications running with Qt Widgets.
Definition: arcs.h:48
QString getName()
Definition: arcssheet.h:246
void renameSheet(QString oldName, QString newName)
This class represents an application.
This class is representing a process under ARCS.
Definition: arcsprocess.h:52
void setCurrentMode(ARCS::ARCSAppFlag flag)
QStringList getComponentList()
void removeSheet(QString s)
void setContext(ARCSContext *ctx)
Definition: arcsprocess.h:61
static ARCSFactory * getInstance()
Returns the instance of the singleton ARCSFactory.
None of the application mode has been selected so far.
Definition: arcs.h:43
bool setController(QString s=QString::null)
void addProcess(ARCSProcess *ap)
void renameSheet(QString oldName, QString newName)
Renames a sheet in the set of transitions.
QVariant getProperty(QString name)
Gets a meta-property from this component.
ARCS::ARCSAppFlag getCurrentMode()
For applications nested in a thread.
Definition: arcs.h:46
Defines a controller component.
Class handling the generic description of a component.
ARCSStateMachine * getStateMachine()
ARCSAbstractComponent * getComponent(QString name)
Retrieves a component by its id.
This class manages components and constants in a given context.
Definition: arcscontext.h:45
bool loadLibrary(QString path)
Loads a library given the path to it.
ARCSProcess * getProcess(int idx)
ARCSControllerComponent * getController()
Definition: arcsprocess.h:135
void removeProcess(int i)
Removes a process in the list of processes managed by the application.
void setName(QString s)
Definition: arcssheet.h:244
ARCSSheet & getSheet(QString s)
Definition: arcsprocess.h:86
For applications nested in a thread running with an event loop.
Definition: arcs.h:47
For applications requiring event loops.
Definition: arcs.h:45
Maintains connections between objects.
Definition: arcssheet.h:48
For basic applications.
Definition: arcs.h:44
QString getControllerId()
Definition: arcsprocess.h:96
void addSheet(QString s, ARCSSheet sh)