Generated on Tue Apr 18 10:21:46 2017 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: 2016-04-19 17:19:45 +0200 (Tue, 19 Apr 2016) $ by $Author: schulte $
00011  *     $Revision: 14967 $
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     labelBranches = new QAction("Label/clear branches", this);
00162     labelBranches->setShortcut(QKeySequence("L"));
00163     connect(labelBranches, SIGNAL(triggered()),
00164             canvas, SLOT(labelBranches()));
00165 
00166     labelPath = new QAction("Label/clear path", this);
00167     labelPath->setShortcut(QKeySequence("Shift+L"));
00168     connect(labelPath, SIGNAL(triggered()),
00169             canvas, SLOT(labelPath()));
00170 
00171     toggleStop = new QAction("Stop/unstop", this);
00172     toggleStop->setShortcut(QKeySequence("X"));
00173     connect(toggleStop, SIGNAL(triggered()), canvas, SLOT(toggleStop()));
00174 
00175     unstopAll = new QAction("Do not stop in subtree", this);
00176     unstopAll->setShortcut(QKeySequence("Shift+X"));
00177     connect(unstopAll, SIGNAL(triggered()), canvas, SLOT(unstopAll()));
00178 
00179     zoomToFit = new QAction("Zoom to fit", this);
00180     zoomToFit->setShortcut(QKeySequence("Z"));
00181     connect(zoomToFit, SIGNAL(triggered()), canvas, SLOT(zoomToFit()));
00182 
00183     center = new QAction("Center current node", this);
00184     center->setShortcut(QKeySequence("C"));
00185     connect(center, SIGNAL(triggered()), canvas, SLOT(centerCurrentNode()));
00186 
00187     exportPDF = new QAction("Export subtree PDF...", this);
00188     exportPDF->setShortcut(QKeySequence("P"));
00189     connect(exportPDF, SIGNAL(triggered()), canvas,
00190             SLOT(exportPDF()));
00191 
00192     exportWholeTreePDF = new QAction("Export PDF...", this);
00193     exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P"));
00194     connect(exportWholeTreePDF, SIGNAL(triggered()), canvas,
00195             SLOT(exportWholeTreePDF()));
00196 
00197     print = new QAction("Print...", this);
00198     print->setShortcut(QKeySequence("Ctrl+P"));
00199     connect(print, SIGNAL(triggered()), canvas,
00200             SLOT(print()));
00201 
00202     bookmarkNode = new QAction("Add/remove bookmark", this);
00203     bookmarkNode->setShortcut(QKeySequence("Shift+B"));
00204     connect(bookmarkNode, SIGNAL(triggered()), canvas, SLOT(bookmarkNode()));
00205 
00206     compareNode = new QAction("Compare", this);
00207     compareNode->setShortcut(QKeySequence("V"));
00208     connect(compareNode, SIGNAL(triggered()),
00209             canvas, SLOT(startCompareNodes()));
00210 
00211     compareNodeBeforeFP = new QAction("Compare before fixpoint", this);
00212     compareNodeBeforeFP->setShortcut(QKeySequence("Ctrl+V"));
00213     connect(compareNodeBeforeFP, SIGNAL(triggered()),
00214             canvas, SLOT(startCompareNodesBeforeFP()));
00215 
00216     connect(canvas, SIGNAL(addedBookmark(const QString&)),
00217             this, SLOT(addBookmark(const QString&)));
00218     connect(canvas, SIGNAL(removedBookmark(int)),
00219             this, SLOT(removeBookmark(int)));
00220 
00221     nullBookmark = new QAction("<none>",this);
00222     nullBookmark->setCheckable(true);
00223     nullBookmark->setChecked(false);
00224     nullBookmark->setEnabled(false);
00225     bookmarksGroup = new QActionGroup(this);
00226     bookmarksGroup->setExclusive(false);
00227     bookmarksGroup->addAction(nullBookmark);
00228     connect(bookmarksGroup, SIGNAL(triggered(QAction*)),
00229             this, SLOT(selectBookmark(QAction*)));
00230 
00231     bookmarksMenu = new QMenu("Bookmarks");
00232     connect(bookmarksMenu, SIGNAL(aboutToShow()),
00233             this, SLOT(populateBookmarksMenu()));
00234 
00235 
00236     setPath = new QAction("Set path", this);
00237     setPath->setShortcut(QKeySequence("Shift+P"));
00238     connect(setPath, SIGNAL(triggered()), canvas, SLOT(setPath()));
00239 
00240     inspectPath = new QAction("Inspect path", this);
00241     inspectPath->setShortcut(QKeySequence("Shift+I"));
00242     connect(inspectPath, SIGNAL(triggered()), canvas, SLOT(inspectPath()));
00243 
00244     showNodeStats = new QAction("Node statistics", this);
00245     showNodeStats->setShortcut(QKeySequence("S"));
00246     connect(showNodeStats, SIGNAL(triggered()),
00247             this, SLOT(showStats()));
00248 
00249     addAction(inspect);
00250     addAction(inspectBeforeFP);
00251     addAction(compareNode);
00252     addAction(compareNodeBeforeFP);
00253     addAction(stop);
00254     addAction(reset);
00255     addAction(navUp);
00256     addAction(navDown);
00257     addAction(navLeft);
00258     addAction(navRight);
00259     addAction(navRoot);
00260     addAction(navNextSol);
00261     addAction(navPrevSol);
00262 
00263     addAction(searchNext);
00264     addAction(searchAll);
00265     addAction(toggleHidden);
00266     addAction(hideFailed);
00267     addAction(unhideAll);
00268     addAction(labelBranches);
00269     addAction(labelPath);
00270     addAction(toggleStop);
00271     addAction(unstopAll);
00272     addAction(zoomToFit);
00273     addAction(center);
00274     addAction(exportPDF);
00275     addAction(exportWholeTreePDF);
00276     addAction(print);
00277 
00278     addAction(setPath);
00279     addAction(inspectPath);
00280     addAction(showNodeStats);
00281 
00282     nullSolutionInspector = new QAction("<none>",this);
00283     nullSolutionInspector->setCheckable(true);
00284     nullSolutionInspector->setChecked(false);
00285     nullSolutionInspector->setEnabled(false);
00286     solutionInspectorGroup = new QActionGroup(this);
00287     solutionInspectorGroup->setExclusive(false);
00288     solutionInspectorGroup->addAction(nullSolutionInspector);
00289     connect(solutionInspectorGroup, SIGNAL(triggered(QAction*)),
00290             this, SLOT(selectSolutionInspector(QAction*)));
00291 
00292     nullDoubleClickInspector = new QAction("<none>",this);
00293     nullDoubleClickInspector->setCheckable(true);
00294     nullDoubleClickInspector->setChecked(false);
00295     nullDoubleClickInspector->setEnabled(false);
00296     doubleClickInspectorGroup = new QActionGroup(this);
00297     doubleClickInspectorGroup->setExclusive(false);
00298     doubleClickInspectorGroup->addAction(nullDoubleClickInspector);
00299     connect(doubleClickInspectorGroup, SIGNAL(triggered(QAction*)),
00300             this, SLOT(selectDoubleClickInspector(QAction*)));
00301 
00302     nullMoveInspector = new QAction("<none>",this);
00303     nullMoveInspector->setCheckable(true);
00304     nullMoveInspector->setChecked(false);
00305     nullMoveInspector->setEnabled(false);
00306     moveInspectorGroup = new QActionGroup(this);
00307     moveInspectorGroup->setExclusive(false);
00308     moveInspectorGroup->addAction(nullMoveInspector);
00309     connect(moveInspectorGroup, SIGNAL(triggered(QAction*)),
00310             this, SLOT(selectMoveInspector(QAction*)));
00311 
00312     nullComparator = new QAction("<none>",this);
00313     nullComparator->setCheckable(true);
00314     nullComparator->setChecked(false);
00315     nullComparator->setEnabled(false);
00316     comparatorGroup = new QActionGroup(this);
00317     comparatorGroup->setExclusive(false);
00318     comparatorGroup->addAction(nullComparator);
00319     connect(comparatorGroup, SIGNAL(triggered(QAction*)),
00320             this, SLOT(selectComparator(QAction*)));
00321 
00322     solutionInspectorMenu = new QMenu("Solution inspectors");
00323     solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
00324     doubleClickInspectorMenu = new QMenu("Double click inspectors");
00325     doubleClickInspectorMenu->addActions(
00326       doubleClickInspectorGroup->actions());
00327     moveInspectorMenu = new QMenu("Move inspectors");
00328     moveInspectorMenu->addActions(moveInspectorGroup->actions());
00329     comparatorMenu = new QMenu("Comparators");
00330     comparatorMenu->addActions(comparatorGroup->actions());
00331 
00332     inspectGroup = new QActionGroup(this);
00333     connect(inspectGroup, SIGNAL(triggered(QAction*)),
00334             this, SLOT(inspectWithAction(QAction*)));
00335     inspectBeforeFPGroup = new QActionGroup(this);
00336     connect(inspectBeforeFPGroup, SIGNAL(triggered(QAction*)),
00337             this, SLOT(inspectBeforeFPWithAction(QAction*)));
00338 
00339     inspectNodeMenu = new QMenu("Inspect");
00340     inspectNodeMenu->addAction(inspect);
00341     connect(inspectNodeMenu, SIGNAL(aboutToShow()),
00342             this, SLOT(populateInspectors()));
00343 
00344     inspectNodeBeforeFPMenu = new QMenu("Inspect before fixpoint");
00345     inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
00346     connect(inspectNodeBeforeFPMenu, SIGNAL(aboutToShow()),
00347             this, SLOT(populateInspectors()));
00348     populateInspectors();
00349 
00350     contextMenu = new QMenu(this);
00351     contextMenu->addMenu(inspectNodeMenu);
00352     contextMenu->addMenu(inspectNodeBeforeFPMenu);
00353     contextMenu->addAction(compareNode);
00354     contextMenu->addAction(compareNodeBeforeFP);
00355     contextMenu->addAction(showNodeStats);
00356     contextMenu->addAction(center);
00357 
00358     contextMenu->addSeparator();
00359 
00360     contextMenu->addAction(searchNext);
00361     contextMenu->addAction(searchAll);
00362 
00363     contextMenu->addSeparator();
00364 
00365     contextMenu->addAction(toggleHidden);
00366     contextMenu->addAction(hideFailed);
00367     contextMenu->addAction(unhideAll);
00368     contextMenu->addAction(labelBranches);
00369     contextMenu->addAction(labelPath);
00370 
00371     contextMenu->addAction(toggleStop);
00372     contextMenu->addAction(unstopAll);
00373 
00374     contextMenu->addSeparator();
00375 
00376     contextMenu->addMenu(bookmarksMenu);
00377     contextMenu->addAction(setPath);
00378     contextMenu->addAction(inspectPath);
00379 
00380     contextMenu->addSeparator();
00381 
00382     contextMenu->addMenu(doubleClickInspectorMenu);
00383     contextMenu->addMenu(solutionInspectorMenu);
00384     contextMenu->addMenu(moveInspectorMenu);
00385 
00386     connect(autoZoomButton, SIGNAL(toggled(bool)), canvas,
00387             SLOT(setAutoZoom(bool)));
00388 
00389     connect(canvas, SIGNAL(autoZoomChanged(bool)),
00390             autoZoomButton, SLOT(setChecked(bool)));
00391 
00392     {
00393       unsigned int i = 0;
00394       while (opt.inspect.solution(i)) {
00395         addSolutionInspector(opt.inspect.solution(i++));
00396       }
00397       i = 0;
00398       while (opt.inspect.click(i)) {
00399         addDoubleClickInspector(opt.inspect.click(i++));
00400       }
00401       i = 0;
00402       while (opt.inspect.move(i)) {
00403         addMoveInspector(opt.inspect.move(i++));
00404       }
00405       i = 0;
00406       while (opt.inspect.compare(i)) {
00407         addComparator(opt.inspect.compare(i++));
00408       }
00409     }
00410 
00411 
00412     layout->addWidget(scrollArea, 0,0,-1,1);
00413     layout->addWidget(canvas->scaleBar, 1,1, Qt::AlignHCenter);
00414     layout->addWidget(autoZoomButton, 0,1, Qt::AlignHCenter);
00415 
00416     setLayout(layout);
00417 
00418     canvas->show();
00419 
00420     resize(500, 400);
00421 
00422     // enables on_<sender>_<signal>() mechanism
00423     QMetaObject::connectSlotsByName(this);
00424   }
00425 
00426   void
00427   Gist::resizeEvent(QResizeEvent*) {
00428     canvas->resizeToOuter();
00429   }
00430 
00431   void
00432   Gist::addInspector(Inspector* i0, QAction*& nas, QAction*& nad,
00433                      QAction*&nam) {
00434     if (doubleClickInspectorGroup->
00435       actions().indexOf(nullDoubleClickInspector) != -1) {
00436       doubleClickInspectorGroup->removeAction(nullDoubleClickInspector);
00437       solutionInspectorGroup->removeAction(nullSolutionInspector);
00438       moveInspectorGroup->removeAction(nullMoveInspector);
00439     }
00440     canvas->addSolutionInspector(i0);
00441     canvas->addDoubleClickInspector(i0);
00442     canvas->addMoveInspector(i0);
00443 
00444     nas = new QAction(i0->name().c_str(), this);
00445     nas->setCheckable(true);
00446     solutionInspectorGroup->addAction(nas);
00447     solutionInspectorMenu->clear();
00448     solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
00449 
00450     nad = new QAction(i0->name().c_str(), this);
00451     nad->setCheckable(true);
00452     doubleClickInspectorGroup->addAction(nad);
00453     doubleClickInspectorMenu->clear();
00454     doubleClickInspectorMenu->addActions(
00455       doubleClickInspectorGroup->actions());
00456 
00457     nam = new QAction(i0->name().c_str(), this);
00458     nam->setCheckable(true);
00459     moveInspectorGroup->addAction(nam);
00460     moveInspectorMenu->clear();
00461     moveInspectorMenu->addActions(
00462       moveInspectorGroup->actions());
00463 
00464     QAction* ia = new QAction(i0->name().c_str(), this);
00465     inspectGroup->addAction(ia);
00466     QAction* ibfpa = new QAction(i0->name().c_str(), this);
00467     inspectBeforeFPGroup->addAction(ibfpa);
00468 
00469     if (inspectGroup->actions().size() < 10) {
00470       ia->setShortcut(QKeySequence(QString("Ctrl+")+
00471         QString("").setNum(inspectGroup->actions().size())));
00472       ibfpa->setShortcut(QKeySequence(QString("Ctrl+Alt+")+
00473         QString("").setNum(inspectBeforeFPGroup->actions().size())));
00474     }
00475   }
00476 
00477   void
00478   Gist::addSolutionInspector(Inspector* ins) {
00479     QAction* nas;
00480     QAction* nad;
00481     QAction* nam;
00482     if (doubleClickInspectorGroup->
00483       actions().indexOf(nullDoubleClickInspector) == -1) {
00484       QList<QAction*> is = solutionInspectorGroup->actions();
00485       for (int i=0; i<is.size(); i++) {
00486         canvas->activateSolutionInspector(i,false);
00487         is[i]->setChecked(false);
00488       }
00489     }
00490     addInspector(ins, nas,nad,nam);
00491     nas->setChecked(true);
00492     selectSolutionInspector(nas);
00493   }
00494 
00495   void
00496   Gist::addDoubleClickInspector(Inspector* ins) {
00497     QAction* nas;
00498     QAction* nad;
00499     QAction* nam;
00500     if (doubleClickInspectorGroup->
00501       actions().indexOf(nullDoubleClickInspector) == -1) {
00502       QList<QAction*> is = doubleClickInspectorGroup->actions();
00503       for (int i=0; i<is.size(); i++) {
00504         canvas->activateDoubleClickInspector(i,false);
00505         is[i]->setChecked(false);
00506       }
00507     }
00508     addInspector(ins, nas,nad,nam);
00509     nad->setChecked(true);
00510     selectDoubleClickInspector(nad);
00511   }
00512 
00513   void
00514   Gist::addMoveInspector(Inspector* ins) {
00515     QAction* nas;
00516     QAction* nad;
00517     QAction* nam;
00518     if (doubleClickInspectorGroup->
00519       actions().indexOf(nullDoubleClickInspector) == -1) {
00520       QList<QAction*> is = moveInspectorGroup->actions();
00521       for (int i=0; i<is.size(); i++) {
00522         canvas->activateMoveInspector(i,false);
00523         is[i]->setChecked(false);
00524       }
00525     }
00526     addInspector(ins, nas,nad,nam);
00527     nam->setChecked(true);
00528     selectMoveInspector(nam);
00529   }
00530 
00531   void
00532   Gist::addComparator(Comparator* c) {
00533     if (comparatorGroup->actions().indexOf(nullComparator) == -1) {
00534       QList<QAction*> is = comparatorGroup->actions();
00535       for (int i=0; i<is.size(); i++) {
00536         canvas->activateComparator(i,false);
00537         is[i]->setChecked(false);
00538       }
00539     } else {
00540       comparatorGroup->removeAction(nullComparator);
00541     }
00542     canvas->addComparator(c);
00543 
00544     QAction* ncs = new QAction(c->name().c_str(), this);
00545     ncs->setCheckable(true);
00546     comparatorGroup->addAction(ncs);
00547     comparatorMenu->clear();
00548     comparatorMenu->addActions(comparatorGroup->actions());
00549     ncs->setChecked(true);
00550     selectComparator(ncs);
00551   }
00552 
00553   Gist::~Gist(void) { delete canvas; }
00554 
00555   void
00556   Gist::on_canvas_contextMenu(QContextMenuEvent* event) {
00557     contextMenu->popup(event->globalPos());
00558   }
00559 
00560   void
00561   Gist::on_canvas_statusChanged(VisualNode* n, const Statistics& stats,
00562                                 bool finished) {
00563     nodeStatInspector->node(*canvas->na,n,stats,finished);
00564     if (!finished) {
00565       inspect->setEnabled(false);
00566       inspectGroup->setEnabled(false);
00567       inspectBeforeFP->setEnabled(false);
00568       inspectBeforeFPGroup->setEnabled(false);
00569       compareNode->setEnabled(false);
00570       compareNodeBeforeFP->setEnabled(false);
00571       showNodeStats->setEnabled(false);
00572       stop->setEnabled(true);
00573       reset->setEnabled(false);
00574       navUp->setEnabled(false);
00575       navDown->setEnabled(false);
00576       navLeft->setEnabled(false);
00577       navRight->setEnabled(false);
00578       navRoot->setEnabled(false);
00579       navNextSol->setEnabled(false);
00580       navPrevSol->setEnabled(false);
00581 
00582       searchNext->setEnabled(false);
00583       searchAll->setEnabled(false);
00584       toggleHidden->setEnabled(false);
00585       hideFailed->setEnabled(false);
00586       unhideAll->setEnabled(false);
00587       labelBranches->setEnabled(false);
00588       labelPath->setEnabled(false);
00589 
00590       toggleStop->setEnabled(false);
00591       unstopAll->setEnabled(false);
00592 
00593       center->setEnabled(false);
00594       exportPDF->setEnabled(false);
00595       exportWholeTreePDF->setEnabled(false);
00596       print->setEnabled(false);
00597 
00598       setPath->setEnabled(false);
00599       inspectPath->setEnabled(false);
00600       bookmarkNode->setEnabled(false);
00601       bookmarksGroup->setEnabled(false);
00602     } else {
00603       stop->setEnabled(false);
00604       reset->setEnabled(true);
00605 
00606       if ( (n->isOpen() || n->hasOpenChildren()) && (!n->isHidden()) ) {
00607         searchNext->setEnabled(true);
00608         searchAll->setEnabled(true);
00609       } else {
00610         searchNext->setEnabled(false);
00611         searchAll->setEnabled(false);
00612       }
00613       if (n->getNumberOfChildren() > 0) {
00614         navDown->setEnabled(true);
00615         toggleHidden->setEnabled(true);
00616         hideFailed->setEnabled(true);
00617         unhideAll->setEnabled(true);
00618         unstopAll->setEnabled(true);
00619       } else {
00620         navDown->setEnabled(false);
00621         toggleHidden->setEnabled(false);
00622         hideFailed->setEnabled(false);
00623         unhideAll->setEnabled(false);
00624         unstopAll->setEnabled(false);
00625       }
00626 
00627       toggleStop->setEnabled(n->getStatus() == STOP ||
00628         n->getStatus() == UNSTOP);
00629 
00630       showNodeStats->setEnabled(true);
00631       inspect->setEnabled(true);
00632       labelPath->setEnabled(true);
00633       if (n->getStatus() == UNDETERMINED) {
00634         inspectGroup->setEnabled(false);
00635         inspectBeforeFP->setEnabled(false);
00636         inspectBeforeFPGroup->setEnabled(false);
00637         compareNode->setEnabled(false);
00638         compareNodeBeforeFP->setEnabled(false);
00639         labelBranches->setEnabled(false);
00640       } else {
00641         inspectGroup->setEnabled(true);
00642         inspectBeforeFP->setEnabled(true);
00643         inspectBeforeFPGroup->setEnabled(true);
00644         compareNode->setEnabled(true);
00645         compareNodeBeforeFP->setEnabled(true);
00646         labelBranches->setEnabled(!n->isHidden());
00647       }
00648 
00649       navRoot->setEnabled(true);
00650       VisualNode* p = n->getParent(*canvas->na);
00651       if (p == NULL) {
00652         inspectBeforeFP->setEnabled(false);
00653         inspectBeforeFPGroup->setEnabled(false);
00654         navUp->setEnabled(false);
00655         navRight->setEnabled(false);
00656         navLeft->setEnabled(false);
00657       } else {
00658         navUp->setEnabled(true);
00659         unsigned int alt = n->getAlternative(*canvas->na);
00660         navRight->setEnabled(alt + 1 < p->getNumberOfChildren());
00661         navLeft->setEnabled(alt > 0);
00662       }
00663 
00664       VisualNode* root = n;
00665       while (!root->isRoot())
00666         root = root->getParent(*canvas->na);
00667       NextSolCursor nsc(n, false, *canvas->na);
00668       PreorderNodeVisitor<NextSolCursor> nsv(nsc);
00669       nsv.run();
00670       navNextSol->setEnabled(nsv.getCursor().node() != root);
00671 
00672       NextSolCursor psc(n, true, *canvas->na);
00673       PreorderNodeVisitor<NextSolCursor> psv(psc);
00674       psv.run();
00675       navPrevSol->setEnabled(psv.getCursor().node() != root);
00676 
00677       center->setEnabled(true);
00678       exportPDF->setEnabled(true);
00679       exportWholeTreePDF->setEnabled(true);
00680       print->setEnabled(true);
00681 
00682       setPath->setEnabled(true);
00683       inspectPath->setEnabled(true);
00684 
00685       bookmarkNode->setEnabled(true);
00686       bookmarksGroup->setEnabled(true);
00687     }
00688     emit statusChanged(stats,finished);
00689   }
00690 
00691   void
00692   Gist::inspectWithAction(QAction* a) {
00693     canvas->inspectCurrentNode(true,inspectGroup->actions().indexOf(a));
00694   }
00695 
00696   void
00697   Gist::inspectBeforeFPWithAction(QAction* a) {
00698     canvas->inspectCurrentNode(false,
00699       inspectBeforeFPGroup->actions().indexOf(a));
00700   }
00701 
00702   bool
00703   Gist::finish(void) {
00704     return canvas->finish();
00705   }
00706 
00707   void
00708   Gist::selectDoubleClickInspector(QAction* a) {
00709     canvas->activateDoubleClickInspector(
00710       doubleClickInspectorGroup->actions().indexOf(a),
00711       a->isChecked());
00712   }
00713   void
00714   Gist::selectSolutionInspector(QAction* a) {
00715     canvas->activateSolutionInspector(
00716       solutionInspectorGroup->actions().indexOf(a),
00717       a->isChecked());
00718   }
00719   void
00720   Gist::selectMoveInspector(QAction* a) {
00721     canvas->activateMoveInspector(
00722       moveInspectorGroup->actions().indexOf(a),
00723       a->isChecked());
00724   }
00725   void
00726   Gist::selectComparator(QAction* a) {
00727     canvas->activateComparator(comparatorGroup->actions().indexOf(a),
00728       a->isChecked());
00729   }
00730   void
00731   Gist::selectBookmark(QAction* a) {
00732     int idx = bookmarksGroup->actions().indexOf(a);
00733     canvas->setCurrentNode(canvas->bookmarks[idx]);
00734     canvas->centerCurrentNode();
00735   }
00736 
00737   void
00738   Gist::addBookmark(const QString& id) {
00739     if (bookmarksGroup->actions().indexOf(nullBookmark) != -1) {
00740       bookmarksGroup->removeAction(nullBookmark);
00741     }
00742 
00743     QAction* nb = new QAction(id, this);
00744     nb->setCheckable(true);
00745     bookmarksGroup->addAction(nb);
00746   }
00747 
00748   void
00749   Gist::removeBookmark(int idx) {
00750     QAction* a = bookmarksGroup->actions()[idx];
00751     bookmarksGroup->removeAction(a);
00752     if (bookmarksGroup->actions().size() == 0) {
00753       bookmarksGroup->addAction(nullBookmark);
00754     }
00755   }
00756 
00757   void
00758   Gist::populateBookmarksMenu(void) {
00759     bookmarksMenu->clear();
00760     bookmarksMenu->addAction(bookmarkNode);
00761     bookmarksMenu->addSeparator();
00762     bookmarksMenu->addActions(bookmarksGroup->actions());
00763   }
00764 
00765   void
00766   Gist::populateInspectors(void) {
00767     inspectNodeMenu->clear();
00768     inspectNodeMenu->addAction(inspect);
00769     inspectNodeMenu->addSeparator();
00770     inspectNodeMenu->addActions(inspectGroup->actions());
00771     inspectNodeBeforeFPMenu->clear();
00772     inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
00773     inspectNodeBeforeFPMenu->addSeparator();
00774     inspectNodeBeforeFPMenu->addActions(inspectBeforeFPGroup->actions());
00775   }
00776 
00777   void
00778   Gist::setAutoHideFailed(bool b) { canvas->setAutoHideFailed(b); }
00779   void
00780   Gist::setAutoZoom(bool b) { canvas->setAutoZoom(b); }
00781   bool
00782   Gist::getAutoHideFailed(void) { return canvas->getAutoHideFailed(); }
00783   bool
00784   Gist::getAutoZoom(void) { return canvas->getAutoZoom(); }
00785   void
00786   Gist::setRefresh(int i) { canvas->setRefresh(i); }
00787   void
00788   Gist::setRefreshPause(int i) { canvas->setRefreshPause(i); }
00789   bool
00790   Gist::getSmoothScrollAndZoom(void) {
00791     return canvas->getSmoothScrollAndZoom();
00792   }
00793   void
00794   Gist::setSmoothScrollAndZoom(bool b) {
00795     canvas->setSmoothScrollAndZoom(b);
00796   }
00797   bool
00798   Gist::getMoveDuringSearch(void) {
00799     return canvas->getMoveDuringSearch();
00800   }
00801   void
00802   Gist::setMoveDuringSearch(bool b) {
00803     canvas->setMoveDuringSearch(b);
00804   }
00805   void
00806   Gist::setRecompDistances(int c_d, int a_d) {
00807     canvas->setRecompDistances(c_d, a_d);
00808   }
00809 
00810   int
00811   Gist::getCd(void) {
00812     return canvas->c_d;
00813   }
00814   int
00815   Gist::getAd(void) {
00816     return canvas->a_d;
00817   }
00818 
00819   void
00820   Gist::setShowCopies(bool b) {
00821     canvas->setShowCopies(b);
00822   }
00823   bool
00824   Gist::getShowCopies(void) {
00825     return canvas->getShowCopies();
00826   }
00827 
00828   void
00829   Gist::showStats(void) {
00830     nodeStatInspector->showStats();
00831     canvas->emitStatusChanged();
00832   }
00833 
00834 }}
00835 
00836 // STATISTICS: gist-any