Generated on Thu Mar 22 10:39:32 2012 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  *  Last modified:
00010  *     $Date: 2011-05-31 11:01:28 +0200 (Tue, 31 May 2011) $ by $Author: tack $
00011  *     $Revision: 12032 $
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(QString("Ctrl+")+
00457         QString("").setNum(inspectGroup->actions().size())));
00458       ibfpa->setShortcut(QKeySequence(QString("Ctrl+Alt+")+
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       center->setEnabled(false);
00578       exportPDF->setEnabled(false);
00579       exportWholeTreePDF->setEnabled(false);
00580       print->setEnabled(false);
00581 
00582       setPath->setEnabled(false);
00583       inspectPath->setEnabled(false);
00584       bookmarkNode->setEnabled(false);
00585       bookmarksGroup->setEnabled(false);
00586     } else {
00587       stop->setEnabled(false);
00588       reset->setEnabled(true);
00589 
00590       if ( (n->isOpen() || n->hasOpenChildren()) && (!n->isHidden()) ) {
00591         searchNext->setEnabled(true);
00592         searchAll->setEnabled(true);
00593       } else {
00594         searchNext->setEnabled(false);
00595         searchAll->setEnabled(false);
00596       }
00597       if (n->getNumberOfChildren() > 0) {
00598         navDown->setEnabled(true);
00599         toggleHidden->setEnabled(true);
00600         hideFailed->setEnabled(true);
00601         unhideAll->setEnabled(true);
00602         unstopAll->setEnabled(true);
00603       } else {
00604         navDown->setEnabled(false);
00605         toggleHidden->setEnabled(false);
00606         hideFailed->setEnabled(false);
00607         unhideAll->setEnabled(false);
00608         unstopAll->setEnabled(false);
00609       }
00610       
00611       toggleStop->setEnabled(n->getStatus() == STOP ||
00612         n->getStatus() == UNSTOP);
00613 
00614       showNodeStats->setEnabled(true);
00615       inspect->setEnabled(true);
00616       if (n->getStatus() == UNDETERMINED) {
00617         inspectGroup->setEnabled(false);
00618         inspectBeforeFP->setEnabled(false);
00619         inspectBeforeFPGroup->setEnabled(false);
00620         compareNode->setEnabled(false);
00621         compareNodeBeforeFP->setEnabled(false);
00622       } else {
00623         inspectGroup->setEnabled(true);        
00624         inspectBeforeFP->setEnabled(true);
00625         inspectBeforeFPGroup->setEnabled(true);
00626         compareNode->setEnabled(true);
00627         compareNodeBeforeFP->setEnabled(true);
00628       }
00629 
00630       navRoot->setEnabled(true);
00631       VisualNode* p = n->getParent(*canvas->na);
00632       if (p == NULL) {
00633         inspectBeforeFP->setEnabled(false);
00634         inspectBeforeFPGroup->setEnabled(false);
00635         navUp->setEnabled(false);
00636         navRight->setEnabled(false);
00637         navLeft->setEnabled(false);
00638       } else {
00639         navUp->setEnabled(true);
00640         unsigned int alt = n->getAlternative(*canvas->na);
00641         navRight->setEnabled(alt + 1 < p->getNumberOfChildren());
00642         navLeft->setEnabled(alt > 0);
00643       }
00644 
00645       VisualNode* root = n;
00646       while (!root->isRoot())
00647         root = root->getParent(*canvas->na);
00648       NextSolCursor nsc(n, false, *canvas->na);
00649       PreorderNodeVisitor<NextSolCursor> nsv(nsc);
00650       nsv.run();
00651       navNextSol->setEnabled(nsv.getCursor().node() != root);
00652 
00653       NextSolCursor psc(n, true, *canvas->na);
00654       PreorderNodeVisitor<NextSolCursor> psv(psc);
00655       psv.run();
00656       navPrevSol->setEnabled(psv.getCursor().node() != root);
00657 
00658       center->setEnabled(true);
00659       exportPDF->setEnabled(true);
00660       exportWholeTreePDF->setEnabled(true);
00661       print->setEnabled(true);
00662 
00663       setPath->setEnabled(true);
00664       inspectPath->setEnabled(true);
00665 
00666       bookmarkNode->setEnabled(true);
00667       bookmarksGroup->setEnabled(true);
00668     }
00669     emit statusChanged(stats,finished);
00670   }
00671 
00672   void
00673   Gist::inspectWithAction(QAction* a) {
00674     canvas->inspectCurrentNode(true,inspectGroup->actions().indexOf(a));
00675   }
00676 
00677   void
00678   Gist::inspectBeforeFPWithAction(QAction* a) {
00679     canvas->inspectCurrentNode(false,
00680       inspectBeforeFPGroup->actions().indexOf(a));
00681   }
00682 
00683   bool
00684   Gist::finish(void) {
00685     return canvas->finish();
00686   }
00687 
00688   void
00689   Gist::selectDoubleClickInspector(QAction* a) {
00690     canvas->activateDoubleClickInspector(
00691       doubleClickInspectorGroup->actions().indexOf(a),
00692       a->isChecked());
00693   }
00694   void
00695   Gist::selectSolutionInspector(QAction* a) {
00696     canvas->activateSolutionInspector(
00697       solutionInspectorGroup->actions().indexOf(a),
00698       a->isChecked());
00699   }
00700   void
00701   Gist::selectMoveInspector(QAction* a) {
00702     canvas->activateMoveInspector(
00703       moveInspectorGroup->actions().indexOf(a),
00704       a->isChecked());
00705   }
00706   void
00707   Gist::selectComparator(QAction* a) {
00708     canvas->activateComparator(comparatorGroup->actions().indexOf(a),
00709       a->isChecked());
00710   }
00711   void
00712   Gist::selectBookmark(QAction* a) {
00713     int idx = bookmarksGroup->actions().indexOf(a);
00714     canvas->setCurrentNode(canvas->bookmarks[idx]);
00715     canvas->centerCurrentNode();
00716   }
00717 
00718   void
00719   Gist::addBookmark(const QString& id) {
00720     if (bookmarksGroup->actions().indexOf(nullBookmark) != -1) {
00721       bookmarksGroup->removeAction(nullBookmark);
00722     }
00723 
00724     QAction* nb = new QAction(id, this);
00725     nb->setCheckable(true);
00726     bookmarksGroup->addAction(nb);
00727   }
00728 
00729   void
00730   Gist::removeBookmark(int idx) {
00731     QAction* a = bookmarksGroup->actions()[idx];
00732     bookmarksGroup->removeAction(a);
00733     if (bookmarksGroup->actions().size() == 0) {
00734       bookmarksGroup->addAction(nullBookmark);
00735     }
00736   }
00737   
00738   void
00739   Gist::populateBookmarksMenu(void) {
00740     bookmarksMenu->clear();
00741     bookmarksMenu->addAction(bookmarkNode);
00742     bookmarksMenu->addSeparator();
00743     bookmarksMenu->addActions(bookmarksGroup->actions());
00744   }
00745 
00746   void
00747   Gist::populateInspectors(void) {
00748     inspectNodeMenu->clear();
00749     inspectNodeMenu->addAction(inspect);
00750     inspectNodeMenu->addSeparator();
00751     inspectNodeMenu->addActions(inspectGroup->actions());
00752     inspectNodeBeforeFPMenu->clear();
00753     inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
00754     inspectNodeBeforeFPMenu->addSeparator();
00755     inspectNodeBeforeFPMenu->addActions(inspectBeforeFPGroup->actions());
00756   }
00757   
00758   void
00759   Gist::setAutoHideFailed(bool b) { canvas->setAutoHideFailed(b); }
00760   void
00761   Gist::setAutoZoom(bool b) { canvas->setAutoZoom(b); }
00762   bool
00763   Gist::getAutoHideFailed(void) { return canvas->getAutoHideFailed(); }
00764   bool
00765   Gist::getAutoZoom(void) { return canvas->getAutoZoom(); }
00766   void
00767   Gist::setRefresh(int i) { canvas->setRefresh(i); }
00768   void
00769   Gist::setRefreshPause(int i) { canvas->setRefreshPause(i); }
00770   bool
00771   Gist::getSmoothScrollAndZoom(void) {
00772     return canvas->getSmoothScrollAndZoom();
00773   }
00774   void
00775   Gist::setSmoothScrollAndZoom(bool b) {
00776     canvas->setSmoothScrollAndZoom(b);
00777   }
00778   void
00779   Gist::setRecompDistances(int c_d, int a_d) {
00780     canvas->setRecompDistances(c_d, a_d);
00781   }
00782 
00783   int
00784   Gist::getCd(void) {
00785     return canvas->c_d;
00786   }
00787   int
00788   Gist::getAd(void) {
00789     return canvas->a_d;
00790   }
00791 
00792   void
00793   Gist::setShowCopies(bool b) {
00794     canvas->setShowCopies(b);
00795   }
00796   bool
00797   Gist::getShowCopies(void) {
00798     return canvas->getShowCopies();
00799   }
00800 
00801   void
00802   Gist::showStats(void) {
00803     nodeStatInspector->showStats();
00804     canvas->emitStatusChanged();
00805   }
00806 
00807 }}
00808 
00809 // STATISTICS: gist-any