Generated on Sat Feb 7 2015 02:01:18 for Gecode by doxygen 1.8.9.1
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: 2013-05-06 09:04:26 +0200 (Mon, 06 May 2013) $ by $Author: tack $
11  * $Revision: 13614 $
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  labelBranches = new QAction("Label/clear branches", this);
162  labelBranches->setShortcut(QKeySequence("L"));
163  connect(labelBranches, SIGNAL(triggered()),
164  canvas, SLOT(labelBranches()));
165 
166  labelPath = new QAction("Label/clear path", this);
167  labelPath->setShortcut(QKeySequence("Shift+L"));
168  connect(labelPath, SIGNAL(triggered()),
169  canvas, SLOT(labelPath()));
170 
171  toggleStop = new QAction("Stop/unstop", this);
172  toggleStop->setShortcut(QKeySequence("X"));
173  connect(toggleStop, SIGNAL(triggered()), canvas, SLOT(toggleStop()));
174 
175  unstopAll = new QAction("Do not stop in subtree", this);
176  unstopAll->setShortcut(QKeySequence("Shift+X"));
177  connect(unstopAll, SIGNAL(triggered()), canvas, SLOT(unstopAll()));
178 
179  zoomToFit = new QAction("Zoom to fit", this);
180  zoomToFit->setShortcut(QKeySequence("Z"));
181  connect(zoomToFit, SIGNAL(triggered()), canvas, SLOT(zoomToFit()));
182 
183  center = new QAction("Center current node", this);
184  center->setShortcut(QKeySequence("C"));
185  connect(center, SIGNAL(triggered()), canvas, SLOT(centerCurrentNode()));
186 
187  exportPDF = new QAction("Export subtree PDF...", this);
188  exportPDF->setShortcut(QKeySequence("P"));
189  connect(exportPDF, SIGNAL(triggered()), canvas,
190  SLOT(exportPDF()));
191 
192  exportWholeTreePDF = new QAction("Export PDF...", this);
193  exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P"));
194  connect(exportWholeTreePDF, SIGNAL(triggered()), canvas,
195  SLOT(exportWholeTreePDF()));
196 
197  print = new QAction("Print...", this);
198  print->setShortcut(QKeySequence("Ctrl+P"));
199  connect(print, SIGNAL(triggered()), canvas,
200  SLOT(print()));
201 
202  bookmarkNode = new QAction("Add/remove bookmark", this);
203  bookmarkNode->setShortcut(QKeySequence("Shift+B"));
204  connect(bookmarkNode, SIGNAL(triggered()), canvas, SLOT(bookmarkNode()));
205 
206  compareNode = new QAction("Compare", this);
207  compareNode->setShortcut(QKeySequence("V"));
208  connect(compareNode, SIGNAL(triggered()),
209  canvas, SLOT(startCompareNodes()));
210 
211  compareNodeBeforeFP = new QAction("Compare before fixpoint", this);
212  compareNodeBeforeFP->setShortcut(QKeySequence("Ctrl+V"));
213  connect(compareNodeBeforeFP, SIGNAL(triggered()),
214  canvas, SLOT(startCompareNodesBeforeFP()));
215 
216  connect(canvas, SIGNAL(addedBookmark(const QString&)),
217  this, SLOT(addBookmark(const QString&)));
218  connect(canvas, SIGNAL(removedBookmark(int)),
219  this, SLOT(removeBookmark(int)));
220 
221  nullBookmark = new QAction("<none>",this);
222  nullBookmark->setCheckable(true);
223  nullBookmark->setChecked(false);
224  nullBookmark->setEnabled(false);
225  bookmarksGroup = new QActionGroup(this);
226  bookmarksGroup->setExclusive(false);
227  bookmarksGroup->addAction(nullBookmark);
228  connect(bookmarksGroup, SIGNAL(triggered(QAction*)),
229  this, SLOT(selectBookmark(QAction*)));
230 
231  bookmarksMenu = new QMenu("Bookmarks");
232  connect(bookmarksMenu, SIGNAL(aboutToShow()),
233  this, SLOT(populateBookmarksMenu()));
234 
235 
236  setPath = new QAction("Set path", this);
237  setPath->setShortcut(QKeySequence("Shift+P"));
238  connect(setPath, SIGNAL(triggered()), canvas, SLOT(setPath()));
239 
240  inspectPath = new QAction("Inspect path", this);
241  inspectPath->setShortcut(QKeySequence("Shift+I"));
242  connect(inspectPath, SIGNAL(triggered()), canvas, SLOT(inspectPath()));
243 
244  showNodeStats = new QAction("Node statistics", this);
245  showNodeStats->setShortcut(QKeySequence("S"));
246  connect(showNodeStats, SIGNAL(triggered()),
247  this, SLOT(showStats()));
248 
249  addAction(inspect);
250  addAction(inspectBeforeFP);
251  addAction(compareNode);
252  addAction(compareNodeBeforeFP);
253  addAction(stop);
254  addAction(reset);
255  addAction(navUp);
256  addAction(navDown);
257  addAction(navLeft);
258  addAction(navRight);
259  addAction(navRoot);
260  addAction(navNextSol);
261  addAction(navPrevSol);
262 
263  addAction(searchNext);
264  addAction(searchAll);
265  addAction(toggleHidden);
266  addAction(hideFailed);
267  addAction(unhideAll);
268  addAction(labelBranches);
269  addAction(labelPath);
270  addAction(toggleStop);
271  addAction(unstopAll);
272  addAction(zoomToFit);
273  addAction(center);
274  addAction(exportPDF);
275  addAction(exportWholeTreePDF);
276  addAction(print);
277 
278  addAction(setPath);
279  addAction(inspectPath);
280  addAction(showNodeStats);
281 
282  nullSolutionInspector = new QAction("<none>",this);
283  nullSolutionInspector->setCheckable(true);
284  nullSolutionInspector->setChecked(false);
285  nullSolutionInspector->setEnabled(false);
286  solutionInspectorGroup = new QActionGroup(this);
287  solutionInspectorGroup->setExclusive(false);
288  solutionInspectorGroup->addAction(nullSolutionInspector);
289  connect(solutionInspectorGroup, SIGNAL(triggered(QAction*)),
290  this, SLOT(selectSolutionInspector(QAction*)));
291 
292  nullDoubleClickInspector = new QAction("<none>",this);
293  nullDoubleClickInspector->setCheckable(true);
294  nullDoubleClickInspector->setChecked(false);
295  nullDoubleClickInspector->setEnabled(false);
296  doubleClickInspectorGroup = new QActionGroup(this);
297  doubleClickInspectorGroup->setExclusive(false);
298  doubleClickInspectorGroup->addAction(nullDoubleClickInspector);
299  connect(doubleClickInspectorGroup, SIGNAL(triggered(QAction*)),
300  this, SLOT(selectDoubleClickInspector(QAction*)));
301 
302  nullMoveInspector = new QAction("<none>",this);
303  nullMoveInspector->setCheckable(true);
304  nullMoveInspector->setChecked(false);
305  nullMoveInspector->setEnabled(false);
306  moveInspectorGroup = new QActionGroup(this);
307  moveInspectorGroup->setExclusive(false);
308  moveInspectorGroup->addAction(nullMoveInspector);
309  connect(moveInspectorGroup, SIGNAL(triggered(QAction*)),
310  this, SLOT(selectMoveInspector(QAction*)));
311 
312  nullComparator = new QAction("<none>",this);
313  nullComparator->setCheckable(true);
314  nullComparator->setChecked(false);
315  nullComparator->setEnabled(false);
316  comparatorGroup = new QActionGroup(this);
317  comparatorGroup->setExclusive(false);
318  comparatorGroup->addAction(nullComparator);
319  connect(comparatorGroup, SIGNAL(triggered(QAction*)),
320  this, SLOT(selectComparator(QAction*)));
321 
322  solutionInspectorMenu = new QMenu("Solution inspectors");
323  solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
324  doubleClickInspectorMenu = new QMenu("Double click inspectors");
325  doubleClickInspectorMenu->addActions(
326  doubleClickInspectorGroup->actions());
327  moveInspectorMenu = new QMenu("Move inspectors");
328  moveInspectorMenu->addActions(moveInspectorGroup->actions());
329  comparatorMenu = new QMenu("Comparators");
330  comparatorMenu->addActions(comparatorGroup->actions());
331 
332  inspectGroup = new QActionGroup(this);
333  connect(inspectGroup, SIGNAL(triggered(QAction*)),
334  this, SLOT(inspectWithAction(QAction*)));
335  inspectBeforeFPGroup = new QActionGroup(this);
336  connect(inspectBeforeFPGroup, SIGNAL(triggered(QAction*)),
337  this, SLOT(inspectBeforeFPWithAction(QAction*)));
338 
339  inspectNodeMenu = new QMenu("Inspect");
340  inspectNodeMenu->addAction(inspect);
341  connect(inspectNodeMenu, SIGNAL(aboutToShow()),
342  this, SLOT(populateInspectors()));
343 
344  inspectNodeBeforeFPMenu = new QMenu("Inspect before fixpoint");
345  inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
346  connect(inspectNodeBeforeFPMenu, SIGNAL(aboutToShow()),
347  this, SLOT(populateInspectors()));
348  populateInspectors();
349 
350  contextMenu = new QMenu(this);
351  contextMenu->addMenu(inspectNodeMenu);
352  contextMenu->addMenu(inspectNodeBeforeFPMenu);
353  contextMenu->addAction(compareNode);
354  contextMenu->addAction(compareNodeBeforeFP);
355  contextMenu->addAction(showNodeStats);
356  contextMenu->addAction(center);
357 
358  contextMenu->addSeparator();
359 
360  contextMenu->addAction(searchNext);
361  contextMenu->addAction(searchAll);
362 
363  contextMenu->addSeparator();
364 
365  contextMenu->addAction(toggleHidden);
366  contextMenu->addAction(hideFailed);
367  contextMenu->addAction(unhideAll);
368  contextMenu->addAction(labelBranches);
369  contextMenu->addAction(labelPath);
370 
371  contextMenu->addAction(toggleStop);
372  contextMenu->addAction(unstopAll);
373 
374  contextMenu->addSeparator();
375 
376  contextMenu->addMenu(bookmarksMenu);
377  contextMenu->addAction(setPath);
378  contextMenu->addAction(inspectPath);
379 
380  contextMenu->addSeparator();
381 
382  contextMenu->addMenu(doubleClickInspectorMenu);
383  contextMenu->addMenu(solutionInspectorMenu);
384  contextMenu->addMenu(moveInspectorMenu);
385 
386  connect(autoZoomButton, SIGNAL(toggled(bool)), canvas,
387  SLOT(setAutoZoom(bool)));
388 
389  connect(canvas, SIGNAL(autoZoomChanged(bool)),
390  autoZoomButton, SLOT(setChecked(bool)));
391 
392  {
393  unsigned int i = 0;
394  while (opt.inspect.solution(i)) {
396  }
397  i = 0;
398  while (opt.inspect.click(i)) {
400  }
401  i = 0;
402  while (opt.inspect.move(i)) {
403  addMoveInspector(opt.inspect.move(i++));
404  }
405  i = 0;
406  while (opt.inspect.compare(i)) {
407  addComparator(opt.inspect.compare(i++));
408  }
409  }
410 
411 
412  layout->addWidget(scrollArea, 0,0,-1,1);
413  layout->addWidget(canvas->scaleBar, 1,1, Qt::AlignHCenter);
414  layout->addWidget(autoZoomButton, 0,1, Qt::AlignHCenter);
415 
416  setLayout(layout);
417 
418  canvas->show();
419 
420  resize(500, 400);
421 
422  // enables on_<sender>_<signal>() mechanism
423  QMetaObject::connectSlotsByName(this);
424  }
425 
426  void
427  Gist::resizeEvent(QResizeEvent*) {
428  canvas->resizeToOuter();
429  }
430 
431  void
432  Gist::addInspector(Inspector* i0, QAction*& nas, QAction*& nad,
433  QAction*&nam) {
435  actions().indexOf(nullDoubleClickInspector) != -1) {
436  doubleClickInspectorGroup->removeAction(nullDoubleClickInspector);
437  solutionInspectorGroup->removeAction(nullSolutionInspector);
438  moveInspectorGroup->removeAction(nullMoveInspector);
439  }
440  canvas->addSolutionInspector(i0);
441  canvas->addDoubleClickInspector(i0);
442  canvas->addMoveInspector(i0);
443 
444  nas = new QAction(i0->name().c_str(), this);
445  nas->setCheckable(true);
446  solutionInspectorGroup->addAction(nas);
447  solutionInspectorMenu->clear();
448  solutionInspectorMenu->addActions(solutionInspectorGroup->actions());
449 
450  nad = new QAction(i0->name().c_str(), this);
451  nad->setCheckable(true);
452  doubleClickInspectorGroup->addAction(nad);
453  doubleClickInspectorMenu->clear();
454  doubleClickInspectorMenu->addActions(
455  doubleClickInspectorGroup->actions());
456 
457  nam = new QAction(i0->name().c_str(), this);
458  nam->setCheckable(true);
459  moveInspectorGroup->addAction(nam);
460  moveInspectorMenu->clear();
461  moveInspectorMenu->addActions(
462  moveInspectorGroup->actions());
463 
464  QAction* ia = new QAction(i0->name().c_str(), this);
465  inspectGroup->addAction(ia);
466  QAction* ibfpa = new QAction(i0->name().c_str(), this);
467  inspectBeforeFPGroup->addAction(ibfpa);
468 
469  if (inspectGroup->actions().size() < 10) {
470  ia->setShortcut(QKeySequence(QString("Ctrl+")+
471  QString("").setNum(inspectGroup->actions().size())));
472  ibfpa->setShortcut(QKeySequence(QString("Ctrl+Alt+")+
473  QString("").setNum(inspectBeforeFPGroup->actions().size())));
474  }
475  }
476 
477  void
478  Gist::addSolutionInspector(Inspector* ins) {
479  QAction* nas;
480  QAction* nad;
481  QAction* nam;
483  actions().indexOf(nullDoubleClickInspector) == -1) {
484  QList<QAction*> is = solutionInspectorGroup->actions();
485  for (int i=0; i<is.size(); i++) {
486  canvas->activateSolutionInspector(i,false);
487  is[i]->setChecked(false);
488  }
489  }
490  addInspector(ins, nas,nad,nam);
491  nas->setChecked(true);
492  selectSolutionInspector(nas);
493  }
494 
495  void
496  Gist::addDoubleClickInspector(Inspector* ins) {
497  QAction* nas;
498  QAction* nad;
499  QAction* nam;
501  actions().indexOf(nullDoubleClickInspector) == -1) {
502  QList<QAction*> is = doubleClickInspectorGroup->actions();
503  for (int i=0; i<is.size(); i++) {
504  canvas->activateDoubleClickInspector(i,false);
505  is[i]->setChecked(false);
506  }
507  }
508  addInspector(ins, nas,nad,nam);
509  nad->setChecked(true);
510  selectDoubleClickInspector(nad);
511  }
512 
513  void
514  Gist::addMoveInspector(Inspector* ins) {
515  QAction* nas;
516  QAction* nad;
517  QAction* nam;
519  actions().indexOf(nullDoubleClickInspector) == -1) {
520  QList<QAction*> is = moveInspectorGroup->actions();
521  for (int i=0; i<is.size(); i++) {
522  canvas->activateMoveInspector(i,false);
523  is[i]->setChecked(false);
524  }
525  }
526  addInspector(ins, nas,nad,nam);
527  nam->setChecked(true);
528  selectMoveInspector(nam);
529  }
530 
531  void
532  Gist::addComparator(Comparator* c) {
533  if (comparatorGroup->actions().indexOf(nullComparator) == -1) {
534  QList<QAction*> is = comparatorGroup->actions();
535  for (int i=0; i<is.size(); i++) {
536  canvas->activateComparator(i,false);
537  is[i]->setChecked(false);
538  }
539  } else {
540  comparatorGroup->removeAction(nullComparator);
541  }
542  canvas->addComparator(c);
543 
544  QAction* ncs = new QAction(c->name().c_str(), this);
545  ncs->setCheckable(true);
546  comparatorGroup->addAction(ncs);
547  comparatorMenu->clear();
548  comparatorMenu->addActions(comparatorGroup->actions());
549  ncs->setChecked(true);
550  selectComparator(ncs);
551  }
552 
553  Gist::~Gist(void) { delete canvas; }
554 
555  void
556  Gist::on_canvas_contextMenu(QContextMenuEvent* event) {
557  contextMenu->popup(event->globalPos());
558  }
559 
560  void
561  Gist::on_canvas_statusChanged(VisualNode* n, const Statistics& stats,
562  bool finished) {
563  nodeStatInspector->node(*canvas->na,n,stats,finished);
564  if (!finished) {
565  inspect->setEnabled(false);
566  inspectGroup->setEnabled(false);
567  inspectBeforeFP->setEnabled(false);
568  inspectBeforeFPGroup->setEnabled(false);
569  compareNode->setEnabled(false);
570  compareNodeBeforeFP->setEnabled(false);
571  showNodeStats->setEnabled(false);
572  stop->setEnabled(true);
573  reset->setEnabled(false);
574  navUp->setEnabled(false);
575  navDown->setEnabled(false);
576  navLeft->setEnabled(false);
577  navRight->setEnabled(false);
578  navRoot->setEnabled(false);
579  navNextSol->setEnabled(false);
580  navPrevSol->setEnabled(false);
581 
582  searchNext->setEnabled(false);
583  searchAll->setEnabled(false);
584  toggleHidden->setEnabled(false);
585  hideFailed->setEnabled(false);
586  unhideAll->setEnabled(false);
587  labelBranches->setEnabled(false);
588  labelPath->setEnabled(false);
589 
590  toggleStop->setEnabled(false);
591  unstopAll->setEnabled(false);
592 
593  center->setEnabled(false);
594  exportPDF->setEnabled(false);
595  exportWholeTreePDF->setEnabled(false);
596  print->setEnabled(false);
597 
598  setPath->setEnabled(false);
599  inspectPath->setEnabled(false);
600  bookmarkNode->setEnabled(false);
601  bookmarksGroup->setEnabled(false);
602  } else {
603  stop->setEnabled(false);
604  reset->setEnabled(true);
605 
606  if ( (n->isOpen() || n->hasOpenChildren()) && (!n->isHidden()) ) {
607  searchNext->setEnabled(true);
608  searchAll->setEnabled(true);
609  } else {
610  searchNext->setEnabled(false);
611  searchAll->setEnabled(false);
612  }
613  if (n->getNumberOfChildren() > 0) {
614  navDown->setEnabled(true);
615  toggleHidden->setEnabled(true);
616  hideFailed->setEnabled(true);
617  unhideAll->setEnabled(true);
618  unstopAll->setEnabled(true);
619  } else {
620  navDown->setEnabled(false);
621  toggleHidden->setEnabled(false);
622  hideFailed->setEnabled(false);
623  unhideAll->setEnabled(false);
624  unstopAll->setEnabled(false);
625  }
626 
627  toggleStop->setEnabled(n->getStatus() == STOP ||
628  n->getStatus() == UNSTOP);
629 
630  showNodeStats->setEnabled(true);
631  inspect->setEnabled(true);
632  labelPath->setEnabled(true);
633  if (n->getStatus() == UNDETERMINED) {
634  inspectGroup->setEnabled(false);
635  inspectBeforeFP->setEnabled(false);
636  inspectBeforeFPGroup->setEnabled(false);
637  compareNode->setEnabled(false);
638  compareNodeBeforeFP->setEnabled(false);
639  labelBranches->setEnabled(false);
640  } else {
641  inspectGroup->setEnabled(true);
642  inspectBeforeFP->setEnabled(true);
643  inspectBeforeFPGroup->setEnabled(true);
644  compareNode->setEnabled(true);
645  compareNodeBeforeFP->setEnabled(true);
646  labelBranches->setEnabled(!n->isHidden());
647  }
648 
649  navRoot->setEnabled(true);
650  VisualNode* p = n->getParent(*canvas->na);
651  if (p == NULL) {
652  inspectBeforeFP->setEnabled(false);
653  inspectBeforeFPGroup->setEnabled(false);
654  navUp->setEnabled(false);
655  navRight->setEnabled(false);
656  navLeft->setEnabled(false);
657  } else {
658  navUp->setEnabled(true);
659  unsigned int alt = n->getAlternative(*canvas->na);
660  navRight->setEnabled(alt + 1 < p->getNumberOfChildren());
661  navLeft->setEnabled(alt > 0);
662  }
663 
664  VisualNode* root = n;
665  while (!root->isRoot())
666  root = root->getParent(*canvas->na);
667  NextSolCursor nsc(n, false, *canvas->na);
668  PreorderNodeVisitor<NextSolCursor> nsv(nsc);
669  nsv.run();
670  navNextSol->setEnabled(nsv.getCursor().node() != root);
671 
672  NextSolCursor psc(n, true, *canvas->na);
673  PreorderNodeVisitor<NextSolCursor> psv(psc);
674  psv.run();
675  navPrevSol->setEnabled(psv.getCursor().node() != root);
676 
677  center->setEnabled(true);
678  exportPDF->setEnabled(true);
679  exportWholeTreePDF->setEnabled(true);
680  print->setEnabled(true);
681 
682  setPath->setEnabled(true);
683  inspectPath->setEnabled(true);
684 
685  bookmarkNode->setEnabled(true);
686  bookmarksGroup->setEnabled(true);
687  }
688  emit statusChanged(stats,finished);
689  }
690 
691  void
692  Gist::inspectWithAction(QAction* a) {
693  canvas->inspectCurrentNode(true,inspectGroup->actions().indexOf(a));
694  }
695 
696  void
697  Gist::inspectBeforeFPWithAction(QAction* a) {
698  canvas->inspectCurrentNode(false,
699  inspectBeforeFPGroup->actions().indexOf(a));
700  }
701 
702  bool
703  Gist::finish(void) {
704  return canvas->finish();
705  }
706 
707  void
708  Gist::selectDoubleClickInspector(QAction* a) {
710  doubleClickInspectorGroup->actions().indexOf(a),
711  a->isChecked());
712  }
713  void
714  Gist::selectSolutionInspector(QAction* a) {
716  solutionInspectorGroup->actions().indexOf(a),
717  a->isChecked());
718  }
719  void
720  Gist::selectMoveInspector(QAction* a) {
721  canvas->activateMoveInspector(
722  moveInspectorGroup->actions().indexOf(a),
723  a->isChecked());
724  }
725  void
726  Gist::selectComparator(QAction* a) {
727  canvas->activateComparator(comparatorGroup->actions().indexOf(a),
728  a->isChecked());
729  }
730  void
731  Gist::selectBookmark(QAction* a) {
732  int idx = bookmarksGroup->actions().indexOf(a);
733  canvas->setCurrentNode(canvas->bookmarks[idx]);
734  canvas->centerCurrentNode();
735  }
736 
737  void
738  Gist::addBookmark(const QString& id) {
739  if (bookmarksGroup->actions().indexOf(nullBookmark) != -1) {
740  bookmarksGroup->removeAction(nullBookmark);
741  }
742 
743  QAction* nb = new QAction(id, this);
744  nb->setCheckable(true);
745  bookmarksGroup->addAction(nb);
746  }
747 
748  void
749  Gist::removeBookmark(int idx) {
750  QAction* a = bookmarksGroup->actions()[idx];
751  bookmarksGroup->removeAction(a);
752  if (bookmarksGroup->actions().size() == 0) {
753  bookmarksGroup->addAction(nullBookmark);
754  }
755  }
756 
757  void
758  Gist::populateBookmarksMenu(void) {
759  bookmarksMenu->clear();
760  bookmarksMenu->addAction(bookmarkNode);
761  bookmarksMenu->addSeparator();
762  bookmarksMenu->addActions(bookmarksGroup->actions());
763  }
764 
765  void
766  Gist::populateInspectors(void) {
767  inspectNodeMenu->clear();
768  inspectNodeMenu->addAction(inspect);
769  inspectNodeMenu->addSeparator();
770  inspectNodeMenu->addActions(inspectGroup->actions());
771  inspectNodeBeforeFPMenu->clear();
772  inspectNodeBeforeFPMenu->addAction(inspectBeforeFP);
773  inspectNodeBeforeFPMenu->addSeparator();
774  inspectNodeBeforeFPMenu->addActions(inspectBeforeFPGroup->actions());
775  }
776 
777  void
778  Gist::setAutoHideFailed(bool b) { canvas->setAutoHideFailed(b); }
779  void
780  Gist::setAutoZoom(bool b) { canvas->setAutoZoom(b); }
781  bool
782  Gist::getAutoHideFailed(void) { return canvas->getAutoHideFailed(); }
783  bool
784  Gist::getAutoZoom(void) { return canvas->getAutoZoom(); }
785  void
786  Gist::setRefresh(int i) { canvas->setRefresh(i); }
787  void
788  Gist::setRefreshPause(int i) { canvas->setRefreshPause(i); }
789  bool
790  Gist::getSmoothScrollAndZoom(void) {
791  return canvas->getSmoothScrollAndZoom();
792  }
793  void
794  Gist::setSmoothScrollAndZoom(bool b) {
795  canvas->setSmoothScrollAndZoom(b);
796  }
797  bool
798  Gist::getMoveDuringSearch(void) {
799  return canvas->getMoveDuringSearch();
800  }
801  void
802  Gist::setMoveDuringSearch(bool b) {
803  canvas->setMoveDuringSearch(b);
804  }
805  void
806  Gist::setRecompDistances(int c_d, int a_d) {
807  canvas->setRecompDistances(c_d, a_d);
808  }
809 
810  int
811  Gist::getCd(void) {
812  return canvas->c_d;
813  }
814  int
815  Gist::getAd(void) {
816  return canvas->a_d;
817  }
818 
819  void
820  Gist::setShowCopies(bool b) {
821  canvas->setShowCopies(b);
822  }
823  bool
824  Gist::getShowCopies(void) {
825  return canvas->getShowCopies();
826  }
827 
828  void
829  Gist::showStats(void) {
830  nodeStatInspector->showStats();
831  canvas->emitStatusChanged();
832  }
833 
834 }}
835 
836 // STATISTICS: gist-any
void click(Inspector *i)
Add inspector that reacts on node double clicks.
Definition: gist.hpp:174
QAction * navNextSol
Navigate to next solution (to the left)
Definition: qtgist.hh:140
QActionGroup * doubleClickInspectorGroup
Group of all actions for double click inspectors.
Definition: qtgist.hh:188
Node representing stop point.
Definition: spacenode.hh:53
void setCurrentNode(VisualNode *n, bool finished=true, bool update=true)
Set the selected node to n.
QAction * toggleHidden
Toggle whether current node is hidden.
Definition: qtgist.hh:148
QAction * navDown
Navigate to leftmost child node.
Definition: qtgist.hh:132
QAction * navRoot
Navigate to root node.
Definition: qtgist.hh:138
QAction * bookmarkNode
Bookmark current node.
Definition: qtgist.hh:169
void inspectCurrentNode(bool fix=true, int inspectorNo=-1)
Call the double click inspector for the currently selected node.
Definition: treecanvas.cpp:622
QAction * navUp
Navigate to parent node.
Definition: qtgist.hh:130
QAction * setPath
Set path from current node to the root.
Definition: qtgist.hh:175
void addMoveInspector(Inspector *i0)
Add move inspector i0.
Definition: qtgist.cpp:514
void addMoveInspector(Inspector *i)
Add inspector i.
Definition: treecanvas.cpp:162
void addDoubleClickInspector(Inspector *i)
Add inspector i.
Definition: treecanvas.cpp:140
int size(void) const
Return size of array (number of elements)
Definition: array.hpp:1662
void setSmoothScrollAndZoom(bool b)
Set preference whether to use smooth scrolling and zooming.
QAction * inspect
Inspect current node.
Definition: qtgist.hh:122
Abstract base class for comparators.
Definition: gist.hh:123
void addComparator(Comparator *c)
Add comparator c.
Definition: treecanvas.cpp:173
QVector< VisualNode * > bookmarks
The bookmarks map.
Definition: treecanvas.hh:279
QAction * compareNode
Compare current node to other node.
Definition: qtgist.hh:171
QAction * unstopAll
Bookmark current node.
Definition: qtgist.hh:183
QActionGroup * inspectBeforeFPGroup
Group of all actions for direct inspector selection.
Definition: qtgist.hh:198
QAction * hideFailed
Hide failed subtrees under current node.
Definition: qtgist.hh:150
void activateComparator(int i, bool active)
Set active comparator.
Definition: treecanvas.cpp:178
QAction * navPrevSol
Navigate to previous solution (to the right)
Definition: qtgist.hh:142
QAction * navLeft
Navigate to left sibling.
Definition: qtgist.hh:134
QSlider * scaleBar
The scale bar.
Definition: treecanvas.hh:287
Computation spaces.
Definition: core.hpp:1362
QAction * toggleStop
Bookmark current node.
Definition: qtgist.hh:181
Abstract base class for inspectors.
Definition: gist.hh:103
Node that has not been explored yet.
Definition: spacenode.hh:52
void solution(Inspector *i)
Add inspector that reacts on each new solution that is found.
Definition: gist.hpp:178
void searchFinished(void)
Signals that Gist is ready to be closed.
QAction * navRight
Navigate to right sibling.
Definition: qtgist.hh:136
Gecode::FloatVal c(-8, 8)
QActionGroup * bookmarksGroup
Group of all actions for bookmarks.
Definition: qtgist.hh:194
void addInspector(Inspector *i, QAction *&nas, QAction *&nad, QAction *&nam)
Add inspector i0.
Definition: qtgist.cpp:432
QAction * inspectBeforeFP
Inspect current node before fixpoint.
Definition: qtgist.hh:124
virtual std::string name(void)
Name of the comparator.
Definition: gist.cpp:56
int p
Number of positive literals for node type.
Definition: bool-expr.cpp:236
bool getMoveDuringSearch(void)
Return preference whether to move cursor during search.
QAction * unhideAll
Unhide all hidden subtrees under current node.
Definition: qtgist.hh:152
Gecode::IntArgs i(4, 1, 2, 3, 4)
int n
Number of negative literals for node type.
Definition: bool-expr.cpp:238
Options opt
The options.
Definition: test.cpp:101
QAction * center
Center on current node.
Definition: qtgist.hh:160
const unsigned int a_d
Create a clone during recomputation if distance is greater than a_d (adaptive distance) ...
Definition: search.hh:99
void statusChanged(const Statistics &, bool)
Signals that the tree has changed.
QAction * exportPDF
Export PDF of current subtree.
Definition: qtgist.hh:162
void setRefreshPause(int i)
Set refresh pause in msec.
void solution(const Space *)
Signals that a solution has been found.
bool getAutoHideFailed(void)
Return preference whether to automatically hide failed subtrees.
Display information about nodes.
Definition: nodestats.hh:53
Gecode Interactive Search Tool
Definition: qtgist.hh:85
void activateDoubleClickInspector(int i, bool active)
Set active inspector.
Definition: treecanvas.cpp:145
void activateSolutionInspector(int i, bool active)
Set active inspector.
Definition: treecanvas.cpp:156
void setRefresh(int i)
Set refresh rate.
int a_d
The adaptive recomputation distance.
Definition: treecanvas.hh:315
void emitStatusChanged(void)
Re-emit status change information for current node.
Definition: treecanvas.cpp:935
virtual std::string name(void)
Name of the inspector.
Definition: gist.cpp:48
void resizeToOuter(void)
Resize to the outer widget size if auto zoom is enabled.
void setAutoZoom(bool b)
Set preference whether to automatically zoom to fit.
Definition: qtgist.cpp:780
void addSolutionInspector(Inspector *i0)
Add solution inspector i0.
Definition: qtgist.cpp:478
void addComparator(Comparator *c0)
Add comparator c0.
Definition: qtgist.cpp:532
QActionGroup * moveInspectorGroup
Group of all actions for move inspectors.
Definition: qtgist.hh:190
QAction * labelPath
Label branches on path to root.
Definition: qtgist.hh:156
QAction * stop
Stop search.
Definition: qtgist.hh:126
QAction * compareNodeBeforeFP
Compare current node to other node before fixpoint.
Definition: qtgist.hh:173
bool getSmoothScrollAndZoom(void)
Return preference whether to use smooth scrolling and zooming.
QAction * showNodeStats
Open node statistics inspector.
Definition: qtgist.hh:179
void setAutoZoom(bool b)
Set preference whether to automatically zoom to fit.
void setShowCopies(bool b)
Set preference whether to show copies in the tree.
int c_d
The recomputation distance.
Definition: treecanvas.hh:313
void addDoubleClickInspector(Inspector *i0)
Add double click inspector i0.
Definition: qtgist.cpp:496
QActionGroup * solutionInspectorGroup
Group of all actions for solution inspectors.
Definition: qtgist.hh:186
int bab(Space *root, const Gist::Options &opt)
Create a new stand-alone Gist for branch-and-bound search of root.
Definition: gist.hpp:212
QAction * searchNext
Search next solution in current subtree.
Definition: qtgist.hh:144
const unsigned char zoomToFitIcon[]
void addSolutionInspector(Inspector *i)
Add inspector i.
Definition: treecanvas.cpp:151
void setMoveDuringSearch(bool b)
Set preference whether to move cursor during search.
void setRecompDistances(int c_d, int a_d)
Set recomputation distances.
bool getShowCopies(void)
Return preference whether to show copies in the tree.
const unsigned int c_d
Create a clone after every c_d commits (commit distance)
Definition: search.hh:97
void centerCurrentNode(void)
Center the view on the currently selected node.
Definition: treecanvas.cpp:568
bool getAutoZoom(void)
Return preference whether to automatically zoom to fit.
QActionGroup * inspectGroup
Group of all actions for direct inspector selection.
Definition: qtgist.hh:196
class Gecode::Gist::Options::_I inspect
struct Gecode::@518::NNF::@57::@58 b
For binary nodes (and, or, eqv)
Gecode toplevel namespace
QAction * searchAll
Search all solutions in current subtree.
Definition: qtgist.hh:146
QAction * print
Print tree.
Definition: qtgist.hh:166
void setAutoHideFailed(bool b)
Set preference whether to automatically hide failed subtrees.
QAction * labelBranches
Label branches under current node.
Definition: qtgist.hh:154
QAction * reset
Reset Gist.
Definition: qtgist.hh:128
QAction * zoomToFit
Zoom tree to fit window.
Definition: qtgist.hh:158
QAction * exportWholeTreePDF
Export PDF of whole tree.
Definition: qtgist.hh:164
QAction * inspectPath
Inspect all nodes on selected path.
Definition: qtgist.hh:177
Options for Gist
Definition: gist.hh:238
void compare(Comparator *c)
Add comparator.
Definition: gist.hpp:186
void node(const VisualNode::NodeAllocator &, VisualNode *n, const Statistics &stat, bool finished)
Update display to reflect information about n.
Definition: nodestats.cpp:107
void activateMoveInspector(int i, bool active)
Set active inspector.
Definition: treecanvas.cpp:167
QActionGroup * comparatorGroup
Group of all actions for comparators.
Definition: qtgist.hh:192
struct Gecode::@518::NNF::@57::@59 a
For atomic nodes.
void move(Inspector *i)
Add inspector that reacts on each move of the cursor.
Definition: gist.hpp:182
Node::NodeAllocator * na
Allocator for nodes.
Definition: treecanvas.hh:260
bool finish(void)
Stop search and wait for it to finish.
A canvas that displays the search tree.
Definition: treecanvas.hh:91
void showStats(void)
Show this window and bring it to the front.
Definition: nodestats.cpp:131
Node representing ignored stop point.
Definition: spacenode.hh:54