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