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