Generated on Thu Mar 13 2014 04:39:27 for Gecode by doxygen 1.8.1.2
qtgist.cpp
Go to the documentation of this file.
1 /* -*- mode: C++; c-basic-offset: 2; indent-tabs-mode: nil -*- */
2 /*
3  * Main authors:
4  * Guido Tack <tack@gecode.org>
5  *
6  * Copyright:
7  * Guido Tack, 2006
8  *
9  * Last modified:
10  * $Date: 2011-05-31 19:01:28 +1000 (Tue, 31 May 2011) $ by $Author: tack $
11  * $Revision: 12032 $
12  *
13  * This file is part of Gecode, the generic constraint
14  * development environment:
15  * http://www.gecode.org
16  *
17  * Permission is hereby granted, free of charge, to any person obtaining
18  * a copy of this software and associated documentation files (the
19  * "Software"), to deal in the Software without restriction, including
20  * without limitation the rights to use, copy, modify, merge, publish,
21  * distribute, sublicense, and/or sell copies of the Software, and to
22  * permit persons to whom the Software is furnished to do so, subject to
23  * the following conditions:
24  *
25  * The above copyright notice and this permission notice shall be
26  * included in all copies or substantial portions of the Software.
27  *
28  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
29  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
30  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
31  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
32  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
33  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
34  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35  *
36  */
37 
38 #include <gecode/gist/qtgist.hh>
39 
43 
44 namespace Gecode { namespace Gist {
45 
46  Gist::Gist(Space* root, bool bab, QWidget* parent,
47  const Options& opt) : QWidget(parent) {
48  QGridLayout* layout = new QGridLayout(this);
49 
50  QAbstractScrollArea* scrollArea = new QAbstractScrollArea(this);
51 
52  scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
53  scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
54  scrollArea->setAutoFillBackground(true);
55  QPalette myPalette(scrollArea->palette());
56  myPalette.setColor(QPalette::Window, Qt::white);
57  scrollArea->setPalette(myPalette);
58  canvas = new TreeCanvas(root, bab, scrollArea->viewport(),opt);
59  canvas->setPalette(myPalette);
60  canvas->setObjectName("canvas");
61 
62  connect(scrollArea->horizontalScrollBar(), SIGNAL(valueChanged(int)),
63  canvas, SLOT(scroll(void)));
64  connect(scrollArea->verticalScrollBar(), SIGNAL(valueChanged(int)),
65  canvas, SLOT(scroll(void)));
66 
67  QVBoxLayout* sa_layout = new QVBoxLayout();
68  sa_layout->setContentsMargins(0,0,0,0);
69  sa_layout->addWidget(canvas);
70  scrollArea->viewport()->setLayout(sa_layout);
71 
72  connect(canvas, SIGNAL(solution(const Space*)),
73  this, SIGNAL(solution(const Space*)));
74 
75  connect(canvas, SIGNAL(searchFinished(void)), this, SIGNAL(searchFinished(void)));
76 
77  QPixmap myPic;
78  myPic.loadFromData(zoomToFitIcon, sizeof(zoomToFitIcon));
79 
80  QToolButton* autoZoomButton = new QToolButton();
81  autoZoomButton->setCheckable(true);
82  autoZoomButton->setIcon(myPic);
83 
84  nodeStatInspector = new NodeStatInspector(this);
85 
86  inspect = new QAction("Inspect", this);
87  inspect->setShortcut(QKeySequence("Return"));
88  connect(inspect, SIGNAL(triggered()), canvas,
89  SLOT(inspectCurrentNode()));
90 
91  inspectBeforeFP = new QAction("Inspect before fixpoint", this);
92  inspectBeforeFP->setShortcut(QKeySequence("Ctrl+Return"));
93  connect(inspectBeforeFP, SIGNAL(triggered()), canvas,
94  SLOT(inspectBeforeFP(void)));
95 
96  stop = new QAction("Stop search", this);
97  stop->setShortcut(QKeySequence("Esc"));
98  connect(stop, SIGNAL(triggered()), canvas,
99  SLOT(stopSearch()));
100 
101  reset = new QAction("Reset", this);
102  reset->setShortcut(QKeySequence("Ctrl+R"));
103  connect(reset, SIGNAL(triggered()), canvas,
104  SLOT(reset()));
105 
106  navUp = new QAction("Up", this);
107  navUp->setShortcut(QKeySequence("Up"));
108  connect(navUp, SIGNAL(triggered()), canvas,
109  SLOT(navUp()));
110 
111  navDown = new QAction("Down", this);
112  navDown->setShortcut(QKeySequence("Down"));
113  connect(navDown, SIGNAL(triggered()), canvas,
114  SLOT(navDown()));
115 
116  navLeft = new QAction("Left", this);
117  navLeft->setShortcut(QKeySequence("Left"));
118  connect(navLeft, SIGNAL(triggered()), canvas,
119  SLOT(navLeft()));
120 
121  navRight = new QAction("Right", this);
122  navRight->setShortcut(QKeySequence("Right"));
123  connect(navRight, SIGNAL(triggered()), canvas,
124  SLOT(navRight()));
125 
126  navRoot = new QAction("Root", this);
127  navRoot->setShortcut(QKeySequence("R"));
128  connect(navRoot, SIGNAL(triggered()), canvas,
129  SLOT(navRoot()));
130 
131  navNextSol = new QAction("To next solution", this);
132  navNextSol->setShortcut(QKeySequence("Shift+Right"));
133  connect(navNextSol, SIGNAL(triggered()), canvas,
134  SLOT(navNextSol()));
135 
136  navPrevSol = new QAction("To previous solution", this);
137  navPrevSol->setShortcut(QKeySequence("Shift+Left"));
138  connect(navPrevSol, SIGNAL(triggered()), canvas,
139  SLOT(navPrevSol()));
140 
141  searchNext = new QAction("Next solution", this);
142  searchNext->setShortcut(QKeySequence("N"));
143  connect(searchNext, SIGNAL(triggered()), canvas, SLOT(searchOne()));
144 
145  searchAll = new QAction("All solutions", this);
146  searchAll->setShortcut(QKeySequence("A"));
147  connect(searchAll, SIGNAL(triggered()), canvas, SLOT(searchAll()));
148 
149  toggleHidden = new QAction("Hide/unhide", this);
150  toggleHidden->setShortcut(QKeySequence("H"));
151  connect(toggleHidden, SIGNAL(triggered()), canvas, SLOT(toggleHidden()));
152 
153  hideFailed = new QAction("Hide failed subtrees", this);
154  hideFailed->setShortcut(QKeySequence("F"));
155  connect(hideFailed, SIGNAL(triggered()), canvas, SLOT(hideFailed()));
156 
157  unhideAll = new QAction("Unhide all", this);
158  unhideAll->setShortcut(QKeySequence("U"));
159  connect(unhideAll, SIGNAL(triggered()), canvas, SLOT(unhideAll()));
160 
161  toggleStop = new QAction("Stop/unstop", this);
162  toggleStop->setShortcut(QKeySequence("X"));
163  connect(toggleStop, SIGNAL(triggered()), canvas, SLOT(toggleStop()));
164 
165  unstopAll = new QAction("Do not stop in subtree", this);
166  unstopAll->setShortcut(QKeySequence("Shift+X"));
167  connect(unstopAll, SIGNAL(triggered()), canvas, SLOT(unstopAll()));
168 
169  zoomToFit = new QAction("Zoom to fit", this);
170  zoomToFit->setShortcut(QKeySequence("Z"));
171  connect(zoomToFit, SIGNAL(triggered()), canvas, SLOT(zoomToFit()));
172 
173  center = new QAction("Center current node", this);
174  center->setShortcut(QKeySequence("C"));
175  connect(center, SIGNAL(triggered()), canvas, SLOT(centerCurrentNode()));
176 
177  exportPDF = new QAction("Export subtree PDF...", this);
178  exportPDF->setShortcut(QKeySequence("P"));
179  connect(exportPDF, SIGNAL(triggered()), canvas,
180  SLOT(exportPDF()));
181 
182  exportWholeTreePDF = new QAction("Export PDF...", this);
183  exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P"));
184  connect(exportWholeTreePDF, SIGNAL(triggered()), canvas,
185  SLOT(exportWholeTreePDF()));
186 
187  print = new QAction("Print...", this);
188  print->setShortcut(QKeySequence("Ctrl+P"));
189  connect(print, SIGNAL(triggered()), canvas,
190  SLOT(print()));
191 
192  bookmarkNode = new QAction("Add/remove bookmark", this);
193  bookmarkNode->setShortcut(QKeySequence("Shift+B"));
194  connect(bookmarkNode, SIGNAL(triggered()), canvas, SLOT(bookmarkNode()));
195 
196  compareNode = new QAction("Compare", this);
197  compareNode->setShortcut(QKeySequence("V"));
198  connect(compareNode, SIGNAL(triggered()),
199  canvas, SLOT(startCompareNodes()));
200 
201  compareNodeBeforeFP = new QAction("Compare before fixpoint", this);
202  compareNodeBeforeFP->setShortcut(QKeySequence("Ctrl+V"));
203  connect(compareNodeBeforeFP, SIGNAL(triggered()),
204  canvas, SLOT(startCompareNodesBeforeFP()));
205 
206  connect(canvas, SIGNAL(addedBookmark(const QString&)),
207  this, SLOT(addBookmark(const QString&)));
208  connect(canvas, SIGNAL(removedBookmark(int)),
209  this, SLOT(removeBookmark(int)));
210 
211  nullBookmark = new QAction("<none>",this);
212  nullBookmark->setCheckable(true);
213  nullBookmark->setChecked(false);
214  nullBookmark->setEnabled(false);
215  bookmarksGroup = new QActionGroup(this);
216  bookmarksGroup->setExclusive(false);
217  bookmarksGroup->addAction(nullBookmark);
218  connect(bookmarksGroup, SIGNAL(triggered(QAction*)),
219  this, SLOT(selectBookmark(QAction*)));
220 
221  bookmarksMenu = new QMenu("Bookmarks");
222  connect(bookmarksMenu, SIGNAL(aboutToShow()),
223  this, SLOT(populateBookmarksMenu()));
224 
225 
226  setPath = new QAction("Set path", this);
227  setPath->setShortcut(QKeySequence("Shift+P"));
228  connect(setPath, SIGNAL(triggered()), canvas, SLOT(setPath()));
229 
230  inspectPath = new QAction("Inspect path", this);
231  inspectPath->setShortcut(QKeySequence("Shift+I"));
232  connect(inspectPath, SIGNAL(triggered()), canvas, SLOT(inspectPath()));
233 
234  showNodeStats = new QAction("Node statistics", this);
235  showNodeStats->setShortcut(QKeySequence("S"));
236  connect(showNodeStats, SIGNAL(triggered()),
237  this, SLOT(showStats()));
238 
239  addAction(inspect);
240  addAction(inspectBeforeFP);
241  addAction(compareNode);
242  addAction(compareNodeBeforeFP);
243  addAction(stop);
244  addAction(reset);
245  addAction(navUp);
246  addAction(navDown);
247  addAction(navLeft);
248  addAction(navRight);
249  addAction(navRoot);
250  addAction(navNextSol);
251  addAction(navPrevSol);
252 
253  addAction(searchNext);
254  addAction(searchAll);
255  addAction(toggleHidden);
256  addAction(hideFailed);
257  addAction(unhideAll);
258  addAction(toggleStop);
259  addAction(unstopAll);
260  addAction(zoomToFit);
261  addAction(center);
262  addAction(exportPDF);
263  addAction(exportWholeTreePDF);
264  addAction(print);
265 
266  addAction(setPath);
267  addAction(inspectPath);
268  addAction(showNodeStats);
269 
270  nullSolutionInspector = new QAction("<none>",this);
271  nullSolutionInspector->setCheckable(true);
272  nullSolutionInspector->setChecked(false);
273  nullSolutionInspector->setEnabled(false);
274  solutionInspectorGroup = new QActionGroup(this);
275  solutionInspectorGroup->setExclusive(false);
276  solutionInspectorGroup->addAction(nullSolutionInspector);
277  connect(solutionInspectorGroup, SIGNAL(triggered(QAction*)),
278  this, SLOT(selectSolutionInspector(QAction*)));
279 
280  nullDoubleClickInspector = new QAction("<none>",this);
281  nullDoubleClickInspector->setCheckable(true);
282  nullDoubleClickInspector->setChecked(false);
283  nullDoubleClickInspector->setEnabled(false);
284  doubleClickInspectorGroup = new QActionGroup(this);
285  doubleClickInspectorGroup->setExclusive(false);
286  doubleClickInspectorGroup->addAction(nullDoubleClickInspector);
287  connect(doubleClickInspectorGroup, SIGNAL(triggered(QAction*)),
288  this, SLOT(selectDoubleClickInspector(QAction*)));
289 
290  nullMoveInspector = new QAction("<none>",this);
291  nullMoveInspector->setCheckable(true);
292  nullMoveInspector->setChecked(false);
293  nullMoveInspector->setEnabled(false);
294  moveInspectorGroup = new QActionGroup(this);
295  moveInspectorGroup->setExclusive(false);
296  moveInspectorGroup->addAction(nullMoveInspector);
297  connect(moveInspectorGroup, SIGNAL(triggered(QAction*)),
298  this, SLOT(selectMoveInspector(QAction*)));
299 
300  nullComparator = new QAction("<none>",this);
301  nullComparator->setCheckable(true);
302  nullComparator->setChecked(false);
303  nullComparator->setEnabled(false);
304  comparatorGroup = new QActionGroup(this);
305  comparatorGroup->setExclusive(false);
306  comparatorGroup->addAction(nullComparator);
307  connect(comparatorGroup, SIGNAL(triggered(QAction*)),
308  this, SLOT(selectComparator(QAction*)));
309 
310  solutionInspectorMenu = new QMenu("Solution inspectors");
311  solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
312  doubleClickInspectorMenu = new QMenu("Double click inspectors");
313  doubleClickInspectorMenu->addActions(
314  doubleClickInspectorGroup->actions());
315  moveInspectorMenu = new QMenu("Move inspectors");
316  moveInspectorMenu->addActions(moveInspectorGroup->actions());
317  comparatorMenu = new QMenu("Comparators");
318  comparatorMenu->addActions(comparatorGroup->actions());
319 
320  inspectGroup = new QActionGroup(this);
321  connect(inspectGroup, SIGNAL(triggered(QAction*)),
322  this, SLOT(inspectWithAction(QAction*)));
323  inspectBeforeFPGroup = new QActionGroup(this);
324  connect(inspectBeforeFPGroup, SIGNAL(triggered(QAction*)),
325  this, SLOT(inspectBeforeFPWithAction(QAction*)));
326 
327  inspectNodeMenu = new QMenu("Inspect");
328  inspectNodeMenu->addAction(inspect);
329  connect(inspectNodeMenu, SIGNAL(aboutToShow()),
330  this, SLOT(populateInspectors()));
331 
332  inspectNodeBeforeFPMenu = new QMenu("Inspect before fixpoint");
333  inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
334  connect(inspectNodeBeforeFPMenu, SIGNAL(aboutToShow()),
335  this, SLOT(populateInspectors()));
336  populateInspectors();
337 
338  contextMenu = new QMenu(this);
339  contextMenu->addMenu(inspectNodeMenu);
340  contextMenu->addMenu(inspectNodeBeforeFPMenu);
341  contextMenu->addAction(compareNode);
342  contextMenu->addAction(compareNodeBeforeFP);
343  contextMenu->addAction(showNodeStats);
344  contextMenu->addAction(center);
345 
346  contextMenu->addSeparator();
347 
348  contextMenu->addAction(searchNext);
349  contextMenu->addAction(searchAll);
350 
351  contextMenu->addSeparator();
352 
353  contextMenu->addAction(toggleHidden);
354  contextMenu->addAction(hideFailed);
355  contextMenu->addAction(unhideAll);
356 
357  contextMenu->addAction(toggleStop);
358  contextMenu->addAction(unstopAll);
359 
360  contextMenu->addSeparator();
361 
362  contextMenu->addMenu(bookmarksMenu);
363  contextMenu->addAction(setPath);
364  contextMenu->addAction(inspectPath);
365 
366  contextMenu->addSeparator();
367 
368  contextMenu->addMenu(doubleClickInspectorMenu);
369  contextMenu->addMenu(solutionInspectorMenu);
370  contextMenu->addMenu(moveInspectorMenu);
371 
372  connect(autoZoomButton, SIGNAL(toggled(bool)), canvas,
373  SLOT(setAutoZoom(bool)));
374 
375  connect(canvas, SIGNAL(autoZoomChanged(bool)),
376  autoZoomButton, SLOT(setChecked(bool)));
377 
378  {
379  unsigned int i = 0;
380  while (opt.inspect.solution(i)) {
382  }
383  i = 0;
384  while (opt.inspect.click(i)) {
386  }
387  i = 0;
388  while (opt.inspect.move(i)) {
389  addMoveInspector(opt.inspect.move(i++));
390  }
391  i = 0;
392  while (opt.inspect.compare(i)) {
393  addComparator(opt.inspect.compare(i++));
394  }
395  }
396 
397 
398  layout->addWidget(scrollArea, 0,0,-1,1);
399  layout->addWidget(canvas->scaleBar, 1,1, Qt::AlignHCenter);
400  layout->addWidget(autoZoomButton, 0,1, Qt::AlignHCenter);
401 
402  setLayout(layout);
403 
404  canvas->show();
405 
406  resize(500, 400);
407 
408  // enables on_<sender>_<signal>() mechanism
409  QMetaObject::connectSlotsByName(this);
410  }
411 
412  void
413  Gist::resizeEvent(QResizeEvent*) {
414  canvas->resizeToOuter();
415  }
416 
417  void
418  Gist::addInspector(Inspector* i0, QAction*& nas, QAction*& nad,
419  QAction*&nam) {
421  actions().indexOf(nullDoubleClickInspector) != -1) {
422  doubleClickInspectorGroup->removeAction(nullDoubleClickInspector);
423  solutionInspectorGroup->removeAction(nullSolutionInspector);
424  moveInspectorGroup->removeAction(nullMoveInspector);
425  }
426  canvas->addSolutionInspector(i0);
427  canvas->addDoubleClickInspector(i0);
428  canvas->addMoveInspector(i0);
429 
430  nas = new QAction(i0->name().c_str(), this);
431  nas->setCheckable(true);
432  solutionInspectorGroup->addAction(nas);
433  solutionInspectorMenu->clear();
434  solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
435 
436  nad = new QAction(i0->name().c_str(), this);
437  nad->setCheckable(true);
438  doubleClickInspectorGroup->addAction(nad);
439  doubleClickInspectorMenu->clear();
440  doubleClickInspectorMenu->addActions(
441  doubleClickInspectorGroup->actions());
442 
443  nam = new QAction(i0->name().c_str(), this);
444  nam->setCheckable(true);
445  moveInspectorGroup->addAction(nam);
446  moveInspectorMenu->clear();
447  moveInspectorMenu->addActions(
448  moveInspectorGroup->actions());
449 
450  QAction* ia = new QAction(i0->name().c_str(), this);
451  inspectGroup->addAction(ia);
452  QAction* ibfpa = new QAction(i0->name().c_str(), this);
453  inspectBeforeFPGroup->addAction(ibfpa);
454 
455  if (inspectGroup->actions().size() < 10) {
456  ia->setShortcut(QKeySequence(QString("Ctrl+")+
457  QString("").setNum(inspectGroup->actions().size())));
458  ibfpa->setShortcut(QKeySequence(QString("Ctrl+Alt+")+
459  QString("").setNum(inspectBeforeFPGroup->actions().size())));
460  }
461  }
462 
463  void
465  QAction* nas;
466  QAction* nad;
467  QAction* nam;
469  actions().indexOf(nullDoubleClickInspector) == -1) {
470  QList<QAction*> is = solutionInspectorGroup->actions();
471  for (int i=0; i<is.size(); i++) {
472  canvas->activateSolutionInspector(i,false);
473  is[i]->setChecked(false);
474  }
475  }
476  addInspector(ins, nas,nad,nam);
477  nas->setChecked(true);
478  selectSolutionInspector(nas);
479  }
480 
481  void
483  QAction* nas;
484  QAction* nad;
485  QAction* nam;
487  actions().indexOf(nullDoubleClickInspector) == -1) {
488  QList<QAction*> is = doubleClickInspectorGroup->actions();
489  for (int i=0; i<is.size(); i++) {
490  canvas->activateDoubleClickInspector(i,false);
491  is[i]->setChecked(false);
492  }
493  }
494  addInspector(ins, nas,nad,nam);
495  nad->setChecked(true);
496  selectDoubleClickInspector(nad);
497  }
498 
499  void
501  QAction* nas;
502  QAction* nad;
503  QAction* nam;
505  actions().indexOf(nullDoubleClickInspector) == -1) {
506  QList<QAction*> is = moveInspectorGroup->actions();
507  for (int i=0; i<is.size(); i++) {
508  canvas->activateMoveInspector(i,false);
509  is[i]->setChecked(false);
510  }
511  }
512  addInspector(ins, nas,nad,nam);
513  nam->setChecked(true);
514  selectMoveInspector(nam);
515  }
516 
517  void
519  if (comparatorGroup->actions().indexOf(nullComparator) == -1) {
520  QList<QAction*> is = comparatorGroup->actions();
521  for (int i=0; i<is.size(); i++) {
522  canvas->activateComparator(i,false);
523  is[i]->setChecked(false);
524  }
525  } else {
526  comparatorGroup->removeAction(nullComparator);
527  }
528  canvas->addComparator(c);
529 
530  QAction* ncs = new QAction(c->name().c_str(), this);
531  ncs->setCheckable(true);
532  comparatorGroup->addAction(ncs);
533  comparatorMenu->clear();
534  comparatorMenu->addActions(comparatorGroup->actions());
535  ncs->setChecked(true);
536  selectComparator(ncs);
537  }
538 
539  Gist::~Gist(void) { delete canvas; }
540 
541  void
542  Gist::on_canvas_contextMenu(QContextMenuEvent* event) {
543  contextMenu->popup(event->globalPos());
544  }
545 
546  void
547  Gist::on_canvas_statusChanged(VisualNode* n, const Statistics& stats,
548  bool finished) {
549  nodeStatInspector->node(*canvas->na,n,stats,finished);
550  if (!finished) {
551  inspect->setEnabled(false);
552  inspectGroup->setEnabled(false);
553  inspectBeforeFP->setEnabled(false);
554  inspectBeforeFPGroup->setEnabled(false);
555  compareNode->setEnabled(false);
556  compareNodeBeforeFP->setEnabled(false);
557  showNodeStats->setEnabled(false);
558  stop->setEnabled(true);
559  reset->setEnabled(false);
560  navUp->setEnabled(false);
561  navDown->setEnabled(false);
562  navLeft->setEnabled(false);
563  navRight->setEnabled(false);
564  navRoot->setEnabled(false);
565  navNextSol->setEnabled(false);
566  navPrevSol->setEnabled(false);
567 
568  searchNext->setEnabled(false);
569  searchAll->setEnabled(false);
570  toggleHidden->setEnabled(false);
571  hideFailed->setEnabled(false);
572  unhideAll->setEnabled(false);
573 
574  toggleStop->setEnabled(false);
575  unstopAll->setEnabled(false);
576 
577  center->setEnabled(false);
578  exportPDF->setEnabled(false);
579  exportWholeTreePDF->setEnabled(false);
580  print->setEnabled(false);
581 
582  setPath->setEnabled(false);
583  inspectPath->setEnabled(false);
584  bookmarkNode->setEnabled(false);
585  bookmarksGroup->setEnabled(false);
586  } else {
587  stop->setEnabled(false);
588  reset->setEnabled(true);
589 
590  if ( (n->isOpen() || n->hasOpenChildren()) && (!n->isHidden()) ) {
591  searchNext->setEnabled(true);
592  searchAll->setEnabled(true);
593  } else {
594  searchNext->setEnabled(false);
595  searchAll->setEnabled(false);
596  }
597  if (n->getNumberOfChildren() > 0) {
598  navDown->setEnabled(true);
599  toggleHidden->setEnabled(true);
600  hideFailed->setEnabled(true);
601  unhideAll->setEnabled(true);
602  unstopAll->setEnabled(true);
603  } else {
604  navDown->setEnabled(false);
605  toggleHidden->setEnabled(false);
606  hideFailed->setEnabled(false);
607  unhideAll->setEnabled(false);
608  unstopAll->setEnabled(false);
609  }
610 
611  toggleStop->setEnabled(n->getStatus() == STOP ||
612  n->getStatus() == UNSTOP);
613 
614  showNodeStats->setEnabled(true);
615  inspect->setEnabled(true);
616  if (n->getStatus() == UNDETERMINED) {
617  inspectGroup->setEnabled(false);
618  inspectBeforeFP->setEnabled(false);
619  inspectBeforeFPGroup->setEnabled(false);
620  compareNode->setEnabled(false);
621  compareNodeBeforeFP->setEnabled(false);
622  } else {
623  inspectGroup->setEnabled(true);
624  inspectBeforeFP->setEnabled(true);
625  inspectBeforeFPGroup->setEnabled(true);
626  compareNode->setEnabled(true);
627  compareNodeBeforeFP->setEnabled(true);
628  }
629 
630  navRoot->setEnabled(true);
631  VisualNode* p = n->getParent(*canvas->na);
632  if (p == NULL) {
633  inspectBeforeFP->setEnabled(false);
634  inspectBeforeFPGroup->setEnabled(false);
635  navUp->setEnabled(false);
636  navRight->setEnabled(false);
637  navLeft->setEnabled(false);
638  } else {
639  navUp->setEnabled(true);
640  unsigned int alt = n->getAlternative(*canvas->na);
641  navRight->setEnabled(alt + 1 < p->getNumberOfChildren());
642  navLeft->setEnabled(alt > 0);
643  }
644 
645  VisualNode* root = n;
646  while (!root->isRoot())
647  root = root->getParent(*canvas->na);
648  NextSolCursor nsc(n, false, *canvas->na);
649  PreorderNodeVisitor<NextSolCursor> nsv(nsc);
650  nsv.run();
651  navNextSol->setEnabled(nsv.getCursor().node() != root);
652 
653  NextSolCursor psc(n, true, *canvas->na);
654  PreorderNodeVisitor<NextSolCursor> psv(psc);
655  psv.run();
656  navPrevSol->setEnabled(psv.getCursor().node() != root);
657 
658  center->setEnabled(true);
659  exportPDF->setEnabled(true);
660  exportWholeTreePDF->setEnabled(true);
661  print->setEnabled(true);
662 
663  setPath->setEnabled(true);
664  inspectPath->setEnabled(true);
665 
666  bookmarkNode->setEnabled(true);
667  bookmarksGroup->setEnabled(true);
668  }
669  emit statusChanged(stats,finished);
670  }
671 
672  void
673  Gist::inspectWithAction(QAction* a) {
674  canvas->inspectCurrentNode(true,inspectGroup->actions().indexOf(a));
675  }
676 
677  void
678  Gist::inspectBeforeFPWithAction(QAction* a) {
679  canvas->inspectCurrentNode(false,
680  inspectBeforeFPGroup->actions().indexOf(a));
681  }
682 
683  bool
684  Gist::finish(void) {
685  return canvas->finish();
686  }
687 
688  void
689  Gist::selectDoubleClickInspector(QAction* a) {
691  doubleClickInspectorGroup->actions().indexOf(a),
692  a->isChecked());
693  }
694  void
695  Gist::selectSolutionInspector(QAction* a) {
697  solutionInspectorGroup->actions().indexOf(a),
698  a->isChecked());
699  }
700  void
701  Gist::selectMoveInspector(QAction* a) {
702  canvas->activateMoveInspector(
703  moveInspectorGroup->actions().indexOf(a),
704  a->isChecked());
705  }
706  void
707  Gist::selectComparator(QAction* a) {
708  canvas->activateComparator(comparatorGroup->actions().indexOf(a),
709  a->isChecked());
710  }
711  void
712  Gist::selectBookmark(QAction* a) {
713  int idx = bookmarksGroup->actions().indexOf(a);
714  canvas->setCurrentNode(canvas->bookmarks[idx]);
715  canvas->centerCurrentNode();
716  }
717 
718  void
719  Gist::addBookmark(const QString& id) {
720  if (bookmarksGroup->actions().indexOf(nullBookmark) != -1) {
721  bookmarksGroup->removeAction(nullBookmark);
722  }
723 
724  QAction* nb = new QAction(id, this);
725  nb->setCheckable(true);
726  bookmarksGroup->addAction(nb);
727  }
728 
729  void
730  Gist::removeBookmark(int idx) {
731  QAction* a = bookmarksGroup->actions()[idx];
732  bookmarksGroup->removeAction(a);
733  if (bookmarksGroup->actions().size() == 0) {
734  bookmarksGroup->addAction(nullBookmark);
735  }
736  }
737 
738  void
739  Gist::populateBookmarksMenu(void) {
740  bookmarksMenu->clear();
741  bookmarksMenu->addAction(bookmarkNode);
742  bookmarksMenu->addSeparator();
743  bookmarksMenu->addActions(bookmarksGroup->actions());
744  }
745 
746  void
747  Gist::populateInspectors(void) {
748  inspectNodeMenu->clear();
749  inspectNodeMenu->addAction(inspect);
750  inspectNodeMenu->addSeparator();
751  inspectNodeMenu->addActions(inspectGroup->actions());
752  inspectNodeBeforeFPMenu->clear();
753  inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
754  inspectNodeBeforeFPMenu->addSeparator();
755  inspectNodeBeforeFPMenu->addActions(inspectBeforeFPGroup->actions());
756  }
757 
758  void
760  void
761  Gist::setAutoZoom(bool b) { canvas->setAutoZoom(b); }
762  bool
763  Gist::getAutoHideFailed(void) { return canvas->getAutoHideFailed(); }
764  bool
765  Gist::getAutoZoom(void) { return canvas->getAutoZoom(); }
766  void
767  Gist::setRefresh(int i) { canvas->setRefresh(i); }
768  void
770  bool
772  return canvas->getSmoothScrollAndZoom();
773  }
774  void
776  canvas->setSmoothScrollAndZoom(b);
777  }
778  void
780  canvas->setRecompDistances(c_d, a_d);
781  }
782 
783  int
784  Gist::getCd(void) {
785  return canvas->c_d;
786  }
787  int
788  Gist::getAd(void) {
789  return canvas->a_d;
790  }
791 
792  void
794  canvas->setShowCopies(b);
795  }
796  bool
798  return canvas->getShowCopies();
799  }
800 
801  void
802  Gist::showStats(void) {
803  nodeStatInspector->showStats();
804  canvas->emitStatusChanged();
805  }
806 
807 }}
808 
809 // STATISTICS: gist-any