Generated on Tue May 22 09:39:53 2018 for Gecode by doxygen 1.6.3

qtgist.cpp

Go to the documentation of this file.
00001 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
00002 /*
00003  *  Main authors:
00004  *     Guido Tack <tack@gecode.org>
00005  *
00006  *  Copyright:
00007  *     Guido Tack, 2006
00008  *
00009  *  This file is part of Gecode, the generic constraint
00010  *  development environment:
00011  *     http://www.gecode.org
00012  *
00013  * Permission is hereby granted, free of charge, to any person obtaining
00014  * a copy of this software and associated documentation files (the
00015  * "Software"), to deal in the Software without restriction, including
00016  * without limitation the rights to use, copy, modify, merge, publish,
00017  * distribute, sublicense, and/or sell copies of the Software, and to
00018  * permit persons to whom the Software is furnished to do so, subject to
00019  * the following conditions:
00020  *
00021  * The above copyright notice and this permission notice shall be
00022  * included in all copies or substantial portions of the Software.
00023  *
00024  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00025  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00026  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00027  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
00028  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
00029  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
00030  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00031  *
00032  */
00033 
00034 #include <gecode/gist/qtgist.hh>
00035 
00036 #include <gecode/gist/zoomToFitIcon.hpp>
00037 #include <gecode/gist/nodevisitor.hh>
00038 #include <gecode/gist/nodecursor.hh>
00039 
00040 namespace Gecode { namespace Gist {
00041 
00042   Gist::Gist(Space* root, bool bab, QWidget* parent,
00043              const Options& opt) : QWidget(parent) {
00044     QGridLayout* layout = new QGridLayout(this);
00045 
00046     QAbstractScrollArea* scrollArea = new QAbstractScrollArea(this);
00047 
00048     scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
00049     scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
00050     scrollArea->setAutoFillBackground(true);
00051     QPalette myPalette(scrollArea->palette());
00052     myPalette.setColor(QPalette::Window, Qt::white);
00053     scrollArea->setPalette(myPalette);
00054     canvas = new TreeCanvas(root, bab, scrollArea->viewport(),opt);
00055     canvas->setPalette(myPalette);
00056     canvas->setObjectName("canvas");
00057 
00058     connect(scrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)),
00059             canvas, SLOT(scroll(void)));
00060     connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)),
00061             canvas, SLOT(scroll(void)));
00062 
00063     QVBoxLayout* sa_layout = new QVBoxLayout();
00064     sa_layout->setContentsMargins(0,0,0,0);
00065     sa_layout->addWidget(canvas);
00066     scrollArea->viewport()->setLayout(sa_layout);
00067 
00068     connect(canvas, SIGNAL(solution(const Space*)),
00069             this, SIGNAL(solution(const Space*)));
00070 
00071     connect(canvas, SIGNAL(searchFinished(void)), this, SIGNAL(searchFinished(void)));
00072 
00073     QPixmap myPic;
00074     myPic.loadFromData(zoomToFitIcon, sizeof(zoomToFitIcon));
00075 
00076     QToolButton* autoZoomButton = new QToolButton();
00077     autoZoomButton->setCheckable(true);
00078     autoZoomButton->setIcon(myPic);
00079 
00080     nodeStatInspector = new NodeStatInspector(this);
00081 
00082     inspect = new QAction("Inspect", this);
00083     inspect->setShortcut(QKeySequence("Return"));
00084     connect(inspect, SIGNAL(triggered()), canvas,
00085                        SLOT(inspectCurrentNode()));
00086 
00087     inspectBeforeFP = new QAction("Inspect before fixpoint", this);
00088     inspectBeforeFP->setShortcut(QKeySequence("Ctrl+Return"));
00089     connect(inspectBeforeFP, SIGNAL(triggered()), canvas,
00090             SLOT(inspectBeforeFP(void)));
00091 
00092     stop = new QAction("Stop search", this);
00093     stop->setShortcut(QKeySequence("Esc"));
00094     connect(stop, SIGNAL(triggered()), canvas,
00095                     SLOT(stopSearch()));
00096 
00097     reset = new QAction("Reset", this);
00098     reset->setShortcut(QKeySequence("Ctrl+R"));
00099     connect(reset, SIGNAL(triggered()), canvas,
00100             SLOT(reset()));
00101 
00102     navUp = new QAction("Up", this);
00103     navUp->setShortcut(QKeySequence("Up"));
00104     connect(navUp, SIGNAL(triggered()), canvas,
00105                    SLOT(navUp()));
00106 
00107     navDown = new QAction("Down", this);
00108     navDown->setShortcut(QKeySequence("Down"));
00109     connect(navDown, SIGNAL(triggered()), canvas,
00110                      SLOT(navDown()));
00111 
00112     navLeft = new QAction("Left", this);
00113     navLeft->setShortcut(QKeySequence("Left"));
00114     connect(navLeft, SIGNAL(triggered()), canvas,
00115                      SLOT(navLeft()));
00116 
00117     navRight = new QAction("Right", this);
00118     navRight->setShortcut(QKeySequence("Right"));
00119     connect(navRight, SIGNAL(triggered()), canvas,
00120                       SLOT(navRight()));
00121 
00122     navRoot = new QAction("Root", this);
00123     navRoot->setShortcut(QKeySequence("R"));
00124     connect(navRoot, SIGNAL(triggered()), canvas,
00125                       SLOT(navRoot()));
00126 
00127     navNextSol = new QAction("To next solution", this);
00128     navNextSol->setShortcut(QKeySequence("Shift+Right"));
00129     connect(navNextSol, SIGNAL(triggered()), canvas,
00130                       SLOT(navNextSol()));
00131 
00132     navPrevSol = new QAction("To previous solution", this);
00133     navPrevSol->setShortcut(QKeySequence("Shift+Left"));
00134     connect(navPrevSol, SIGNAL(triggered()), canvas,
00135                       SLOT(navPrevSol()));
00136 
00137     searchNext = new QAction("Next solution", this);
00138     searchNext->setShortcut(QKeySequence("N"));
00139     connect(searchNext, SIGNAL(triggered()), canvas, SLOT(searchOne()));
00140 
00141     searchAll = new QAction("All solutions", this);
00142     searchAll->setShortcut(QKeySequence("A"));
00143     connect(searchAll, SIGNAL(triggered()), canvas, SLOT(searchAll()));
00144 
00145     toggleHidden = new QAction("Hide/unhide", this);
00146     toggleHidden->setShortcut(QKeySequence("H"));
00147     connect(toggleHidden, SIGNAL(triggered()), canvas, SLOT(toggleHidden()));
00148 
00149     hideFailed = new QAction("Hide failed subtrees", this);
00150     hideFailed->setShortcut(QKeySequence("F"));
00151     connect(hideFailed, SIGNAL(triggered()), canvas, SLOT(hideFailed()));
00152 
00153     unhideAll = new QAction("Unhide all", this);
00154     unhideAll->setShortcut(QKeySequence("U"));
00155     connect(unhideAll, SIGNAL(triggered()), canvas, SLOT(unhideAll()));
00156 
00157     labelBranches = new QAction("Label/clear branches", this);
00158     labelBranches->setShortcut(QKeySequence("L"));
00159     connect(labelBranches, SIGNAL(triggered()),
00160             canvas, SLOT(labelBranches()));
00161 
00162     labelPath = new QAction("Label/clear path", this);
00163     labelPath->setShortcut(QKeySequence("Shift+L"));
00164     connect(labelPath, SIGNAL(triggered()),
00165             canvas, SLOT(labelPath()));
00166 
00167     toggleStop = new QAction("Stop/unstop", this);
00168     toggleStop->setShortcut(QKeySequence("X"));
00169     connect(toggleStop, SIGNAL(triggered()), canvas, SLOT(toggleStop()));
00170 
00171     unstopAll = new QAction("Do not stop in subtree", this);
00172     unstopAll->setShortcut(QKeySequence("Shift+X"));
00173     connect(unstopAll, SIGNAL(triggered()), canvas, SLOT(unstopAll()));
00174 
00175     zoomToFit = new QAction("Zoom to fit", this);
00176     zoomToFit->setShortcut(QKeySequence("Z"));
00177     connect(zoomToFit, SIGNAL(triggered()), canvas, SLOT(zoomToFit()));
00178 
00179     center = new QAction("Center current node", this);
00180     center->setShortcut(QKeySequence("C"));
00181     connect(center, SIGNAL(triggered()), canvas, SLOT(centerCurrentNode()));
00182 
00183     exportPDF = new QAction("Export subtree PDF...", this);
00184     exportPDF->setShortcut(QKeySequence("P"));
00185     connect(exportPDF, SIGNAL(triggered()), canvas,
00186             SLOT(exportPDF()));
00187 
00188     exportWholeTreePDF = new QAction("Export PDF...", this);
00189     exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P"));
00190     connect(exportWholeTreePDF, SIGNAL(triggered()), canvas,
00191             SLOT(exportWholeTreePDF()));
00192 
00193     print = new QAction("Print...", this);
00194     print->setShortcut(QKeySequence("Ctrl+P"));
00195     connect(print, SIGNAL(triggered()), canvas,
00196             SLOT(print()));
00197 
00198     bookmarkNode = new QAction("Add/remove bookmark", this);
00199     bookmarkNode->setShortcut(QKeySequence("Shift+B"));
00200     connect(bookmarkNode, SIGNAL(triggered()), canvas, SLOT(bookmarkNode()));
00201 
00202     compareNode = new QAction("Compare", this);
00203     compareNode->setShortcut(QKeySequence("V"));
00204     connect(compareNode, SIGNAL(triggered()),
00205             canvas, SLOT(startCompareNodes()));
00206 
00207     compareNodeBeforeFP = new QAction("Compare before fixpoint", this);
00208     compareNodeBeforeFP->setShortcut(QKeySequence("Ctrl+V"));
00209     connect(compareNodeBeforeFP, SIGNAL(triggered()),
00210             canvas, SLOT(startCompareNodesBeforeFP()));
00211 
00212     connect(canvas, SIGNAL(addedBookmark(const QString&)),
00213             this, SLOT(addBookmark(const QString&)));
00214     connect(canvas, SIGNAL(removedBookmark(int)),
00215             this, SLOT(removeBookmark(int)));
00216 
00217     nullBookmark = new QAction("<none>",this);
00218     nullBookmark->setCheckable(true);
00219     nullBookmark->setChecked(false);
00220     nullBookmark->setEnabled(false);
00221     bookmarksGroup = new QActionGroup(this);
00222     bookmarksGroup->setExclusive(false);
00223     bookmarksGroup->addAction(nullBookmark);
00224     connect(bookmarksGroup, SIGNAL(triggered(QAction*)),
00225             this, SLOT(selectBookmark(QAction*)));
00226 
00227     bookmarksMenu = new QMenu("Bookmarks");
00228     connect(bookmarksMenu, SIGNAL(aboutToShow()),
00229             this, SLOT(populateBookmarksMenu()));
00230 
00231 
00232     setPath = new QAction("Set path", this);
00233     setPath->setShortcut(QKeySequence("Shift+P"));
00234     connect(setPath, SIGNAL(triggered()), canvas, SLOT(setPath()));
00235 
00236     inspectPath = new QAction("Inspect path", this);
00237     inspectPath->setShortcut(QKeySequence("Shift+I"));
00238     connect(inspectPath, SIGNAL(triggered()), canvas, SLOT(inspectPath()));
00239 
00240     showNodeStats = new QAction("Node statistics", this);
00241     showNodeStats->setShortcut(QKeySequence("S"));
00242     connect(showNodeStats, SIGNAL(triggered()),
00243             this, SLOT(showStats()));
00244 
00245     addAction(inspect);
00246     addAction(inspectBeforeFP);
00247     addAction(compareNode);
00248     addAction(compareNodeBeforeFP);
00249     addAction(stop);
00250     addAction(reset);
00251     addAction(navUp);
00252     addAction(navDown);
00253     addAction(navLeft);
00254     addAction(navRight);
00255     addAction(navRoot);
00256     addAction(navNextSol);
00257     addAction(navPrevSol);
00258 
00259     addAction(searchNext);
00260     addAction(searchAll);
00261     addAction(toggleHidden);
00262     addAction(hideFailed);
00263     addAction(unhideAll);
00264     addAction(labelBranches);
00265     addAction(labelPath);
00266     addAction(toggleStop);
00267     addAction(unstopAll);
00268     addAction(zoomToFit);
00269     addAction(center);
00270     addAction(exportPDF);
00271     addAction(exportWholeTreePDF);
00272     addAction(print);
00273 
00274     addAction(setPath);
00275     addAction(inspectPath);
00276     addAction(showNodeStats);
00277 
00278     nullSolutionInspector = new QAction("<none>",this);
00279     nullSolutionInspector->setCheckable(true);
00280     nullSolutionInspector->setChecked(false);
00281     nullSolutionInspector->setEnabled(false);
00282     solutionInspectorGroup = new QActionGroup(this);
00283     solutionInspectorGroup->setExclusive(false);
00284     solutionInspectorGroup->addAction(nullSolutionInspector);
00285     connect(solutionInspectorGroup, SIGNAL(triggered(QAction*)),
00286             this, SLOT(selectSolutionInspector(QAction*)));
00287 
00288     nullDoubleClickInspector = new QAction("<none>",this);
00289     nullDoubleClickInspector->setCheckable(true);
00290     nullDoubleClickInspector->setChecked(false);
00291     nullDoubleClickInspector->setEnabled(false);
00292     doubleClickInspectorGroup = new QActionGroup(this);
00293     doubleClickInspectorGroup->setExclusive(false);
00294     doubleClickInspectorGroup->addAction(nullDoubleClickInspector);
00295     connect(doubleClickInspectorGroup, SIGNAL(triggered(QAction*)),
00296             this, SLOT(selectDoubleClickInspector(QAction*)));
00297 
00298     nullMoveInspector = new QAction("<none>",this);
00299     nullMoveInspector->setCheckable(true);
00300     nullMoveInspector->setChecked(false);
00301     nullMoveInspector->setEnabled(false);
00302     moveInspectorGroup = new QActionGroup(this);
00303     moveInspectorGroup->setExclusive(false);
00304     moveInspectorGroup->addAction(nullMoveInspector);
00305     connect(moveInspectorGroup, SIGNAL(triggered(QAction*)),
00306             this, SLOT(selectMoveInspector(QAction*)));
00307 
00308     nullComparator = new QAction("<none>",this);
00309     nullComparator->setCheckable(true);
00310     nullComparator->setChecked(false);
00311     nullComparator->setEnabled(false);
00312     comparatorGroup = new QActionGroup(this);
00313     comparatorGroup->setExclusive(false);
00314     comparatorGroup->addAction(nullComparator);
00315     connect(comparatorGroup, SIGNAL(triggered(QAction*)),
00316             this, SLOT(selectComparator(QAction*)));
00317 
00318     solutionInspectorMenu = new QMenu("Solution inspectors");
00319     solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
00320     doubleClickInspectorMenu = new QMenu("Double click inspectors");
00321     doubleClickInspectorMenu->addActions(
00322       doubleClickInspectorGroup->actions());
00323     moveInspectorMenu = new QMenu("Move inspectors");
00324     moveInspectorMenu->addActions(moveInspectorGroup->actions());
00325     comparatorMenu = new QMenu("Comparators");
00326     comparatorMenu->addActions(comparatorGroup->actions());
00327 
00328     inspectGroup = new QActionGroup(this);
00329     connect(inspectGroup, SIGNAL(triggered(QAction*)),
00330             this, SLOT(inspectWithAction(QAction*)));
00331     inspectBeforeFPGroup = new QActionGroup(this);
00332     connect(inspectBeforeFPGroup, SIGNAL(triggered(QAction*)),
00333             this, SLOT(inspectBeforeFPWithAction(QAction*)));
00334 
00335     inspectNodeMenu = new QMenu("Inspect");
00336     inspectNodeMenu->addAction(inspect);
00337     connect(inspectNodeMenu, SIGNAL(aboutToShow()),
00338             this, SLOT(populateInspectors()));
00339 
00340     inspectNodeBeforeFPMenu = new QMenu("Inspect before fixpoint");
00341     inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
00342     connect(inspectNodeBeforeFPMenu, SIGNAL(aboutToShow()),
00343             this, SLOT(populateInspectors()));
00344     populateInspectors();
00345 
00346     contextMenu = new QMenu(this);
00347     contextMenu->addMenu(inspectNodeMenu);
00348     contextMenu->addMenu(inspectNodeBeforeFPMenu);
00349     contextMenu->addAction(compareNode);
00350     contextMenu->addAction(compareNodeBeforeFP);
00351     contextMenu->addAction(showNodeStats);
00352     contextMenu->addAction(center);
00353 
00354     contextMenu->addSeparator();
00355 
00356     contextMenu->addAction(searchNext);
00357     contextMenu->addAction(searchAll);
00358 
00359     contextMenu->addSeparator();
00360 
00361     contextMenu->addAction(toggleHidden);
00362     contextMenu->addAction(hideFailed);
00363     contextMenu->addAction(unhideAll);
00364     contextMenu->addAction(labelBranches);
00365     contextMenu->addAction(labelPath);
00366 
00367     contextMenu->addAction(toggleStop);
00368     contextMenu->addAction(unstopAll);
00369 
00370     contextMenu->addSeparator();
00371 
00372     contextMenu->addMenu(bookmarksMenu);
00373     contextMenu->addAction(setPath);
00374     contextMenu->addAction(inspectPath);
00375 
00376     contextMenu->addSeparator();
00377 
00378     contextMenu->addMenu(doubleClickInspectorMenu);
00379     contextMenu->addMenu(solutionInspectorMenu);
00380     contextMenu->addMenu(moveInspectorMenu);
00381 
00382     connect(autoZoomButton, SIGNAL(toggled(bool)), canvas,
00383             SLOT(setAutoZoom(bool)));
00384 
00385     connect(canvas, SIGNAL(autoZoomChanged(bool)),
00386             autoZoomButton, SLOT(setChecked(bool)));
00387 
00388     {
00389       unsigned int i = 0;
00390       while (opt.inspect.solution(i)) {
00391         addSolutionInspector(opt.inspect.solution(i++));
00392       }
00393       i = 0;
00394       while (opt.inspect.click(i)) {
00395         addDoubleClickInspector(opt.inspect.click(i++));
00396       }
00397       i = 0;
00398       while (opt.inspect.move(i)) {
00399         addMoveInspector(opt.inspect.move(i++));
00400       }
00401       i = 0;
00402       while (opt.inspect.compare(i)) {
00403         addComparator(opt.inspect.compare(i++));
00404       }
00405     }
00406 
00407 
00408     layout->addWidget(scrollArea, 0,0,-1,1);
00409     layout->addWidget(canvas->scaleBar, 1,1, Qt::AlignHCenter);
00410     layout->addWidget(autoZoomButton, 0,1, Qt::AlignHCenter);
00411 
00412     setLayout(layout);
00413 
00414     canvas->show();
00415 
00416     resize(500, 400);
00417 
00418     // enables on_<sender>_<signal>() mechanism
00419     QMetaObject::connectSlotsByName(this);
00420   }
00421 
00422   void
00423   Gist::resizeEvent(QResizeEvent*) {
00424     canvas->resizeToOuter();
00425   }
00426 
00427   void
00428   Gist::addInspector(Inspector* i0, QAction*& nas, QAction*& nad,
00429                      QAction*&nam) {
00430     if (doubleClickInspectorGroup->
00431       actions().indexOf(nullDoubleClickInspector) != -1) {
00432       doubleClickInspectorGroup->removeAction(nullDoubleClickInspector);
00433       solutionInspectorGroup->removeAction(nullSolutionInspector);
00434       moveInspectorGroup->removeAction(nullMoveInspector);
00435     }
00436     canvas->addSolutionInspector(i0);
00437     canvas->addDoubleClickInspector(i0);
00438     canvas->addMoveInspector(i0);
00439 
00440     nas = new QAction(i0->name().c_str(), this);
00441     nas->setCheckable(true);
00442     solutionInspectorGroup->addAction(nas);
00443     solutionInspectorMenu->clear();
00444     solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
00445 
00446     nad = new QAction(i0->name().c_str(), this);
00447     nad->setCheckable(true);
00448     doubleClickInspectorGroup->addAction(nad);
00449     doubleClickInspectorMenu->clear();
00450     doubleClickInspectorMenu->addActions(
00451       doubleClickInspectorGroup->actions());
00452 
00453     nam = new QAction(i0->name().c_str(), this);
00454     nam->setCheckable(true);
00455     moveInspectorGroup->addAction(nam);
00456     moveInspectorMenu->clear();
00457     moveInspectorMenu->addActions(
00458       moveInspectorGroup->actions());
00459 
00460     QAction* ia = new QAction(i0->name().c_str(), this);
00461     inspectGroup->addAction(ia);
00462     QAction* ibfpa = new QAction(i0->name().c_str(), this);
00463     inspectBeforeFPGroup->addAction(ibfpa);
00464 
00465     if (inspectGroup->actions().size() < 10) {
00466       ia->setShortcut(QKeySequence(QString("Ctrl+")+
00467         QString("").setNum(inspectGroup->actions().size())));
00468       ibfpa->setShortcut(QKeySequence(QString("Ctrl+Alt+")+
00469         QString("").setNum(inspectBeforeFPGroup->actions().size())));
00470     }
00471   }
00472 
00473   void
00474   Gist::addSolutionInspector(Inspector* ins) {
00475     QAction* nas;
00476     QAction* nad;
00477     QAction* nam;
00478     if (doubleClickInspectorGroup->
00479       actions().indexOf(nullDoubleClickInspector) == -1) {
00480       QList<QAction*> is = solutionInspectorGroup->actions();
00481       for (int i=0; i<is.size(); i++) {
00482         canvas->activateSolutionInspector(i,false);
00483         is[i]->setChecked(false);
00484       }
00485     }
00486     addInspector(ins, nas,nad,nam);
00487     nas->setChecked(true);
00488     selectSolutionInspector(nas);
00489   }
00490 
00491   void
00492   Gist::addDoubleClickInspector(Inspector* ins) {
00493     QAction* nas;
00494     QAction* nad;
00495     QAction* nam;
00496     if (doubleClickInspectorGroup->
00497       actions().indexOf(nullDoubleClickInspector) == -1) {
00498       QList<QAction*> is = doubleClickInspectorGroup->actions();
00499       for (int i=0; i<is.size(); i++) {
00500         canvas->activateDoubleClickInspector(i,false);
00501         is[i]->setChecked(false);
00502       }
00503     }
00504     addInspector(ins, nas,nad,nam);
00505     nad->setChecked(true);
00506     selectDoubleClickInspector(nad);
00507   }
00508 
00509   void
00510   Gist::addMoveInspector(Inspector* ins) {
00511     QAction* nas;
00512     QAction* nad;
00513     QAction* nam;
00514     if (doubleClickInspectorGroup->
00515       actions().indexOf(nullDoubleClickInspector) == -1) {
00516       QList<QAction*> is = moveInspectorGroup->actions();
00517       for (int i=0; i<is.size(); i++) {
00518         canvas->activateMoveInspector(i,false);
00519         is[i]->setChecked(false);
00520       }
00521     }
00522     addInspector(ins, nas,nad,nam);
00523     nam->setChecked(true);
00524     selectMoveInspector(nam);
00525   }
00526 
00527   void
00528   Gist::addComparator(Comparator* c) {
00529     if (comparatorGroup->actions().indexOf(nullComparator) == -1) {
00530       QList<QAction*> is = comparatorGroup->actions();
00531       for (int i=0; i<is.size(); i++) {
00532         canvas->activateComparator(i,false);
00533         is[i]->setChecked(false);
00534       }
00535     } else {
00536       comparatorGroup->removeAction(nullComparator);
00537     }
00538     canvas->addComparator(c);
00539 
00540     QAction* ncs = new QAction(c->name().c_str(), this);
00541     ncs->setCheckable(true);
00542     comparatorGroup->addAction(ncs);
00543     comparatorMenu->clear();
00544     comparatorMenu->addActions(comparatorGroup->actions());
00545     ncs->setChecked(true);
00546     selectComparator(ncs);
00547   }
00548 
00549   Gist::~Gist(void) { delete canvas; }
00550 
00551   void
00552   Gist::on_canvas_contextMenu(QContextMenuEvent* event) {
00553     contextMenu->popup(event->globalPos());
00554   }
00555 
00556   void
00557   Gist::on_canvas_statusChanged(VisualNode* n, const Statistics& stats,
00558                                 bool finished) {
00559     nodeStatInspector->node(*canvas->na,n,stats,finished);
00560     if (!finished) {
00561       inspect->setEnabled(false);
00562       inspectGroup->setEnabled(false);
00563       inspectBeforeFP->setEnabled(false);
00564       inspectBeforeFPGroup->setEnabled(false);
00565       compareNode->setEnabled(false);
00566       compareNodeBeforeFP->setEnabled(false);
00567       showNodeStats->setEnabled(false);
00568       stop->setEnabled(true);
00569       reset->setEnabled(false);
00570       navUp->setEnabled(false);
00571       navDown->setEnabled(false);
00572       navLeft->setEnabled(false);
00573       navRight->setEnabled(false);
00574       navRoot->setEnabled(false);
00575       navNextSol->setEnabled(false);
00576       navPrevSol->setEnabled(false);
00577 
00578       searchNext->setEnabled(false);
00579       searchAll->setEnabled(false);
00580       toggleHidden->setEnabled(false);
00581       hideFailed->setEnabled(false);
00582       unhideAll->setEnabled(false);
00583       labelBranches->setEnabled(false);
00584       labelPath->setEnabled(false);
00585 
00586       toggleStop->setEnabled(false);
00587       unstopAll->setEnabled(false);
00588 
00589       center->setEnabled(false);
00590       exportPDF->setEnabled(false);
00591       exportWholeTreePDF->setEnabled(false);
00592       print->setEnabled(false);
00593 
00594       setPath->setEnabled(false);
00595       inspectPath->setEnabled(false);
00596       bookmarkNode->setEnabled(false);
00597       bookmarksGroup->setEnabled(false);
00598     } else {
00599       stop->setEnabled(false);
00600       reset->setEnabled(true);
00601 
00602       if ( (n->isOpen() || n->hasOpenChildren()) && (!n->isHidden()) ) {
00603         searchNext->setEnabled(true);
00604         searchAll->setEnabled(true);
00605       } else {
00606         searchNext->setEnabled(false);
00607         searchAll->setEnabled(false);
00608       }
00609       if (n->getNumberOfChildren() > 0) {
00610         navDown->setEnabled(true);
00611         toggleHidden->setEnabled(true);
00612         hideFailed->setEnabled(true);
00613         unhideAll->setEnabled(true);
00614         unstopAll->setEnabled(true);
00615       } else {
00616         navDown->setEnabled(false);
00617         toggleHidden->setEnabled(false);
00618         hideFailed->setEnabled(false);
00619         unhideAll->setEnabled(false);
00620         unstopAll->setEnabled(false);
00621       }
00622 
00623       toggleStop->setEnabled(n->getStatus() == STOP ||
00624         n->getStatus() == UNSTOP);
00625 
00626       showNodeStats->setEnabled(true);
00627       inspect->setEnabled(true);
00628       labelPath->setEnabled(true);
00629       if (n->getStatus() == UNDETERMINED) {
00630         inspectGroup->setEnabled(false);
00631         inspectBeforeFP->setEnabled(false);
00632         inspectBeforeFPGroup->setEnabled(false);
00633         compareNode->setEnabled(false);
00634         compareNodeBeforeFP->setEnabled(false);
00635         labelBranches->setEnabled(false);
00636       } else {
00637         inspectGroup->setEnabled(true);
00638         inspectBeforeFP->setEnabled(true);
00639         inspectBeforeFPGroup->setEnabled(true);
00640         compareNode->setEnabled(true);
00641         compareNodeBeforeFP->setEnabled(true);
00642         labelBranches->setEnabled(!n->isHidden());
00643       }
00644 
00645       navRoot->setEnabled(true);
00646       VisualNode* p = n->getParent(*canvas->na);
00647       if (p == NULL) {
00648         inspectBeforeFP->setEnabled(false);
00649         inspectBeforeFPGroup->setEnabled(false);
00650         navUp->setEnabled(false);
00651         navRight->setEnabled(false);
00652         navLeft->setEnabled(false);
00653       } else {
00654         navUp->setEnabled(true);
00655         unsigned int alt = n->getAlternative(*canvas->na);
00656         navRight->setEnabled(alt + 1 < p->getNumberOfChildren());
00657         navLeft->setEnabled(alt > 0);
00658       }
00659 
00660       VisualNode* root = n;
00661       while (!root->isRoot())
00662         root = root->getParent(*canvas->na);
00663       NextSolCursor nsc(n, false, *canvas->na);
00664       PreorderNodeVisitor<NextSolCursor> nsv(nsc);
00665       nsv.run();
00666       navNextSol->setEnabled(nsv.getCursor().node() != root);
00667 
00668       NextSolCursor psc(n, true, *canvas->na);
00669       PreorderNodeVisitor<NextSolCursor> psv(psc);
00670       psv.run();
00671       navPrevSol->setEnabled(psv.getCursor().node() != root);
00672 
00673       center->setEnabled(true);
00674       exportPDF->setEnabled(true);
00675       exportWholeTreePDF->setEnabled(true);
00676       print->setEnabled(true);
00677 
00678       setPath->setEnabled(true);
00679       inspectPath->setEnabled(true);
00680 
00681       bookmarkNode->setEnabled(true);
00682       bookmarksGroup->setEnabled(true);
00683     }
00684     emit statusChanged(stats,finished);
00685   }
00686 
00687   void
00688   Gist::inspectWithAction(QAction* a) {
00689     canvas->inspectCurrentNode(true,inspectGroup->actions().indexOf(a));
00690   }
00691 
00692   void
00693   Gist::inspectBeforeFPWithAction(QAction* a) {
00694     canvas->inspectCurrentNode(false,
00695       inspectBeforeFPGroup->actions().indexOf(a));
00696   }
00697 
00698   bool
00699   Gist::finish(void) {
00700     return canvas->finish();
00701   }
00702 
00703   void
00704   Gist::selectDoubleClickInspector(QAction* a) {
00705     canvas->activateDoubleClickInspector(
00706       doubleClickInspectorGroup->actions().indexOf(a),
00707       a->isChecked());
00708   }
00709   void
00710   Gist::selectSolutionInspector(QAction* a) {
00711     canvas->activateSolutionInspector(
00712       solutionInspectorGroup->actions().indexOf(a),
00713       a->isChecked());
00714   }
00715   void
00716   Gist::selectMoveInspector(QAction* a) {
00717     canvas->activateMoveInspector(
00718       moveInspectorGroup->actions().indexOf(a),
00719       a->isChecked());
00720   }
00721   void
00722   Gist::selectComparator(QAction* a) {
00723     canvas->activateComparator(comparatorGroup->actions().indexOf(a),
00724       a->isChecked());
00725   }
00726   void
00727   Gist::selectBookmark(QAction* a) {
00728     int idx = bookmarksGroup->actions().indexOf(a);
00729     canvas->setCurrentNode(canvas->bookmarks[idx]);
00730     canvas->centerCurrentNode();
00731   }
00732 
00733   void
00734   Gist::addBookmark(const QString& id) {
00735     if (bookmarksGroup->actions().indexOf(nullBookmark) != -1) {
00736       bookmarksGroup->removeAction(nullBookmark);
00737     }
00738 
00739     QAction* nb = new QAction(id, this);
00740     nb->setCheckable(true);
00741     bookmarksGroup->addAction(nb);
00742   }
00743 
00744   void
00745   Gist::removeBookmark(int idx) {
00746     QAction* a = bookmarksGroup->actions()[idx];
00747     bookmarksGroup->removeAction(a);
00748     if (bookmarksGroup->actions().size() == 0) {
00749       bookmarksGroup->addAction(nullBookmark);
00750     }
00751   }
00752 
00753   void
00754   Gist::populateBookmarksMenu(void) {
00755     bookmarksMenu->clear();
00756     bookmarksMenu->addAction(bookmarkNode);
00757     bookmarksMenu->addSeparator();
00758     bookmarksMenu->addActions(bookmarksGroup->actions());
00759   }
00760 
00761   void
00762   Gist::populateInspectors(void) {
00763     inspectNodeMenu->clear();
00764     inspectNodeMenu->addAction(inspect);
00765     inspectNodeMenu->addSeparator();
00766     inspectNodeMenu->addActions(inspectGroup->actions());
00767     inspectNodeBeforeFPMenu->clear();
00768     inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
00769     inspectNodeBeforeFPMenu->addSeparator();
00770     inspectNodeBeforeFPMenu->addActions(inspectBeforeFPGroup->actions());
00771   }
00772 
00773   void
00774   Gist::setAutoHideFailed(bool b) { canvas->setAutoHideFailed(b); }
00775   void
00776   Gist::setAutoZoom(bool b) { canvas->setAutoZoom(b); }
00777   bool
00778   Gist::getAutoHideFailed(void) { return canvas->getAutoHideFailed(); }
00779   bool
00780   Gist::getAutoZoom(void) { return canvas->getAutoZoom(); }
00781   void
00782   Gist::setRefresh(int i) { canvas->setRefresh(i); }
00783   void
00784   Gist::setRefreshPause(int i) { canvas->setRefreshPause(i); }
00785   bool
00786   Gist::getSmoothScrollAndZoom(void) {
00787     return canvas->getSmoothScrollAndZoom();
00788   }
00789   void
00790   Gist::setSmoothScrollAndZoom(bool b) {
00791     canvas->setSmoothScrollAndZoom(b);
00792   }
00793   bool
00794   Gist::getMoveDuringSearch(void) {
00795     return canvas->getMoveDuringSearch();
00796   }
00797   void
00798   Gist::setMoveDuringSearch(bool b) {
00799     canvas->setMoveDuringSearch(b);
00800   }
00801   void
00802   Gist::setRecompDistances(int c_d, int a_d) {
00803     canvas->setRecompDistances(c_d, a_d);
00804   }
00805 
00806   int
00807   Gist::getCd(void) {
00808     return canvas->c_d;
00809   }
00810   int
00811   Gist::getAd(void) {
00812     return canvas->a_d;
00813   }
00814 
00815   void
00816   Gist::setShowCopies(bool b) {
00817     canvas->setShowCopies(b);
00818   }
00819   bool
00820   Gist::getShowCopies(void) {
00821     return canvas->getShowCopies();
00822   }
00823 
00824   void
00825   Gist::showStats(void) {
00826     nodeStatInspector->showStats();
00827     canvas->emitStatusChanged();
00828   }
00829 
00830 }}
00831 
00832 // STATISTICS: gist-any