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