void TreeCanvas::toggleStop(void) { QMutexLocker locker(&mutex); currentNode->toggleStop(*na); update(); centerCurrentNode(); emit statusChanged(currentNode, stats, true); }
void TreeCanvas::hideFailed(void) { QMutexLocker locker(&mutex); currentNode->hideFailed(*na); update(); centerCurrentNode(); emit statusChanged(currentNode, stats, true); }
void TreeCanvas::statusChanged(bool finished) { if (finished) { update(); centerCurrentNode(); } emit statusChanged(currentNode, stats, finished); }
void TreeCanvas::labelPath(void) { QMutexLocker locker(&mutex); currentNode->labelPath(*na,curBest,c_d,a_d); update(); centerCurrentNode(); emit statusChanged(currentNode, stats, true); }
void TreeCanvas::unstopAll(void) { QMutexLocker locker(&mutex); QMutexLocker layoutLocker(&layoutMutex); currentNode->unstopAll(*na); update(); centerCurrentNode(); emit statusChanged(currentNode, stats, true); }
void TreeCanvas::navNextSol(bool back) { QMutexLocker locker(&mutex); NextSolCursor nsc(currentNode,back,*na); PreorderNodeVisitor<NextSolCursor> nsv(nsc); nsv.run(); VisualNode* n = nsv.getCursor().node(); if (n != root) { setCurrentNode(n); centerCurrentNode(); } }
void TreeCanvas::navUp(void) { QMutexLocker locker(&mutex); VisualNode* p = currentNode->getParent(*na); setCurrentNode(p); if (p != NULL) { centerCurrentNode(); } }
void TreeCanvas::navRight(void) { QMutexLocker locker(&mutex); VisualNode* p = currentNode->getParent(*na); if (p != NULL) { unsigned int alt = currentNode->getAlternative(*na); if (alt + 1 < p->getNumberOfChildren()) { VisualNode* n = p->getChild(*na,alt+1); setCurrentNode(n); centerCurrentNode(); } } }
void TreeCanvas::navLeft(void) { QMutexLocker locker(&mutex); VisualNode* p = currentNode->getParent(*na); if (p != NULL) { int alt = currentNode->getAlternative(*na); if (alt > 0) { VisualNode* n = p->getChild(*na,alt-1); setCurrentNode(n); centerCurrentNode(); } } }
void TreeCanvas::navDown(void) { QMutexLocker locker(&mutex); if (!currentNode->isHidden()) { switch (currentNode->getStatus()) { case STOP: case UNSTOP: case BRANCH: { int alt = std::max(0, currentNode->getPathAlternative(*na)); VisualNode* n = currentNode->getChild(*na,alt); setCurrentNode(n); centerCurrentNode(); break; } case SOLVED: case FAILED: case UNDETERMINED: break; } } }
void Gist::addActions() { /// Expand current node auto expand_action = new QAction("Expand", this); expand_action->setShortcut(QKeySequence("Return")); addAction(expand_action); connect(expand_action, SIGNAL(triggered()), m_Canvas, SLOT(expandCurrentNode())); reset = new QAction("Reset", this); addAction(reset); connect(reset, SIGNAL(triggered()), m_Canvas, SLOT(reset())); // reset->setShortcut(QKeySequence("Ctrl+R")); showPixelTree = new QAction("Pixel Tree View", this); addAction(showPixelTree); connect(showPixelTree, SIGNAL(triggered()), m_Canvas, SLOT(showPixelTree())); showIcicleTree = new QAction("Icicle Tree View", this); addAction(showIcicleTree); connect(showIcicleTree, SIGNAL(triggered()), m_Canvas, SLOT(showIcicleTree())); showWebscript = new QAction("Webscript View", this); addAction(showWebscript); connect(showWebscript, SIGNAL(triggered()), m_Canvas, SLOT(showWebscript())); followPath = new QAction("Follow Path", this); addAction(followPath); connect(followPath, SIGNAL(triggered()), m_Canvas, SLOT(followPath())); /// Collect ML stats auto collectMLStats_action = new QAction("Collect ML stats", this); addAction(collectMLStats_action); connect(collectMLStats_action, SIGNAL(triggered()), m_Canvas, SLOT(collectMLStats())); deleteWhiteNodes = new QAction{"Delete Unexplored Nodes", this}; addAction(deleteWhiteNodes); connect(deleteWhiteNodes, &QAction::triggered, m_Canvas, &TreeCanvas::deleteWhiteNodes); navUp = new QAction("Up", this); addAction(navUp); navUp->setShortcut(QKeySequence("Up")); connect(navUp, SIGNAL(triggered()), m_Canvas, SLOT(navUp())); navDown = new QAction("Down", this); addAction(navDown); navDown->setShortcut(QKeySequence("Down")); connect(navDown, SIGNAL(triggered()), m_Canvas, SLOT(navDown())); navLeft = new QAction("Left", this); addAction(navLeft); navLeft->setShortcut(QKeySequence("Left")); connect(navLeft, SIGNAL(triggered()), m_Canvas, SLOT(navLeft())); navRight = new QAction("Right", this); addAction(navRight); navRight->setShortcut(QKeySequence("Right")); connect(navRight, SIGNAL(triggered()), m_Canvas, SLOT(navRight())); navRoot = new QAction("Root", this); addAction(navRoot); navRoot->setShortcut(QKeySequence("R")); connect(navRoot, SIGNAL(triggered()), m_Canvas, SLOT(navRoot())); navNextSol = new QAction("To next solution", this); addAction(navNextSol); navNextSol->setShortcut(QKeySequence("Shift+Right")); connect(navNextSol, SIGNAL(triggered()), m_Canvas, SLOT(navNextSol())); navPrevSol = new QAction("To previous solution", this); addAction(navPrevSol); navPrevSol->setShortcut(QKeySequence("Shift+Left")); connect(navPrevSol, SIGNAL(triggered()), m_Canvas, SLOT(navPrevSol())); navNextLeaf = new QAction("To next leaf", this); addAction(navNextLeaf); navNextLeaf->setShortcut(QKeySequence("Ctrl+Right")); connect(navNextLeaf, SIGNAL(triggered()), m_Canvas, SLOT(navNextLeaf())); navPrevLeaf = new QAction("To previous leaf", this); addAction(navPrevLeaf); navPrevLeaf->setShortcut(QKeySequence("Ctrl+Left")); connect(navPrevLeaf, SIGNAL(triggered()), m_Canvas, SLOT(navPrevLeaf())); searchNext = new QAction("Next solution", this); addAction(searchNext); searchNext->setShortcut(QKeySequence("N")); searchAll = new QAction("All solutions", this); addAction(searchAll); searchAll->setShortcut(QKeySequence("A")); toggleHidden = new QAction("Hide/unhide", this); addAction(toggleHidden); toggleHidden->setShortcut(QKeySequence("H")); connect(toggleHidden, SIGNAL(triggered()), m_Canvas, SLOT(toggleHidden())); hideFailed = new QAction("Hide failed subtrees", this); addAction(hideFailed); hideFailed->setShortcut(QKeySequence("F")); connect(hideFailed, SIGNAL(triggered()), m_Canvas, SLOT(hideFailed())); hideSize = new QAction("Hide small subtrees", this); addAction(hideSize); connect(hideSize, SIGNAL(triggered()), m_Canvas, SLOT(hideSize())); #ifdef MAXIM_DEBUG auto printDebugInfo = new QAction("Print Debug Info", this); printDebugInfo->setShortcut(QKeySequence("Ctrl+Shift+D")); connect(printDebugInfo, &QAction::triggered, m_Canvas, &TreeCanvas::printDebugInfo); addAction(printDebugInfo); auto updateCanvas = new QAction{"Update Canvas", this}; updateCanvas->setShortcut(QKeySequence("Shift+U")); connect(updateCanvas, &QAction::triggered, [this]() { qDebug() << "action: update canvas"; m_Canvas->update(); }); addAction(updateCanvas); auto addChildren = new QAction{"Add 2 Children", this}; addChildren->setShortcut(QKeySequence("Shift+C")); connect(addChildren, &QAction::triggered, m_Canvas, &TreeCanvas::addChildren); addAction(addChildren); deleteNode = new QAction{"Delete Node", this}; deleteNode->setShortcut(QKeySequence("del")); connect(deleteNode, &QAction::triggered, m_Canvas, &TreeCanvas::deleteSelectedNode); addAction(deleteNode); dirtyUpNode = new QAction{"Dirty Up Node", this}; dirtyUpNode->setShortcut(QKeySequence("D")); connect(dirtyUpNode, &QAction::triggered, m_Canvas, &TreeCanvas::dirtyUpNode); addAction(dirtyUpNode); #endif unhideAll = new QAction("Unhide all", this); addAction(unhideAll); unhideAll->setShortcut(QKeySequence("U")); connect(unhideAll, SIGNAL(triggered()), m_Canvas, SLOT(unhideAll())); labelBranches = new QAction("Label/clear branches", this); addAction(labelBranches); labelBranches->setShortcut(QKeySequence("L")); /// TODO(maxim): should this be the default (Qt::WindowShortcut) instead? labelBranches->setShortcutContext(Qt::WidgetWithChildrenShortcut); connect(labelBranches, SIGNAL(triggered()), m_Canvas, SLOT(labelBranches())); labelPath = new QAction("Label/clear path", this); addAction(labelPath); labelPath->setShortcut(QKeySequence("Shift+L")); connect(labelPath, SIGNAL(triggered()), m_Canvas, SLOT(labelPath())); // labelPath->setShortcutContext(Qt::ApplicationShortcut); analyzeSimilarSubtrees = new QAction("Symilar Subtree Analysis", this); addAction(analyzeSimilarSubtrees); analyzeSimilarSubtrees->setShortcut(QKeySequence("Shift+s")); connect(analyzeSimilarSubtrees, SIGNAL(triggered()), m_Canvas, SLOT(analyzeSimilarSubtrees())); highlightNodesMenu = new QAction("Highlight Nodes Based On ...", this); addAction(highlightNodesMenu); connect(highlightNodesMenu, SIGNAL(triggered()), m_Canvas, SLOT(highlightNodesMenu())); showNogoods = new QAction("Show no-goods", this); addAction(showNogoods); showNogoods->setShortcut(QKeySequence("Shift+N")); connect(showNogoods, SIGNAL(triggered()), m_Canvas, SLOT(showNogoods())); showNodeInfo = new QAction("Show node info", this); addAction(showNodeInfo); showNodeInfo->setShortcut(QKeySequence("I")); connect(showNodeInfo, SIGNAL(triggered()), m_Canvas, SLOT(showNodeInfo())); showNodeOnPixelTree = new QAction("Show node on a pixel tree", this); addAction(showNodeOnPixelTree); showNodeOnPixelTree->setShortcut(QKeySequence("J")); connect(showNodeOnPixelTree, SIGNAL(triggered()), m_Canvas, SLOT(showNodeOnPixelTree())); toggleStop = new QAction("Stop/unstop", this); addAction(toggleStop); toggleStop->setShortcut(QKeySequence("X")); connect(toggleStop, SIGNAL(triggered()), m_Canvas, SLOT(toggleStop())); unstopAll = new QAction("Do not stop in subtree", this); addAction(unstopAll); unstopAll->setShortcut(QKeySequence("Shift+X")); connect(unstopAll, SIGNAL(triggered()), m_Canvas, SLOT(unstopAll())); zoomToFit = new QAction("Zoom to fit", this); addAction(zoomToFit); zoomToFit->setShortcut(QKeySequence("Z")); connect(zoomToFit, SIGNAL(triggered()), m_Canvas, SLOT(zoomToFit())); center = new QAction("Center current node", this); addAction(center); center->setShortcut(QKeySequence("C")); connect(center, SIGNAL(triggered()), m_Canvas, SLOT(centerCurrentNode())); exportPDF = new QAction("Export subtree PDF...", this); addAction(exportPDF); exportPDF->setShortcut(QKeySequence("P")); connect(exportPDF, SIGNAL(triggered()), m_Canvas, SLOT(exportPDF())); exportWholeTreePDF = new QAction("Export PDF...", this); addAction(exportWholeTreePDF); exportWholeTreePDF->setShortcut(QKeySequence("Ctrl+Shift+P")); connect(exportWholeTreePDF, SIGNAL(triggered()), m_Canvas, SLOT(exportWholeTreePDF())); print = new QAction("Print...", this); addAction(print); print->setShortcut(QKeySequence("Ctrl+P")); connect(print, SIGNAL(triggered()), m_Canvas, SLOT(print())); printSearchLog = new QAction("Export search log...", this); addAction(printSearchLog); connect(printSearchLog, SIGNAL(triggered()), m_Canvas, SLOT(printSearchLog())); bookmarkNode = new QAction("Add/remove bookmark", this); bookmarkNode->setShortcut(QKeySequence("Shift+B")); connect(bookmarkNode, SIGNAL(triggered()), m_Canvas, SLOT(bookmarkNode())); nullBookmark = new QAction("<none>",this); nullBookmark->setCheckable(true); nullBookmark->setChecked(false); nullBookmark->setEnabled(false); bookmarksGroup = new QActionGroup(this); bookmarksGroup->setExclusive(false); bookmarksGroup->addAction(nullBookmark); connect(bookmarksGroup, SIGNAL(triggered(QAction*)), this, SLOT(selectBookmark(QAction*))); bookmarksMenu = new QMenu("Bookmarks", this); connect(bookmarksMenu, SIGNAL(aboutToShow()), this, SLOT(populateBookmarksMenu())); showNodeStats = new QAction("Node statistics", this); addAction(showNodeStats); showNodeStats->setShortcut(QKeySequence("S")); connect(showNodeStats, SIGNAL(triggered()), this, SLOT(showStats())); nullComparator = new QAction("<none>",this); nullComparator->setCheckable(true); nullComparator->setChecked(false); nullComparator->setEnabled(false); comparatorGroup = new QActionGroup(this); comparatorGroup->setExclusive(false); comparatorGroup->addAction(nullComparator); // connect(comparatorGroup, SIGNAL(triggered(QAction*)), // this, SLOT(selectComparator(QAction*))); comparatorMenu = new QMenu("Comparators", this); comparatorMenu->addActions(comparatorGroup->actions()); contextMenu = new QMenu(this); contextMenu->addAction(collectMLStats_action); contextMenu->addAction(showNodeStats); contextMenu->addAction(center); contextMenu->addSeparator(); contextMenu->addAction(searchNext); contextMenu->addAction(searchAll); contextMenu->addSeparator(); contextMenu->addAction(toggleHidden); contextMenu->addAction(hideFailed); contextMenu->addAction(hideSize); contextMenu->addAction(unhideAll); contextMenu->addAction(labelBranches); contextMenu->addAction(labelPath); contextMenu->addAction(showNogoods); contextMenu->addAction(showNodeInfo); contextMenu->addAction(showNodeOnPixelTree); contextMenu->addAction(toggleStop); contextMenu->addAction(unstopAll); contextMenu->addSeparator(); contextMenu->addMenu(bookmarksMenu); contextMenu->addSeparator(); #ifdef MAXIM_DEBUG contextMenu->addAction(deleteNode); contextMenu->addAction(dirtyUpNode); #endif }
void TreeCanvas::navRoot(void) { QMutexLocker locker(&mutex); setCurrentNode(root); centerCurrentNode(); }
void TreeCanvas::inspectCurrentNode(bool fix, int inspectorNo) { QMutexLocker locker(&mutex); if (currentNode->isHidden()) { toggleHidden(); return; } int failedInspectorType = -1; int failedInspector = -1; bool needCentering = false; try { switch (currentNode->getStatus()) { case UNDETERMINED: { unsigned int kids = currentNode->getNumberOfChildNodes(*na,curBest,stats,c_d,a_d); int depth = -1; for (VisualNode* p = currentNode; p != NULL; p=p->getParent(*na)) depth++; if (kids > 0) { needCentering = true; depth++; } stats.maxDepth = std::max(stats.maxDepth, depth); if (currentNode->getStatus() == SOLVED) { assert(currentNode->hasCopy()); emit solution(currentNode->getWorkingSpace()); currentNode->purge(*na); } emit statusChanged(currentNode,stats,true); for (int i=0; i<moveInspectors.size(); i++) { if (moveInspectors[i].second) { failedInspectorType = 0; failedInspector = i; moveInspectors[i].first-> inspect(*currentNode->getWorkingSpace()); failedInspectorType = -1; } } } break; case FAILED: case STOP: case UNSTOP: case BRANCH: case SOLVED: { // SizeCursor sc(currentNode); // PreorderNodeVisitor<SizeCursor> pnv(sc); // int nodes = 1; // while (pnv.next()) { nodes++; } // std::cout << "sizeof(VisualNode): " << sizeof(VisualNode) // << std::endl; // std::cout << "Size: " << (pnv.getCursor().s)/1024 << std::endl; // std::cout << "Nodes: " << nodes << std::endl; // std::cout << "Size / node: " << (pnv.getCursor().s)/nodes // << std::endl; Space* curSpace; if (fix) { if (currentNode->isRoot() && currentNode->getStatus() == FAILED) break; curSpace = currentNode->getSpace(*na,curBest,c_d,a_d); if (currentNode->getStatus() == SOLVED && curSpace->status() != SS_SOLVED) { // in the presence of weakly monotonic propagators, we may have to // use search to find the solution here Space* dfsSpace = Gecode::dfs(curSpace); delete curSpace; curSpace = dfsSpace; } } else { if (currentNode->isRoot()) break; VisualNode* p = currentNode->getParent(*na); curSpace = p->getSpace(*na,curBest,c_d,a_d); switch (curSpace->status()) { case SS_SOLVED: case SS_FAILED: break; case SS_BRANCH: curSpace->commit(*p->getChoice(), currentNode->getAlternative(*na)); break; default: GECODE_NEVER; } } if (inspectorNo==-1) { for (int i=0; i<doubleClickInspectors.size(); i++) { if (doubleClickInspectors[i].second) { failedInspectorType = 1; failedInspector = i; doubleClickInspectors[i].first->inspect(*curSpace); failedInspectorType = -1; } } } else { failedInspectorType = 1; failedInspector = inspectorNo; doubleClickInspectors[inspectorNo].first->inspect(*curSpace); failedInspectorType = -1; } delete curSpace; } break; } } catch (Exception e) { switch (failedInspectorType) { case 0: std::cerr << "Exception in move inspector " << failedInspector; break; case 1: std::cerr << "Exception in double-click inspector " << failedInspector; break; default: std::cerr << "Exception "; break; } std::cerr << ": " << e.what() << "." << std::endl; std::cerr << "Stopping..." << std::endl; std::exit(EXIT_FAILURE); } currentNode->dirtyUp(*na); update(); if (needCentering) centerCurrentNode(); }