00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <QVDesignerGUI>
00024 #include <QVApplication>
00025 #include <QVPropertyContainer>
00026 #include <QVPropertyContainerChange>
00027 #include <QVMPlayerCamera>
00028 #include <QVCameraWorker>
00029 #include <QVWorker>
00030 #include <QVImageCanvas>
00031 #include <QXmlStreamWriter>
00032 #include <QXmlStreamReader>
00033 #include <qvgui/qvplot.h>
00034 #include <qvgui/qvdesigner/facade/workerdialog.h>
00035 #include <qvgui/qvdesigner/facade/cameradialog.h>
00036 #include <qvgui/qvdesigner/facade/imagecanvasdialog.h>
00037 #include <qvgui/qvdesigner/facade/cameraworkerdialog.h>
00038
00039 QVDesignerGUI::QVDesignerGUI(): QObject(), factory(), slate(this), informer(&slate)
00040 {
00041 qDebug() << "QVDesignerGUI::QVDesignerGUI()";
00042 if (qvApp == NULL)
00043 {
00044 QString str = "QVDesignerGUI::QVDesignerGUI(): the SlateGUI cannot be created before the QVApplication instance. Aborting now.";
00045 std::cerr << qPrintable(str) << std::endl;
00046 exit(1);
00047 }
00048
00049
00050 if (qvApp->forHelp()) return;
00051
00052 connect(&slate, SIGNAL(closed()), this, SLOT(quit()));
00053
00054 qvApp->registerGUI(this);
00055 qvApp->setTerminateOnLastWorker(false);
00056
00057
00058
00059
00060
00061 qDebug() << "QVDesignerGUI::QVDesignerGUI() <~ return";
00062 }
00063
00064 void QVDesignerGUI::init()
00065 {
00066
00067 foreach(QVPropertyContainer* qvp, qvApp->getQVPropertyContainers()) {
00068
00069 QVWorker* worker;
00070 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL) {
00071 QString registered = factory.registerUserWorker(worker);
00072 if (!registered.isEmpty())
00073 slate.includeItemType(registered);
00074 }
00075
00076
00077 QString type = factory.containerType(qvp);
00078 QString name = qvp->getName();
00079 uint id = qvp->getId();
00080
00081 initialContainers.insert(id, qvp);
00082 createdItems.insert(id, CreatedItem(type, name, id));
00083
00084 connect(qvp->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));
00085 slate.addItemNode(type, name, id, new ItemProperties(type, qvp));
00086
00087 createDialog(id);
00088 }
00089
00090
00091 foreach(QVPropertyContainer* qvp, qvApp->getQVPropertyContainers()) {
00092 foreach(QString prop, qvp->getPropertyList()) {
00093 QVPropertyContainer *source = qvp->getSourceContainer(prop);
00094 QString sourceProp = qvp->getSourceProperty(prop);
00095 bool sync = qvp->isSynchronous(prop);
00096 bool sequ = qvp->isSequential(prop);
00097
00098 if ( (source != NULL) && (!sourceProp.isEmpty()) ) {
00099 QString fromId = QString("%1").arg(source->getId());
00100 QString fromProp = sourceProp;
00101 QString toId = QString("%1").arg(qvp->getId());
00102 QString toProp = prop;
00103 QString linkName = getLinkName(fromId, fromProp, toId, toProp);
00104 createdLinks.insert(linkName, CreatedLink(source->getId(), fromProp, qvp->getId(), toProp, sync, sequ));
00105 slate.addLinkLine(source->getId(), fromProp, qvp->getId(), toProp, sync, sequ);
00106
00107 }
00108 }
00109 }
00110
00111
00112 slate.arrangeItems();
00113 }
00114
00115 void QVDesignerGUI::show()
00116 {
00117 slate.show();
00118 }
00119
00120 QMap<QString, QList<QString> > QVDesignerGUI::getItemTypes() const
00121 {
00122 return factory.getItemTypes();
00123 }
00124
00125 QMap<QString, QList<QString> > QVDesignerGUI::getInputItemTypes() const
00126 {
00127 return factory.getInputItemTypes();
00128 }
00129
00130 QMap<QString, QList<QString> > QVDesignerGUI::getMiddleItemTypes() const
00131 {
00132 return factory.getMiddleItemTypes();
00133 }
00134
00135 QMap<QString, QList<QString> > QVDesignerGUI::getOutputItemTypes() const
00136 {
00137 return factory.getOutputItemTypes();
00138 }
00139
00140 uint QVDesignerGUI::addItem(QString type, QString name, uint lastId)
00141 {
00142
00143 QVPropertyContainer *cont = factory.createContainer(type, name);
00144 if (cont != 0) {
00145 containers.insert(cont->getId(), cont);
00146 createdItems.insert(cont->getId(), CreatedItem(type, name, cont->getId()));
00147
00148 connect(cont->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));
00149
00150 slate.addItemNode(type, name, cont->getId(), new ItemProperties(type, cont), lastId);
00151 return cont->getId();
00152 }
00153 return 0;
00154 }
00155
00156 bool QVDesignerGUI::setName(const uint id, const QString name)
00157 {
00158 if (containers.contains(id))
00159 containers.value(id)->setName(name);
00160 else if (initialContainers.contains(id))
00161 initialContainers.value(id)->setName(name);
00162 else
00163 return FALSE;
00164
00165 return TRUE;
00166 }
00167
00168 bool QVDesignerGUI::addLink(uint fromId, QString fromProp, uint toId, QString toProp, bool synchronous, bool sequential)
00169 {
00171 if (containers.contains(fromId) && containers.contains(toId)) {
00172 QVPropertyContainer *fromCont = containers.value(fromId);
00173 QVPropertyContainer *toCont = containers.value(toId);
00174
00175 QVCameraWorker *cameraWorker;
00176 QVPropertyContainer::LinkType linkType = QVWorker::AsynchronousLink;
00177 if (synchronous) linkType = QVWorker::SynchronousLink;
00178 if (sequential) linkType = QVWorker::SequentialLink;
00179
00180
00181 if((dynamic_cast<QVMPlayerCamera*>(fromCont)) != NULL)
00182 fromCont->linkProperty(toCont, toProp, linkType);
00183
00184 else if((cameraWorker = dynamic_cast<QVCameraWorker*>(fromCont)) != NULL)
00185 cameraWorker->linkProperty(toCont, toProp);
00186
00187 else if((dynamic_cast<QVImageCanvas*>(toCont)) != NULL)
00188 fromCont->linkProperty(fromProp, toCont, linkType);
00189
00190 else if((dynamic_cast<QVPlot*>(toCont)) != NULL)
00191 fromCont->linkProperty(fromProp, toCont, linkType);
00192
00193 else if(!fromCont->containsProperty(fromProp))
00194 fromCont->linkProperty(toCont, toProp, linkType);
00195
00196 else if(!toCont->containsProperty(toProp))
00197 fromCont->linkProperty(fromProp, toCont, linkType);
00198
00199 else
00200 fromCont->linkProperty(fromProp, toCont, toProp, linkType);
00201 }
00202 else
00203 return FALSE;
00204
00205 return TRUE;
00206 }
00207
00208 bool QVDesignerGUI::delItem(const uint id)
00209 {
00210 if (containers.contains(id)) {
00211
00212 factory.deleteContainer(containers.value(id));
00213 return true;
00214 }
00215 return false;
00216 }
00217
00218 bool QVDesignerGUI::delLink(const uint fromId, const QString fromProp, const uint toId, const QString toProp)
00219 {
00220 if (containers.contains(fromId) && containers.contains(toId))
00221 return containers.value(fromId)->unlinkProperty(fromProp, containers.value(toId), toProp);
00222 else
00223 return false;
00224 }
00225
00226 template <class Type> bool QVDesignerGUI::setProperty(const uint fromId, const QString fromProp, const Type &value)
00227 {
00228 return false;
00229 }
00230
00231 QString QVDesignerGUI::getLinkName(QVPropertyContainerChange change)
00232 {
00233 return getLinkName(QString("%1").arg(change.getOrigId()), change.getOrigProp(), QString("%1").arg(change.getDestId()), change.getDestProp());
00234 }
00235
00236 QString QVDesignerGUI::getLinkName(QString fromIdName, QString fromProp, QString toIdName, QString toProp)
00237 {
00238 return getAbsPropName(fromIdName, fromProp) + " => " + getAbsPropName(toIdName, toProp);
00239 }
00240
00241 QString QVDesignerGUI::getAbsPropName(QString fromIdName, QString fromProp)
00242 {
00243 return fromIdName + "[" + fromProp + "]";
00244 }
00245
00246
00247 void QVDesignerGUI::processChange(QVPropertyContainerChange change)
00248 {
00249 switch (change.getChangeType())
00250 {
00251 case QVPropertyContainerChange::Name:
00252 {
00253 uint id = change.getSourceId();
00254 QString name = change.getSourceName();
00255 if (createdItems.contains(id)) {
00256
00257 slate.setItemName(id, name);
00258 if (createdItems.contains(id)) createdItems[id].name = name;
00259 }
00260 }
00261 break;
00262
00263 case QVPropertyContainerChange::ContainerDel:
00264 {
00265 uint id = change.getSourceId();
00266 containers.remove(id);
00267 createdItems.remove(id);
00268 slate.delItemNode(id);
00269
00270
00271 deleteDialog(id);
00272
00273
00274 }
00275 break;
00276
00277 case QVPropertyContainerChange::PropertyAdd:
00278 if (createdItems.contains(change.getSourceId()))
00279 {
00280 uint srcId = change.getSourceId();
00281 QString propName = change.getPropName();
00282
00283 if (containers.contains(srcId))
00284 {
00285 QVPropertyContainer *cont = containers.value(srcId);
00286 int type = cont->getPropertyType(propName);
00287 bool in = cont->isInput(propName);
00288 bool out = cont->isOutput(propName);
00289 slate.addProperty(srcId, propName, type, in, out);
00290 }
00291
00292 }
00293 break;
00294
00295 case QVPropertyContainerChange::PropertyDel:
00296 if (createdItems.contains(change.getSourceId()))
00297 {
00298 uint srcId = change.getSourceId();
00299 QString propName = change.getPropName();
00300 slate.delProperty(srcId, propName);
00301
00302 }
00303 break;
00304
00305 case QVPropertyContainerChange::PropertyValue:
00306 break;
00307
00308 case QVPropertyContainerChange::LinkAdd:
00309 {
00310 uint fromId = change.getOrigId();
00311 QString fromProp = change.getOrigProp();
00312 uint toId = change.getDestId();
00313 QString toProp = change.getDestProp();
00314 QString linkName = getLinkName(change);
00315 if ( createdItems.contains(fromId) && createdItems.contains(toId) )
00316 {
00317 createdLinks.insert(linkName, CreatedLink(fromId, fromProp, toId, toProp, change.isSinc(), change.isSequ()));
00318 slate.addLinkLine(fromId, fromProp, toId, toProp, change.isSinc(), change.isSequ());
00319
00320 }
00321
00322
00323 }
00324 break;
00325
00326 case QVPropertyContainerChange::LinkDel:
00327 {
00328 uint fromId = change.getOrigId();
00329 QString fromProp = change.getOrigProp();
00330 uint toId = change.getDestId();
00331 QString toProp = change.getDestProp();
00332 QString linkName = getLinkName(change);
00333 if (createdLinks.contains(linkName))
00334 {
00335 createdLinks.remove(linkName);
00336 slate.delLinkLine(fromId, fromProp, toId, toProp);
00337
00338 }
00339 }
00340 break;
00341
00342 case QVPropertyContainerChange::All:
00343
00344 break;
00345
00346 default:
00347 break;
00348 }
00349 }
00350
00351
00352 void QVDesignerGUI::dialogChange(QVPropertyContainerChange change)
00353 {
00354 switch (change.getChangeType())
00355 {
00356 case QVPropertyContainerChange::PropertyValue:
00357 {
00358 uint dialogId = change.getSourceId();
00359 if (dialogsToContainers.contains(dialogId))
00360 {
00361 uint contId = dialogsToContainers.value(dialogId);
00362 QString prop = change.getPropName();
00363 propertyChanges.insert(getAbsPropName(QString("%1").arg(contId), prop), PropertyChange(contId, prop, change.getValue()));
00364 }
00365 break;
00366 }
00367
00368 default:
00369 break;
00370 }
00371 }
00372
00373 void QVDesignerGUI::showProperties(const uint id)
00374 {
00375 if (containers.contains(id)) {
00376 if (dialogs.contains(id)) {
00377 (dialogs.value(id))->show();
00378 }
00379 else {
00380 if (createDialog(id))
00381 (dialogs.value(id))->show();
00382 }
00383 }
00384 else if (initialContainers.contains(id)) {
00385 if (dialogs.contains(id)) {
00386 (dialogs.value(id))->show();
00387 }
00388 else {
00389 if (createDialog(id))
00390 (dialogs.value(id))->show();
00391 }
00392 }
00393 }
00394
00395 bool QVDesignerGUI::createDialog(const uint itemId)
00396 {
00397 QVPropertyContainer *cont;
00398 if (containers.contains(itemId))
00399 cont = containers.value(itemId);
00400 else if (initialContainers.contains(itemId))
00401 cont = initialContainers.value(itemId);
00402 else
00403 return false;
00404
00405 QVCameraWorker *cameraWorker;
00406 QVWorker* worker;
00407 QVMPlayerCamera* camera;
00408 QVImageCanvas* imageCanvas;
00409 if((cameraWorker = dynamic_cast<QVCameraWorker*>(cont)) != NULL) {
00410 CameraWorkerDialog *dialog = new CameraWorkerDialog(cameraWorker);
00411 dialogs.insert(itemId, dialog);
00412 dialogsToContainers.insert(dialog->getNodeId(), itemId);
00413 connect(dialog->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(dialogChange(QVPropertyContainerChange)));
00414 return true;
00415 }
00416 else if((worker = dynamic_cast<QVWorker*>(cont)) != NULL) {
00417 WorkerDialog *dialog = new WorkerDialog(worker);
00418 dialogs.insert(itemId, dialog);
00419 dialogsToContainers.insert(dialog->getNodeId(), itemId);
00420 connect(dialog->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(dialogChange(QVPropertyContainerChange)));
00421 return true;
00422 }
00423 else if((camera = dynamic_cast<QVMPlayerCamera*>(cont)) != NULL) {
00424 CameraDialog * dialog = new CameraDialog(camera);
00425 dialogs.insert(itemId, dialog);
00426 dialogsToContainers.insert(dialog->getNodeId(), itemId);
00427 connect(dialog->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(dialogChange(QVPropertyContainerChange)));
00428 return true;
00429 }
00430 else if((imageCanvas = dynamic_cast<QVImageCanvas*>(cont)) != NULL) {
00431 ImageCanvasDialog * dialog = new ImageCanvasDialog(imageCanvas);
00432 dialogs.insert(itemId, dialog);
00433 dialogsToContainers.insert(dialog->getNodeId(), itemId);
00434 connect(dialog->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(dialogChange(QVPropertyContainerChange)));
00435 return true;
00436 }
00437 return false;
00438 }
00439
00440 void QVDesignerGUI::deleteDialog(const uint itemId)
00441 {
00442
00443 if (dialogs.contains(itemId)) {
00444 delete dialogs.value(itemId);
00445 dialogs.remove(itemId);
00446 }
00447 }
00448
00449 void QVDesignerGUI::run()
00450 {
00451
00452 foreach (uint id, containers.keys()) {
00453 if (!dialogs.contains(id))
00454 createDialog(id);
00455 }
00456
00457
00458 qvApp->startItems();
00459 }
00460
00461 void QVDesignerGUI::stop()
00462 {
00463
00464 QList<CreatedItem> lastItems = createdItems.values();
00465 QList<CreatedLink> lastLinks = createdLinks.values();
00466 QMap<uint, uint> oldId_To_NewId;
00467 QList<GroupInfo> lastGroups = slate.getGroups();
00468
00469
00470 qvApp->quitItems();
00471
00472
00473 qApp->processEvents();
00474
00475
00476 foreach (QVPropertyContainer * cont, initialContainers) {
00477 uint id = cont->getId();
00478 slate.delItemNode(id);
00479 deleteDialog(id);
00480 createdItems.remove(id);
00481 }
00482 initialContainers.clear();
00483
00484
00485 slate.eraseGroups();
00486
00487
00488 foreach (QVPropertyContainer * cont, containers) {
00489 factory.deleteContainer(cont);
00490 }
00491 dialogsToContainers.clear();
00492 createdLinks.clear();
00493
00494
00495 foreach (CreatedItem item, lastItems) {
00496 uint newId = addItem(item.type, item.name, item.id);
00497 oldId_To_NewId.insert(item.id, newId);
00498 if (newId == 0) std::cerr << "QVDesignerGUI - resetItems(): error al crear el Item " + item.name.toStdString() + "\n";
00499 }
00500
00501
00502 foreach (CreatedLink link, lastLinks) {
00503 if (oldId_To_NewId.contains(link.fromId) && (oldId_To_NewId.value(link.fromId) > 0) &&
00504 oldId_To_NewId.contains(link.toId) && (oldId_To_NewId.value(link.toId) > 0) ) {
00505 if (!addLink(oldId_To_NewId.value(link.fromId), link.fromProp, oldId_To_NewId.value(link.toId), link.toProp, link.synchronous, link.sequential))
00506 std::cerr << "QVDesignerGUI - resetItems(): error al crear el Link " + QString("%1").arg(link.fromId).toStdString() + " -> " + QString("%1").arg(link.toId).toStdString() + "\n";
00507 }
00508 }
00509
00510
00511 for (QMap<QString, PropertyChange>::iterator it = propertyChanges.begin(); it != propertyChanges.end(); it++) {
00512 if ( oldId_To_NewId.contains(it.value().id) && (oldId_To_NewId.value(it.value().id) > 0) ) {
00513 it.value().id = oldId_To_NewId.value(it.value().id);
00514 QVPropertyContainer *cont = containers.value(it.value().id);
00515 QString prop = it.value().propName;
00516 QVariant value = it.value().value;
00517
00518 if (cont->isType<int>(prop))
00519 cont->setPropertyValue<int>(prop, value.value<int>());
00520 else if (cont->isType<bool>(prop))
00521 cont->setPropertyValue<bool>(prop, value.value<bool>());
00522 else if (cont->isType<double>(prop))
00523 cont->setPropertyValue<double>(prop, value.value<double>());
00524 else if (cont->isType<QString>(prop))
00525 cont->setPropertyValue<QString>(prop, value.value<QString>());
00526 else if (cont->isType<QVIndexedStringList>(prop))
00527 cont->setPropertyValue<QVIndexedStringList>(prop, value.value<QVIndexedStringList>());
00528 else
00529 std::cerr << "QVDesignerGUI - resetItems(): error al restaurar valor: " + getAbsPropName(QString("%1").arg(it.value().id), it.value().propName).toStdString() + "\n";
00530 }
00531 else
00532 std::cerr << "QVDesignerGUI - resetItems(): error al restaurar valor: " + getAbsPropName(QString("%1").arg(it.value().id), it.value().propName).toStdString() + "\n";
00533 }
00534
00536 createGroups(lastGroups, oldId_To_NewId);
00537 }
00538
00539 void QVDesignerGUI::createGroups(QList<GroupInfo> &lastGroups, QMap<uint, uint> &oldId_To_NewId) {
00540
00541 for (QList<GroupInfo>::iterator it = lastGroups.begin(); it != lastGroups.end(); it++) {
00542
00543 foreach (uint oldId, (*it).getNodes()) {
00544
00545 if (oldId_To_NewId.contains(oldId)) {
00546 (*it).updateNodeId(oldId, oldId_To_NewId.value(oldId));
00547
00548 }
00549
00550 }
00551 }
00552
00553 bool reloop = true;
00554 while (reloop) {
00555
00556 QMap<uint, uint> changes;
00557 QList<GroupInfo>::iterator it = lastGroups.begin();
00558 while (it != lastGroups.end()) {
00559 uint oldId = (*it).getId();
00560 uint newId = slate.createGroup(*it);
00561
00562 if (newId > 0) {
00563 changes.insert(oldId, newId);
00564 it = lastGroups.erase(it);
00565
00566 }
00567 else it++;
00568
00569 }
00570 foreach (uint idChanged, changes.keys()) {
00571 for (QList<GroupInfo>::iterator it = lastGroups.begin(); it != lastGroups.end(); it++)
00572 foreach (uint oldId, (*it).getSubgroups())
00573 if (oldId == idChanged)
00574 (*it).updateSubgroupId(idChanged, changes.value(idChanged));
00575 }
00576 reloop = !changes.isEmpty();
00577 }
00578 }
00579
00580 void QVDesignerGUI::quit()
00581 {
00582 qvApp->deregisterGUI();
00583 qvApp->quit();
00584 }
00585
00586
00587
00588
00589
00590
00591
00592
00593
00597
00598
00599 QString QVDesignerGUI::getCppText() const
00600 {
00601 QString result;
00602
00603
00604 result += "/*\n * Copyright (C) 2007, 2008, 2009. PARP Research Group.\n * <http://perception.inf.um.es>\n * University of Murcia, Spain.\n *\n * This file is part of the QVision library.\n *\n * QVision is free software: you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, version 3 of the License.\n *\n * QVision is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n * GNU Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with QVision. If not, see <http://www.gnu.org/licenses/>.\n */\n\n";
00605
00606
00607 result += "#include <QVApplication>\n#include <QVDefaultGUI>\n";
00608 QList<QString> types;
00609 foreach(CreatedItem item, createdItems.values()) {
00610 QString chopType = item.type;
00611 int espInd = chopType.indexOf(' ');
00612 int lesInd = chopType.indexOf('<');
00613 if ((espInd > 0) && (espInd < lesInd))
00614 types.append(chopType.left(espInd));
00615 else
00616 types.append(chopType.left(lesInd));
00617 }
00618 QSet<QString> unrepeatedTypes = types.toSet();
00619 foreach(QString unrepType, unrepeatedTypes) {
00620 if (factory.isUserType(unrepType))
00621 result += QString("class ") + unrepType + QString(";\n");
00622 else
00623 result += QString("#include <") + unrepType + QString(">\n");
00624 }
00625
00626 bool QVISLadded = FALSE;
00627 foreach(CreatedItem item, createdItems.values()) {
00628 foreach(PropertyChange change, propertyChanges.values()) {
00629 if ( (change.id == item.id) && (containers.value(item.id)->isType<QVIndexedStringList>(change.propName)) ) {
00630 result += QString("#include <QVIndexedStringList>\n");
00631 QVISLadded = TRUE;
00632 break;
00633 }
00634 }
00635 if (QVISLadded) break;
00636 }
00637
00638
00639 result += "\n#ifndef DOXYGEN_IGNORE_THIS\n\n";
00640 result += "int main(int argc, char *argv[])\n {\n QVApplication app(argc, argv, \"Example program for QVision library.\");\n\n";
00641
00642
00643 foreach(CreatedItem item, createdItems.values()) {
00644 result += QString(" ") + item.type + QString(" ") + item.name + QString("(\"") + item.name + QString("\");\n");
00645 }
00646 result += "\n QVDefaultGUI interface;\n\n";
00647
00648
00649 foreach(CreatedLink link, createdLinks.values()) {
00650 if (containers.contains(link.fromId) && containers.contains(link.toId)) {
00651 QVPropertyContainer *fromCont = containers.value(link.fromId);
00652 QVPropertyContainer *toCont = containers.value(link.toId);
00653
00654 QVMPlayerCamera* camera;
00655 QVWorker* worker;
00656 QVWorker* worker2;
00657 QVImageCanvas* canvas;
00658 QVPlot* plot;
00659
00660 if((camera = dynamic_cast<QVMPlayerCamera*>(fromCont)) != NULL) {
00661 if((worker = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00662 result += QString(" ") + fromCont->getName() + QString(".link(&") + toCont->getName() + QString(", \"") + link.toProp + QString("\");\n");
00663 }
00664 }
00665 else if((worker = dynamic_cast<QVWorker*>(fromCont)) != NULL) {
00666 if((worker2 = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00667 result += QString(" ") + fromCont->getName() + QString(".linkProperty(\"") + link.fromProp + QString("\", &");
00668 result += toCont->getName() + QString(", \"") + link.toProp;
00669 if (link.synchronous)
00670 result += QString("\", QVWorker::SynchronousLink);\n");
00671 else
00672 result += QString("\", QVWorker::AsynchronousLink);\n");
00673 }
00674 else if((canvas = dynamic_cast<QVImageCanvas*>(toCont)) != NULL) {
00675 result += QString(" ") + toCont->getName() + QString(".linkProperty(") + fromCont->getName() + QString(", \"") + link.fromProp + QString("\");\n");
00676 }
00677 else if((plot = dynamic_cast<QVPlot*>(toCont)) != NULL) {
00678 result += QString(" ") + toCont->getName() + QString(".linkProperty(") + fromCont->getName() + QString(", \"") + link.fromProp + QString("\");\n");
00679 }
00680 }
00681 }
00682 }
00683
00684
00685 result += "\n";
00686 foreach(CreatedItem item, createdItems.values()) {
00687 foreach(PropertyChange change, propertyChanges.values()) {
00688 if (change.id == item.id) {
00689 QVPropertyContainer *cont = containers.value(item.id);
00690 QString prop = change.propName;
00691 QVariant value = change.value;
00692
00693 if (cont->isType<int>(prop))
00694 result += QString(" ") + item.name + ".setPropertyValue<int>(\"" + prop + "\", " + value.toString() + ");\n";
00695 else if (cont->isType<bool>(prop))
00696 result += QString(" ") + item.name + ".setPropertyValue<bool>(\"" + prop + "\", " + value.toString() + ");\n";
00697 else if (cont->isType<double>(prop))
00698 result += QString(" ") + item.name + ".setPropertyValue<double>(\"" + prop + "\", " + value.toString() + ");\n";
00699 else if (cont->isType<QString>(prop))
00700 result += QString(" ") + item.name + ".setPropertyValue<QString>(\"" + prop + "\", " + value.toString() + ");\n";
00701 else if (cont->isType<QVIndexedStringList>(prop)) {
00702 QVIndexedStringList indlist = value.value<QVIndexedStringList>();
00703 result += QString(" QVIndexedStringList ") + "QVISLfor_" + item.name + ";\n";
00704 foreach (QString option, indlist) {
00705 result += QString(" QVISLfor_") + item.name + ".append(\"" + option + "\");\n";
00706 }
00707 result += QString(" QVISLfor_") + item.name + QString(".setIndex(%1);\n").arg(indlist.getIndex());
00708 result += QString(" ") + item.name + ".setPropertyValue<QVIndexedStringList>(\"" + prop + "\", QVISLfor_" + item.name + ");\n";
00709 }
00710 }
00711 }
00712 }
00713
00714
00715 result += "\n return app.exec();\n }\n\n#endif\n\n";
00716 return result;
00717 }
00718
00719 QString QVDesignerGUI::getXMLText()
00720 {
00721 QString text;
00722 QXmlStreamWriter xmlWriter(&text);
00723 xmlWriter.setAutoFormatting(true);
00724 uint xmlId = 1;
00725 QMap<uint, uint> ItemId_To_xmlId;
00726
00727 xmlWriter.writeStartDocument("1.0");
00728 xmlWriter.writeStartElement("QVApplication");
00729
00730
00731 xmlWriter.writeStartElement("Nodes");
00732 foreach(CreatedItem item, createdItems.values()) {
00733 xmlWriter.writeStartElement("Node");
00734 xmlWriter.writeAttribute("Type", item.type);
00735 xmlWriter.writeAttribute("Id", QString("%1").arg(xmlId));
00736 ItemId_To_xmlId.insert(item.id, xmlId++);
00737 xmlWriter.writeAttribute("Name", item.name);
00738 QPointF pos = slate.getNodePos(item.id);
00739 xmlWriter.writeAttribute("X", QString("%1").arg(pos.x()));
00740 xmlWriter.writeAttribute("Y", QString("%1").arg(pos.y()));
00741
00742
00743 foreach(PropertyChange change, propertyChanges.values()) {
00744 if (change.id == item.id) {
00745 QString strValue = change.value.toString();
00746 if (!strValue.isEmpty()) {
00747 xmlWriter.writeStartElement("Property");
00748 xmlWriter.writeAttribute("Name", change.propName);
00749 xmlWriter.writeAttribute("Value", strValue);
00750 xmlWriter.writeEndElement();
00751 }
00752 }
00753 }
00754 xmlWriter.writeEndElement();
00755 }
00756 xmlWriter.writeEndElement();
00757
00758
00759 xmlWriter.writeStartElement("Links");
00760 foreach (CreatedLink link, createdLinks.values()) {
00761 if ( (containers.contains(link.fromId) && containers.contains(link.toId)) ||
00762 (initialContainers.contains(link.fromId) && initialContainers.contains(link.toId)) ) {
00763 if (link.synchronous) xmlWriter.writeStartElement("SynchronousLink");
00764 else if (link.sequential) xmlWriter.writeStartElement("SequentialLink");
00765 else xmlWriter.writeStartElement("AsynchronousLink");
00766 xmlWriter.writeAttribute("FromId", QString("%1").arg(ItemId_To_xmlId.value(link.fromId)));
00767 xmlWriter.writeAttribute("FromProp", link.fromProp);
00768 xmlWriter.writeAttribute("ToId", QString("%1").arg(ItemId_To_xmlId.value(link.toId)));
00769 xmlWriter.writeAttribute("ToProp", link.toProp);
00770 xmlWriter.writeEndElement();
00771 }
00772 }
00773 xmlWriter.writeEndElement();
00774
00775
00776 xmlWriter.writeStartElement("Groups");
00777 QList<GroupInfo> groupList = slate.getGroups();
00778 foreach (GroupInfo group, groupList) {
00779 xmlWriter.writeStartElement("Group");
00780 xmlWriter.writeAttribute("Id", QString("%1").arg(group.getId()));
00781 xmlWriter.writeAttribute("Name", group.getName());
00782 QPointF pos =group.getPos();
00783 xmlWriter.writeAttribute("X", QString("%1").arg(pos.x()));
00784 xmlWriter.writeAttribute("Y", QString("%1").arg(pos.y()));
00785 foreach (uint nodeId, group.getNodes()) {
00786 xmlWriter.writeStartElement("ChildNode");
00787 xmlWriter.writeAttribute("Id", QString("%1").arg(ItemId_To_xmlId.value(nodeId)));
00788 xmlWriter.writeEndElement();
00789 }
00790 foreach (uint subId, group.getSubgroups()) {
00791 xmlWriter.writeStartElement("ChildGroup");
00792 xmlWriter.writeAttribute("Id", QString("%1").arg(subId));
00793 xmlWriter.writeEndElement();
00794 }
00795 foreach (LinkInfo link, group.getNodeLinks()) {
00796 xmlWriter.writeStartElement("VisibleNodeLink");
00797 xmlWriter.writeAttribute("ChildNode", QString("%1").arg(ItemId_To_xmlId.value(link.getNode())));
00798 xmlWriter.writeAttribute("Prop", link.getProp());
00799 xmlWriter.writeAttribute("Direction", link.getInput() ? "Input" : "Output");
00800 xmlWriter.writeEndElement();
00801 }
00802 foreach (LinkInfo link, group.getSubgroupLinks()) {
00803 xmlWriter.writeStartElement("VisibleGroupLink");
00804 xmlWriter.writeAttribute("ChildGroup", QString("%1").arg(link.getNode()));
00805 xmlWriter.writeAttribute("Prop", link.getProp());
00806 xmlWriter.writeAttribute("Direction", link.getInput() ? "Input" : "Output");
00807 xmlWriter.writeEndElement();
00808 }
00809 xmlWriter.writeEndElement();
00810 }
00811 xmlWriter.writeEndElement();
00812
00813 xmlWriter.writeEndElement();
00814 xmlWriter.writeEndDocument();
00815
00816 return text;
00817 }
00818
00819 bool QVDesignerGUI::loadXML(QString text)
00820 {
00821
00822 foreach (QVPropertyContainer * cont, containers) {
00823 factory.deleteContainer(cont);
00824 }
00825 propertyChanges.clear();
00826 dialogsToContainers.clear();
00827 createdLinks.clear();
00828
00829
00830
00831 QXmlStreamReader xmlReader(text);
00832
00833 while (!xmlReader.atEnd()) {
00834 xmlReader.readNext();
00835
00836 if (xmlReader.isEndElement())
00837 break;
00838
00839 if (xmlReader.isStartElement()) {
00840 if (xmlReader.name() == "QVApplication")
00841 readXMLQVApplication(xmlReader);
00842 else
00843 readXMLUnknownElement(xmlReader);
00844 }
00845 }
00846
00847 XMLId_To_ContainersId.clear();
00848
00849 if (xmlReader.hasError()) return false;
00850
00851 return true;
00852 }
00853
00854 bool QVDesignerGUI::readXMLQVApplication(QXmlStreamReader &xmlReader)
00855 {
00856 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "QVApplication");
00857
00858 while (!xmlReader.atEnd()) {
00859 xmlReader.readNext();
00860
00861 if (xmlReader.isEndElement())
00862 break;
00863
00864 if (xmlReader.isStartElement()) {
00865 if (xmlReader.name() == "Nodes")
00866 readXMLNodes(xmlReader);
00867 else if (xmlReader.name() == "Links")
00868 readXMLLinks(xmlReader);
00869 else if (xmlReader.name() == "Groups")
00870 readXMLGroups(xmlReader);
00871 else
00872 readXMLUnknownElement(xmlReader);
00873 }
00874 }
00875
00876 return true;
00877 }
00878
00879 bool QVDesignerGUI::readXMLNodes(QXmlStreamReader &xmlReader)
00880 {
00881 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Nodes");
00882
00883 while (!xmlReader.atEnd()) {
00884 xmlReader.readNext();
00885
00886 if (xmlReader.isEndElement())
00887 break;
00888
00889 if (xmlReader.isStartElement()) {
00890 if (xmlReader.name() == "Node")
00891 readXMLNode(xmlReader);
00892 else
00893 readXMLUnknownElement(xmlReader);
00894 }
00895 }
00896
00897 return true;
00898 }
00899
00900 bool QVDesignerGUI::readXMLNode(QXmlStreamReader &xmlReader)
00901 {
00902 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Node");
00903
00904 QXmlStreamAttributes attributes = xmlReader.attributes();
00905 QString type = attributes.value("Type").toString();
00906 QString XMLid = attributes.value("Id").toString();
00907 QString name = attributes.value("Name").toString();
00908 QString x = attributes.value("X").toString();
00909 QString y = attributes.value("Y").toString();
00910
00911
00912 uint itemId = addItem(type, name);
00913
00914 XMLId_To_ContainersId.insert(XMLid.toInt(), itemId);
00915 slate.moveNode(itemId, QPointF(x.toInt(), y.toInt()));
00916
00917 while (!xmlReader.atEnd()) {
00918 xmlReader.readNext();
00919
00920 if (xmlReader.isEndElement())
00921 break;
00922
00923 if (xmlReader.isStartElement()) {
00924 if (xmlReader.name() == "Property")
00925 readXMLProperty(xmlReader, itemId);
00926 else
00927 readXMLUnknownElement(xmlReader);
00928 }
00929 }
00930
00931 return true;
00932 }
00933
00934 bool QVDesignerGUI::readXMLProperty(QXmlStreamReader &xmlReader, uint id)
00935 {
00936 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Property");
00937
00938 QXmlStreamAttributes attributes = xmlReader.attributes();
00939 QString name = attributes.value("Name").toString();
00940 QString value = attributes.value("Value").toString();
00941
00942 if (containers.contains(id)) {
00943 QVPropertyContainer *cont = containers.value(id);
00944
00945 if (cont->isType<int>(name)) {
00946 cont->setPropertyValue<int>(name, value.toInt());
00947 propertyChanges.insert(getAbsPropName(QString("%1").arg(id), name), PropertyChange(id, name, QVariant(value.toInt())));
00948 }
00949 else if (cont->isType<bool>(name)) {
00950 cont->setPropertyValue<bool>(name, (value == "true" ? true : false));
00951 propertyChanges.insert(getAbsPropName(QString("%1").arg(id), name), PropertyChange(id, name, QVariant((value == "true" ? true : false))));
00952 }
00953 else if (cont->isType<double>(name)) {
00954 cont->setPropertyValue<double>(name, value.toDouble());
00955 propertyChanges.insert(getAbsPropName(QString("%1").arg(id), name), PropertyChange(id, name, QVariant(value.toDouble())));
00956 }
00957 else if (cont->isType<QString>(name)) {
00958 cont->setPropertyValue<QString>(name, value);
00959 propertyChanges.insert(getAbsPropName(QString("%1").arg(id), name), PropertyChange(id, name, QVariant(value)));
00960 }
00961 }
00962
00963 while (!xmlReader.atEnd()) {
00964 xmlReader.readNext();
00965
00966 if (xmlReader.isEndElement())
00967 break;
00968
00969 if (xmlReader.isStartElement()) {
00970 readXMLUnknownElement(xmlReader);
00971 }
00972 }
00973
00974 return true;
00975 }
00976
00977 bool QVDesignerGUI::readXMLLinks(QXmlStreamReader &xmlReader)
00978 {
00979 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Links");
00980
00981 while (!xmlReader.atEnd()) {
00982 xmlReader.readNext();
00983
00984 if (xmlReader.isEndElement())
00985 break;
00986
00987 if (xmlReader.isStartElement()) {
00988 if (xmlReader.name() == "AsynchronousLink")
00989 readXMLAsynchronousLink(xmlReader);
00990 else if (xmlReader.name() == "SynchronousLink")
00991 readXMLSynchronousLink(xmlReader);
00992 else if (xmlReader.name() == "SequentialLink")
00993 readXMLSequentialLink(xmlReader);
00994 else
00995 readXMLUnknownElement(xmlReader);
00996 }
00997 }
00998
00999 return true;
01000 }
01001
01002 bool QVDesignerGUI::readXMLAsynchronousLink(QXmlStreamReader &xmlReader)
01003 {
01004 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "AsynchronousLink");
01005
01006 QXmlStreamAttributes attributes = xmlReader.attributes();
01007 QString fromId = attributes.value("FromId").toString();
01008 QString fromProp = attributes.value("FromProp").toString();
01009 QString toId = attributes.value("ToId").toString();
01010 QString toProp = attributes.value("ToProp").toString();
01011
01012 addLink(XMLId_To_ContainersId.value(fromId.toUInt()), fromProp, XMLId_To_ContainersId.value(toId.toUInt()), toProp, false, false);
01013
01014 while (!xmlReader.atEnd()) {
01015 xmlReader.readNext();
01016
01017 if (xmlReader.isEndElement())
01018 break;
01019
01020 if (xmlReader.isStartElement()) {
01021 readXMLUnknownElement(xmlReader);
01022 }
01023 }
01024
01025 return true;
01026 }
01027
01028 bool QVDesignerGUI::readXMLSynchronousLink(QXmlStreamReader &xmlReader)
01029 {
01030 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "SynchronousLink");
01031
01032 QXmlStreamAttributes attributes = xmlReader.attributes();
01033 QString fromId = attributes.value("FromId").toString();
01034 QString fromProp = attributes.value("FromProp").toString();
01035 QString toId = attributes.value("ToId").toString();
01036 QString toProp = attributes.value("ToProp").toString();
01037
01038 addLink(XMLId_To_ContainersId.value(fromId.toUInt()), fromProp, XMLId_To_ContainersId.value(toId.toUInt()), toProp, true, false);
01039
01040 while (!xmlReader.atEnd()) {
01041 xmlReader.readNext();
01042
01043 if (xmlReader.isEndElement())
01044 break;
01045
01046 if (xmlReader.isStartElement()) {
01047 readXMLUnknownElement(xmlReader);
01048 }
01049 }
01050
01051 return true;
01052 }
01053
01054 bool QVDesignerGUI::readXMLSequentialLink(QXmlStreamReader &xmlReader)
01055 {
01056 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "SequentialLink");
01057
01058 QXmlStreamAttributes attributes = xmlReader.attributes();
01059 QString fromId = attributes.value("FromId").toString();
01060 QString fromProp = attributes.value("FromProp").toString();
01061 QString toId = attributes.value("ToId").toString();
01062 QString toProp = attributes.value("ToProp").toString();
01063
01064 addLink(XMLId_To_ContainersId.value(fromId.toUInt()), fromProp, XMLId_To_ContainersId.value(toId.toUInt()), toProp, false, true);
01065
01066 while (!xmlReader.atEnd()) {
01067 xmlReader.readNext();
01068
01069 if (xmlReader.isEndElement())
01070 break;
01071
01072 if (xmlReader.isStartElement()) {
01073 readXMLUnknownElement(xmlReader);
01074 }
01075 }
01076
01077 return true;
01078 }
01079
01080 bool QVDesignerGUI::readXMLGroups(QXmlStreamReader &xmlReader) {
01081 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Groups");
01082
01083 QList<GroupInfo> groupInfos;
01084
01085 while (!xmlReader.atEnd()) {
01086 xmlReader.readNext();
01087
01088 if (xmlReader.isEndElement())
01089 break;
01090
01091 if (xmlReader.isStartElement()) {
01092 if (xmlReader.name() == "Group")
01093 readXMLGroup(xmlReader, groupInfos);
01094 else
01095 readXMLUnknownElement(xmlReader);
01096 }
01097 }
01098
01099 createGroups(groupInfos, XMLId_To_ContainersId);
01100
01101 return true;
01102 }
01103
01104 bool QVDesignerGUI::readXMLGroup(QXmlStreamReader &xmlReader, QList<GroupInfo> &groupInfos) {
01105 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "Group");
01106
01107 QXmlStreamAttributes attributes = xmlReader.attributes();
01108 QString XMLid = attributes.value("Id").toString();
01109 QString name = attributes.value("Name").toString();
01110 QString x = attributes.value("X").toString();
01111 QString y = attributes.value("Y").toString();
01112
01113 GroupInfo groupInfo(XMLid.toInt(), name);
01114 groupInfo.setPos(QPointF(x.toInt(), y.toInt()));
01115
01116 while (!xmlReader.atEnd()) {
01117 xmlReader.readNext();
01118
01119 if (xmlReader.isEndElement())
01120 break;
01121
01122 if (xmlReader.isStartElement()) {
01123 if (xmlReader.name() == "ChildNode")
01124 readXMLChildNode(xmlReader, groupInfo);
01125 else if (xmlReader.name() == "ChildGroup")
01126 readXMLChildGroup(xmlReader, groupInfo);
01127 else if (xmlReader.name() == "VisibleNodeLink")
01128 readXMLVisibleNodeLink(xmlReader, groupInfo);
01129 else if (xmlReader.name() == "VisibleGroupLink")
01130 readXMLVisibleGroupLink(xmlReader, groupInfo);
01131 else
01132 readXMLUnknownElement(xmlReader);
01133 }
01134 }
01135
01136 groupInfos.append(groupInfo);
01137
01138 return true;
01139 }
01140
01141 bool QVDesignerGUI::readXMLChildNode(QXmlStreamReader &xmlReader, GroupInfo &groupInfo) {
01142 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "ChildNode");
01143
01144 QXmlStreamAttributes attributes = xmlReader.attributes();
01145 QString XMLid = attributes.value("Id").toString();
01146
01147 groupInfo.addNode(XMLid.toInt());
01148
01149 while (!xmlReader.atEnd()) {
01150 xmlReader.readNext();
01151
01152 if (xmlReader.isEndElement())
01153 break;
01154
01155 if (xmlReader.isStartElement()) {
01156 readXMLUnknownElement(xmlReader);
01157 }
01158 }
01159
01160 return true;
01161 }
01162
01163 bool QVDesignerGUI::readXMLChildGroup(QXmlStreamReader &xmlReader, GroupInfo &groupInfo) {
01164 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "ChildGroup");
01165
01166 QXmlStreamAttributes attributes = xmlReader.attributes();
01167 QString XMLid = attributes.value("Id").toString();
01168
01169 groupInfo.addSubgroup(XMLid.toInt());
01170
01171 while (!xmlReader.atEnd()) {
01172 xmlReader.readNext();
01173
01174 if (xmlReader.isEndElement())
01175 break;
01176
01177 if (xmlReader.isStartElement()) {
01178 readXMLUnknownElement(xmlReader);
01179 }
01180 }
01181
01182 return true;
01183 }
01184
01185 bool QVDesignerGUI::readXMLVisibleNodeLink(QXmlStreamReader &xmlReader, GroupInfo &groupInfo) {
01186 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "VisibleNodeLink");
01187
01188 QXmlStreamAttributes attributes = xmlReader.attributes();
01189 QString XMLid = attributes.value("ChildNode").toString();
01190 QString prop = attributes.value("Prop").toString();
01191 QString direction = attributes.value("Direction").toString();
01192
01193 groupInfo.addNodeLink(LinkInfo(XMLid.toInt(), prop, direction == "Input" ? true : false));
01194
01195 while (!xmlReader.atEnd()) {
01196 xmlReader.readNext();
01197
01198 if (xmlReader.isEndElement())
01199 break;
01200
01201 if (xmlReader.isStartElement()) {
01202 readXMLUnknownElement(xmlReader);
01203 }
01204 }
01205
01206 return true;
01207 }
01208
01209 bool QVDesignerGUI::readXMLVisibleGroupLink(QXmlStreamReader &xmlReader, GroupInfo &groupInfo) {
01210 Q_ASSERT(xmlReader.isStartElement() && xmlReader.name() == "VisibleGroupLink");
01211
01212 QXmlStreamAttributes attributes = xmlReader.attributes();
01213 QString XMLid = attributes.value("ChildGroup").toString();
01214 QString prop = attributes.value("Prop").toString();
01215 QString direction = attributes.value("Direction").toString();
01216
01217 groupInfo.addSubgroupLink(LinkInfo(XMLid.toInt(), prop, direction == "Input" ? true : false));
01218
01219 while (!xmlReader.atEnd()) {
01220 xmlReader.readNext();
01221
01222 if (xmlReader.isEndElement())
01223 break;
01224
01225 if (xmlReader.isStartElement()) {
01226 readXMLUnknownElement(xmlReader);
01227 }
01228 }
01229
01230 return true;
01231 }
01232
01233 bool QVDesignerGUI::readXMLUnknownElement(QXmlStreamReader &xmlReader)
01234 {
01235 Q_ASSERT(xmlReader.isStartElement());
01236
01237
01238
01239 while (!xmlReader.atEnd()) {
01240 xmlReader.readNext();
01241
01242 if (xmlReader.isEndElement())
01243 break;
01244
01245 if (xmlReader.isStartElement())
01246 readXMLUnknownElement(xmlReader);
01247 }
01248
01249 return true;
01250 }
01251