PARP Research Group University of Murcia, Spain


src/qvgui/qvdesigner/qvdesignergui.cpp

00001 /*
00002  *      Copyright (C) 2008, 2009. PARP Research Group.
00003  *      <http://perception.inf.um.es>
00004  *      University of Murcia, Spain.
00005  *
00006  *      This file is part of the QVision library.
00007  *
00008  *      QVision is free software: you can redistribute it and/or modify
00009  *      it under the terms of the GNU Lesser General Public License as
00010  *      published by the Free Software Foundation, version 3 of the License.
00011  *
00012  *      QVision is distributed in the hope that it will be useful,
00013  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *      GNU Lesser General Public License for more details.
00016  *
00017  *      You should have received a copy of the GNU Lesser General Public
00018  *      License along with QVision. If not, see <http://www.gnu.org/licenses/>.
00019  */
00020 
00021 
00022 //#include "qvdesignergui.h"
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         // if its a --help call, do nothing
00050         if (qvApp->forHelp()) return;
00051 
00052         connect(&slate, SIGNAL(closed()), this, SLOT(quit()));
00053 
00054         qvApp->registerGUI(this);
00055         qvApp->setTerminateOnLastWorker(false); // para que no termine cuando se resetea el escenario (y se quitan todos los workers temporalmente)
00056 
00057 /*      // se conecta al informador estatico de la clase para obtener señales cuando se crea y se destruye un property container
00058         QVPropertyContainerInformer *inf = QVPropertyContainer::getGlobalInformer();
00059         connect(inf, SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));*/
00060 
00061         qDebug() << "QVDesignerGUI::QVDesignerGUI() <~ return";
00062 }
00063 
00064 void QVDesignerGUI::init()
00065 {
00066         // registra y pinta los property containers
00067         foreach(QVPropertyContainer* qvp, qvApp->getQVPropertyContainers()) {
00068                 // registro su tipo
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                 // registra y pinta el property container
00077                 QString type = factory.containerType(qvp);
00078                 QString name = qvp->getName();
00079                 uint id = qvp->getId();
00080                 // no se incluye en "containers", ya que no se pueden borrar desde aqui, ya que se crearon en el main y no con new. Se registra en "initialContainers"
00081                 initialContainers.insert(id, qvp);
00082                 createdItems.insert(id, CreatedItem(type, name, id));
00083                 // se conecta al informador de ese container para obtener señales de sus cambios.
00084                 connect(qvp->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));
00085                 slate.addItemNode(type, name, id, new ItemProperties(type, qvp));
00086                 // creo su dialogo
00087                 createDialog(id);
00088         }
00089 
00090         // una vez he registrado todos los property containers, registro y pinto los links de salida de cada uno (asi los pinto todos sin repetir)
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 //                              informer.inform(QString("Link añadido: ") + getLinkName(fromName, fromProp, toName, toProp));
00107                         }
00108                 }
00109         }
00110 
00111         // por último se pide a la vista, ahora que estan todos los nodos y links, que reordene los mismos
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         //std::cout << "Creo " + name.toStdString() + "\n";
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                 // se conecta al informador de ese container para obtener señales de sus cambios.
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                 // borramos el propertyContainer asociado
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                                 //std::cout << change.toString().toStdString() << std::endl;
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                         // si se ha creado su dialogo, tambien lo borramos
00271                         deleteDialog(id);
00272 
00273                         //std::cout << change.toString().toStdString() << std::endl;
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                         //std::cout << change.toString().toStdString() << std::endl;
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                         //std::cout << change.toString().toStdString() << std::endl;
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 //                              informer.inform(QString("Link creado: ") + linkName);
00320                         }
00321 //                      else
00322 //                              informer.inform(QString("Se ha creado un link no registrado: ") + linkName);
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                                 //std::cout << change.toString().toStdString() << std::endl;
00338                         }
00339                 }
00340                 break;
00341 
00342         case QVPropertyContainerChange::All:
00343                 //std::cout << change.toString().toStdString() << std::endl;
00344                 break;
00345 
00346         default:
00347                 break;
00348         }
00349 }
00350 
00351 // esto se hace para que se almacenen los cambios antes de darle a run y que se hagan los read y writes
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         // si se ha creado su dialogo, tambien lo borramos (puede no haberse creado si no se ha dado a run)
00443         if (dialogs.contains(itemId)) {
00444                 delete dialogs.value(itemId);
00445                 dialogs.remove(itemId);
00446         }
00447 }
00448 
00449 void QVDesignerGUI::run()
00450 {
00451         // creamos los dialogos que no se han creado aun, ya que después no se puede (porque no se puede lincar)
00452         foreach (uint id, containers.keys()) {
00453                 if (!dialogs.contains(id))
00454                         createDialog(id);
00455         }
00456 
00457         // y arrancamos la simulación
00458         qvApp->startItems();
00459 }
00460 
00461 void QVDesignerGUI::stop()
00462 {
00463         // guardando la descripción de lo que tenía creado
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         // detenemos la simulación (lo que desregistra los elementos del qvApp y deslinca los items)
00470         qvApp->quitItems();
00471 
00472         // procesa todos los dellLink emitidos al parar los elementos desde el qvapp (para que no se solapen con su recontrucción)
00473         qApp->processEvents();
00474 
00475         // oculto los objetos creados desde el main y borro sus dialogos, que se crean al arrancar
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(); // solo hay que ocultar los elementos de entrada una vez (ya que esos objetos no se pueden eliminar desde este contexto)
00483 
00484         // borro los grupos creados
00485         slate.eraseGroups();
00486 
00487         // borro los objetos creados
00488         foreach (QVPropertyContainer * cont, containers) {
00489                 factory.deleteContainer(cont);
00490         }
00491         dialogsToContainers.clear();
00492         createdLinks.clear();
00493 
00494         // creo otros iguales (registrandose en la lista "containers")
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         // creo links iguales a los que teniamos para los nuevos items (teniendo en cuenta el cambio de id que sufren)
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         // restauro los valores cambiados por el usuario
00511         for (QMap<QString, PropertyChange>::iterator it = propertyChanges.begin(); it != propertyChanges.end(); it++) { // uso un iterador para poder modificar
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);  // uso en id del nuevo item (que sustituye al anterior)
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         // primero actualizo los Ids relativos a los nodos de todos los subgrupos, ya que han cambiado
00541         for (QList<GroupInfo>::iterator it = lastGroups.begin(); it != lastGroups.end(); it++) {
00542                 //std::cout << "para el info " << QString((*it).getName()).toStdString() << " hago los siguientes cambios de ID:\n";
00543                 foreach (uint oldId, (*it).getNodes()) {
00544                         //std::cout << QString("     cambio oldId = %1...").arg(oldId).toStdString();
00545                         if (oldId_To_NewId.contains(oldId)) {
00546                                 (*it).updateNodeId(oldId, oldId_To_NewId.value(oldId));
00547                                 //std::cout << QString(" a newId = %1").arg(oldId_To_NewId.value(oldId)).toStdString();
00548                         }
00549                         //std::cout << "\n";
00550                 }
00551         }
00552         // Voy creando los nuevos grupos por pasadas (para que cree primero los subgrupos), y a la misma vez se van actualizando los IDs de los subgrupos de los restantes
00553         bool reloop = true;
00554         while (reloop) { // bucle por pasadas, intenta crear los grupos restantes, hasta que en una pasada no se cree ninguno
00555                 //std::cout << "Una pasada: \n";
00556                 QMap<uint, uint> changes;
00557                 QList<GroupInfo>::iterator it = lastGroups.begin();
00558                 while (it != lastGroups.end()) { // intento crear los grupos y guardo el cambio de ID
00559                         uint oldId = (*it).getId();
00560                         uint newId = slate.createGroup(*it);
00561                         //std::cout << QString("Encuentro un info, oldId = %1, newId = %2...").arg(oldId).arg(newId).toStdString();
00562                         if (newId > 0) {
00563                                 changes.insert(oldId, newId);
00564                                 it = lastGroups.erase(it);// borro el elemento cambiado de la lista (lo que avanza la lista), ya se ha creado su grupo
00565                                 //std::cout << " por lo que inserto un cambio";
00566                         }
00567                         else it++;
00568                         //std::cout << "\n";
00569                 }
00570                 foreach (uint idChanged, changes.keys()) { // actualizo los cambios en el resto
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         // incluye una cabezera inicial con el copyright de la librería QVision
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         // genera la lista de includes, si alguno de los elementos ha sido definido por el usuario, lo declara para que el usuario lo referencie
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         // si en alguno de los items se ha modificado una propiedad QVIndexedStringList, se añade su include
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         // comienza el método main
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         // contruye los objetos usados
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         // realiza los links
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         // establece los valores actuales de las propiedades
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         // finaliza el fichero
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         // añade las características de los items
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                 // añade las características de los cambios en las  propiedades de cada item
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         // añade las características de los links
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)) ) { // igual tendría que no registrar a los paramInspector al init
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         // añade las características de los grupos credos en la pizarra
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         // borra todo lo que hay
00822         foreach (QVPropertyContainer * cont, containers) {
00823                 factory.deleteContainer(cont);
00824         }
00825         propertyChanges.clear();
00826         dialogsToContainers.clear();
00827         createdLinks.clear();
00828 
00829 
00830         // carga lo del fichero
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(); // se resetea para la siguiente llamada
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 //      qApp->processEvents();
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 // std::cout << "Algo extaño\n";
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 



QVision framework. PARP research group, copyright 2007, 2008.