examples/qvdesigner0.2/facade/designergui.cpp

00001 /*
00002  *      Copyright (C) 2008. 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 "designergui.h"
00023 #include <QVApplication>
00024 #include <QVPropertyContainer>
00025 #include <QVPropertyContainerChange>
00026 #include "workerdialog.h"
00027 #include "cameradialog.h"
00028 
00029 
00030 DesignerGUI::DesignerGUI(): QObject(), factory(), slate(this)
00031 {
00032         qDebug() << "DesignerGUI::DesignerGUI()";
00033         if (qvApp == NULL)
00034                 {
00035                 QString str =   "DesignerGUI::DesignerGUI(): the SlateGUI cannot be created before the QVApplication instance. Aborting now.";
00036                 std::cerr << qPrintable(str) << std::endl;
00037                 exit(1);
00038                 }
00039 
00040         // if its a --help call, do nothing
00041         if (qvApp->forHelp()) return;
00042 
00043         connect(&slate, SIGNAL(closed()), this, SLOT(quit()));
00044 
00045         qvApp->registerGUI(this);
00046         qvApp->setTerminateOnLastWorker(false); // para que no termine cuando se resetea el escenario (y se quitan todos los workers temporalmente)
00047 
00048 /*      // se conecta al informador estatico de la clase para obtener señales cuando se crea y se destruye un property container
00049         QVPropertyContainerInformer *inf = QVPropertyContainer::getGlobalInformer();
00050         connect(inf, SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));*/
00051 
00052         qDebug() << "DesignerGUI::DesignerGUI() <~ return";
00053 }
00054 
00055 void DesignerGUI::init()
00056 {
00057 /*      foreach(QVPropertyContainer* qvp, qvApp->getQVPropertyContainers())
00058                 {
00059                 QVWorker* worker;
00060                 if((worker = dynamic_cast<QVWorker*>(qvp)) != NULL)
00061                         add(worker);
00062                 }
00063         leftvboxlayout->addStretch();
00064         foreach(QVPropertyContainer* qvp, qvApp->getQVPropertyContainers())
00065                 {
00066                 QVCamera* camera;
00067                 if((camera = dynamic_cast<QVCamera*>(qvp)) != NULL)
00068                         add(camera);
00069                 }*/
00070 }
00071 
00072 void DesignerGUI::show()
00073 {
00074         slate.show();
00075 }
00076 
00077 QList<QString> DesignerGUI::getItemTypes() const
00078 {
00079         return factory.getItemTypes();
00080 }
00081 
00082 QList<QString> DesignerGUI::getInputItemTypes() const
00083 {
00084         return factory.getInputItemTypes();
00085 }
00086 
00087 QList<QString> DesignerGUI::getMiddleItemTypes() const
00088 {
00089         return factory.getMiddleItemTypes();
00090 }
00091 
00092 QList<QString> DesignerGUI::getOutputItemTypes() const
00093 {
00094         return factory.getOutputItemTypes();
00095 }
00096 
00097 #include <iostream>
00098 bool DesignerGUI::addItem(QString type, QString name)
00099 {
00100         if (containers.contains(name)) return FALSE;
00101 
00102         //std::cout << "Creo " + name.toStdString() + "\n";
00103         QVPropertyContainer *cont = factory.createContainer(type, name);
00104         if (cont != 0) {
00105                 containers.insert(name, cont);
00106                 createdItems.insert(name, CreatedItem(type, name));
00107                 // se conecta al informador de ese container para obtener señales de sus cambios.
00108                 connect(cont->getInformer(), SIGNAL(changed(QVPropertyContainerChange)), this, SLOT(processChange(QVPropertyContainerChange)));
00109 
00110                 slate.addItemNode(type, name, new ItemProperties(type, cont));
00111                 return TRUE;
00112         }
00113         return FALSE;
00114 }
00115 
00116 #include <QVMPlayerCamera>
00117 #include <QVWorker>
00118 #include <QVImageCanvas>
00119 #include <qvgui/qvplot.h>
00120 bool DesignerGUI::addLink(QString fromName, QString fromProp, QString toName, QString toProp, bool synchronous)
00121 {
00123         if (containers.contains(fromName) && containers.contains(toName)) {
00124                 QVPropertyContainer *fromCont = containers.value(fromName);
00125                 QVPropertyContainer *toCont = containers.value(toName);
00126 
00127                 QVMPlayerCamera* camera;
00128                 QVWorker* worker;
00129                 QVWorker* worker2;
00130                 QVImageCanvas* canvas;
00131                 QVPlot* plot;
00132 
00133                 if((camera = dynamic_cast<QVMPlayerCamera*>(fromCont)) != NULL) {
00134                         if((worker = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00135                                 if (!synchronous) { // solo se permite AsynchronousLink
00136                                         camera->link(worker, toProp);
00137                                 }
00138                         }
00139                 }
00140                 else if((worker = dynamic_cast<QVWorker*>(fromCont)) != NULL) {
00141                         if((worker2 = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00142                                 if (synchronous) {
00143                                         worker->linkProperty(fromProp, worker2, toProp, QVWorker::SynchronousLink);
00144                                 }
00145                                 else {
00146                                         worker->linkProperty(fromProp, worker2, toProp, QVWorker::AsynchronousLink);
00147                                 }
00148                         }
00149                         else if((canvas = dynamic_cast<QVImageCanvas*>(toCont)) != NULL) {
00150                                 if (!synchronous) { // solo se permite AsynchronousLink
00151                                         canvas->linkProperty(*worker, fromProp);
00152                                 }
00153                         }
00154                         else if((plot = dynamic_cast<QVPlot*>(toCont)) != NULL) {
00155                                 if (!synchronous) { // solo se permite AsynchronousLink
00156                                         plot->linkProperty(*worker, fromProp);
00157                                 }
00158                         }
00159                 }
00160         }
00161         return TRUE;
00162 }
00163 
00164 bool DesignerGUI::delItem(const QString name)
00165 {
00166         if (containers.contains(name)) {
00167                 // borramos el propertyContainer asociado
00168 QVMPlayerCamera* camera;
00169 if((camera = dynamic_cast<QVMPlayerCamera*>(containers.value(name))) != NULL) return false; // ahora no dejo borrar camaras pq peta
00170                 delete containers.value(name);
00171                 return true;
00172         }
00173         return false;
00174 }
00175 
00176 bool DesignerGUI::delLink(const QString fromName, const QString fromProp, const QString toName, const QString toProp)
00177 {
00178         if (containers.contains(fromName) && containers.contains(toName)) {
00179                 QVPropertyContainer *fromCont = containers.value(fromName);
00180                 QVPropertyContainer *toCont = containers.value(toName);
00181 
00182                 QVMPlayerCamera* camera;
00183                 QVWorker* worker;
00184                 QVWorker* worker2;
00185                 QVImageCanvas* canvas;
00186                 QVPlot* plot;
00187 
00188                 if((camera = dynamic_cast<QVMPlayerCamera*>(fromCont)) != NULL) {
00189                         if((worker = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00190                                 camera->unlink(worker, toProp);
00191                         }
00192                 }
00193                 else if((worker = dynamic_cast<QVWorker*>(fromCont)) != NULL) {
00194                         if((worker2 = dynamic_cast<QVWorker*>(toCont)) != NULL) {
00195                                 worker->unlinkProperty(fromProp, worker2, toProp);
00196                         }
00197                         else if((canvas = dynamic_cast<QVImageCanvas*>(toCont)) != NULL) {
00198 //                              canvas->unlink(worker, fromProp);
00199                         }
00200                         else if((plot = dynamic_cast<QVPlot*>(toCont)) != NULL) {
00201                                 plot->unlink(worker, fromProp);
00202                         }
00203                 }
00204         }
00205         return TRUE;
00206 }
00207 
00208 template <class Type> bool DesignerGUI::setProperty(const QString fromName, const QString fromProp, const Type &value)
00209 {
00210         return false;
00211 }
00212 
00213 void DesignerGUI::processChange(QVPropertyContainerChange change)
00214 {
00215         switch (change.getChangeType())
00216         {
00217         case QVPropertyContainerChange::Name:
00218                 if (createdItems.contains(change.getSourceName()))
00219                         ;//std::cout << change.toString().toStdString() << std::endl;
00220                 break;
00221 
00222 /*      case QVPropertyContainerChange::ContainerAdd:
00223                 std::cout << change.toString().toStdString() << std::endl;
00224                 break;*/
00225 
00226         case QVPropertyContainerChange::ContainerDel:
00227                 {
00228                         QString name = change.getSourceName();
00229                         containers.remove(name);
00230                         createdItems.remove(name);
00231                         slate.delItemNode(name);
00232                 
00233                         // si se ha creado su dialogo, tambien lo borramos
00234                         if (dialogs.contains(name)) {
00235                                 delete dialogs.value(name);
00236                                 dialogs.remove(name);
00237                         }
00238                         //std::cout << change.toString().toStdString() << std::endl;
00239                 }
00240                 break;
00241 
00242         case QVPropertyContainerChange::PropertyAdd:
00243                 if (createdItems.contains(change.getSourceName()))
00244                 {
00245                         QString srcName = change.getSourceName();
00246                         QString propName = change.getPropName();
00247 
00248                         if (containers.contains(srcName))
00249                         {
00250                                 QVPropertyContainer *cont = containers.value(srcName);
00251                                 int type = cont->getPropertyType(propName);
00252                                 bool in = cont->isInput(propName);
00253                                 bool out = cont->isOutput(propName);
00254                                 slate.addProperty(srcName, propName, type, in, out);
00255                         }
00256                         //std::cout << change.toString().toStdString() << std::endl;
00257                 }
00258                 break;
00259 
00260         case QVPropertyContainerChange::PropertyDel:
00261                 if (createdItems.contains(change.getSourceName()))
00262                 {
00263                         QString srcName = change.getSourceName();
00264                         QString propName = change.getPropName();
00265                         slate.delProperty(srcName, propName);
00266                         //std::cout << change.toString().toStdString() << std::endl;
00267                 }
00268                 break;
00269 
00270         case QVPropertyContainerChange::PropertyValue:
00271                 break;
00272 
00273         case QVPropertyContainerChange::LinkAdd:
00274                 if ( createdItems.contains(change.getOrigName()) && createdItems.contains(change.getDestName()) )
00275                 {
00276                         QString fromName = change.getOrigName();
00277                         QString fromProp = change.getOrigProp();
00278                         QString toName = change.getDestName();
00279                         QString toProp = change.getDestProp();
00280                         QString linkName = fromName + "[" + fromProp + "] => " + toName + "[" + toProp + "]";
00281                         createdLinks.insert(linkName, CreatedLink(fromName, fromProp, toName, toProp, change.isSinc()));
00282                         slate.addLinkLine(fromName, fromProp, toName, toProp, change.isSinc());
00283                         //std::cout << change.toString().toStdString() << std::endl;
00284                 }
00285                 break;
00286 
00287         case QVPropertyContainerChange::LinkDel:
00288                 {
00289                         QString fromName = change.getOrigName();
00290                         QString fromProp = change.getOrigProp();
00291                         QString toName = change.getDestName();
00292                         QString toProp = change.getDestProp();
00293                         QString linkName = fromName + "[" + fromProp + "] => " + toName + "[" + toProp + "]";
00294                         if (createdLinks.contains(linkName))
00295                         {
00296                                 createdLinks.remove(linkName);
00297                                 slate.delLinkLine(fromName, fromProp, toName, toProp);
00298                                 //std::cout << change.toString().toStdString() << std::endl;
00299                         }
00300                 }
00301                 break;
00302 
00303         case QVPropertyContainerChange::All:
00304                 //std::cout << change.toString().toStdString() << std::endl;
00305                 break;
00306 
00307         default:
00308                 break;
00309         }
00310 }
00311 
00312 void DesignerGUI::showProperties(const QString itemName)
00313 {
00314         if (containers.contains(itemName)) {
00315                 if (dialogs.contains(itemName)) {
00316                         (dialogs.value(itemName))->show();
00317                 }
00318                 else {
00319                         if (createDialog(itemName))
00320                                 (dialogs.value(itemName))->show();
00321                 }
00322         }
00323 }
00324 
00325 bool DesignerGUI::createDialog(const QString itemName)
00326 {
00327         QVPropertyContainer *cont = containers.value(itemName);
00328         QVWorker* worker;
00329         QVMPlayerCamera* camera;
00330         if((worker = dynamic_cast<QVWorker*>(cont)) != NULL) {
00331                 dialogs.insert(itemName, new WorkerDialog(worker));
00332                 return true;
00333         }
00334         else if((camera = dynamic_cast<QVMPlayerCamera*>(cont)) != NULL) {
00335                 dialogs.insert(itemName, new CameraDialog(camera));
00336                 return true;
00337         }
00338         return false;
00339 }
00340 
00341 void DesignerGUI::run()
00342 {
00343         // creamos los dialogos que no se han creado aun, ya que después no se puede (porque no se puede lincar)
00344         foreach (QString itemName, containers.keys()) {
00345                 if (!dialogs.contains(itemName))
00346                         createDialog(itemName);
00347         }
00348 
00349         // y arrancamos la simulación
00350         qvApp->startItems();
00351 }
00352 
00353 void DesignerGUI::stop()
00354 {
00355         // detenemos la simulación (lo que desregistra los elementos del qvApp)
00356         qvApp->quitItems();
00357 
00358         // elimino los elementos antiguos, guardando la descripción de lo que tenía creado
00359         QList<CreatedItem> lastItems = createdItems.values();
00360         QList<CreatedLink> lastLinks = createdLinks.values();
00361         foreach (CreatedItem item, lastItems) {
00362                 QVPropertyContainer *cont = containers.value(item.name);
00363                 delete cont;
00364         }
00365 
00366         // creo otros iguales (registradolos en la lista "containers")
00367         foreach (CreatedItem item, lastItems) {
00368                 if (!addItem(item.type, item.name))
00369                         std::cerr << "DesignerGUI - resetItems(): error al crear el Item " + item.name.toStdString() + "\n";
00370         }
00371 
00372         // creo links iguales a los que teniamos para los nuevos items
00373         foreach (CreatedLink link, lastLinks) {
00374                 if (!addLink(link.fromName, link.fromProp, link.toName, link.toProp, link.synchronous))
00375                         std::cerr << "DesignerGUI - resetItems(): error al crear el Link " + link.fromName.toStdString() + " -> " + link.toName.toStdString() + "\n";
00376         }
00377 }
00378 
00379 void DesignerGUI::quit()
00380 {
00381         qvApp->deregisterGUI();
00382         qvApp->quit();
00383 }
00384