38 #include <QtGui/QPainter>
52 namespace Gecode {
namespace Gist {
57 , mutex(QMutex::Recursive)
58 , layoutMutex(QMutex::Recursive)
60 , compareNodes(false), compareNodesBeforeFP(false)
61 , autoHideFailed(true), autoZoom(false)
62 , refresh(500), refreshPause(0), smoothScrollAndZoom(false)
64 , scrollTimeLine(1000), targetX(0), sourceX(0), targetY(0), sourceY(0)
65 , targetW(0), targetH(0), targetScale(0)
66 , layoutDoneTimerId(0) {
67 QMutexLocker locker(&
mutex);
77 int rootIdx =
na->allocate(rootSpace);
78 assert(rootIdx == 0); (void) rootIdx;
86 setAutoFillBackground(
true);
95 Qt::BlockingQueuedConnection);
97 this, SLOT(inspectSolution(
const Space*)));
99 this, SLOT(inspectSolution(
const Space*)),
100 Qt::BlockingQueuedConnection);
108 scaleBar =
new QSlider(Qt::Vertical,
this);
109 scaleBar->setObjectName(
"scaleBar");
113 connect(
scaleBar, SIGNAL(valueChanged(
int)),
123 qRegisterMetaType<Statistics>(
"Statistics");
170 comparators.append(QPair<Comparator*,bool>(c,
false));
183 QSize viewport_size =
size();
184 QAbstractScrollArea* sa =
185 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
188 zoomx = viewport_size.width()/2;
190 zoomy = viewport_size.height()/2;
192 int xoff = (sa->horizontalScrollBar()->value()+zoomx)/
scale;
193 int yoff = (sa->verticalScrollBar()->value()+zoomy)/
scale;
198 scale = (
static_cast<double>(scale0)) / 100.0;
206 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
207 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
208 sa->horizontalScrollBar()->setPageStep(viewport_size.width());
209 sa->verticalScrollBar()->setPageStep(viewport_size.height());
216 sa->horizontalScrollBar()->setValue(xoff-zoomx);
217 sa->verticalScrollBar()->setValue(yoff-zoomy);
225 QMutexLocker locker(&
mutex);
237 QSize viewport_size =
size();
238 QAbstractScrollArea* sa =
239 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
240 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
241 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
242 sa->horizontalScrollBar()->setPageStep(viewport_size.width());
243 sa->verticalScrollBar()->setPageStep(viewport_size.height());
262 QSize viewport_size =
size();
263 QAbstractScrollArea* sa =
264 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
265 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
266 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
295 SearcherThread::updateCanvas(
void) {
321 int scale0 =
static_cast<int>(t->
scale*100);
323 QWidget* p = t->parentWidget();
326 static_cast<double>(p->width()) / (bb.right - bb.left +
329 static_cast<double>(p->height()) /
332 scale0 =
static_cast<int>(
std::min(newXScale, newYScale)*100);
337 double scale = (
static_cast<double>(scale0)) / 100.0;
381 std::stack<SearchItem> stck;
385 static_cast<long unsigned int>(depth+stck.size()));
426 static_cast<long unsigned int>(depth+stck.size()));
448 QMutexLocker locker(&
mutex);
454 QMutexLocker locker(&
mutex);
460 QMutexLocker locker(&
mutex);
469 QMutexLocker locker(&
mutex);
478 QMutexLocker locker(&
mutex);
488 QMutexLocker locker(&
mutex);
497 QMutexLocker locker(&
mutex);
512 int zoomCurrent =
static_cast<int>(scale*100);
531 QWidget* p = parentWidget();
534 static_cast<double>(p->width()) / (bb.
right - bb.
left +
540 int scale0 =
static_cast<int>(
std::min(newXScale, newYScale)*100);
550 int zoomCurrent =
static_cast<int>(scale*100);
551 int targetZoom = scale0;
563 QMutexLocker locker(&
mutex);
574 x =
static_cast<int>((
xtrans+x)*scale); y =
static_cast<int>(y*
scale);
576 QAbstractScrollArea* sa =
577 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
579 x -= sa->viewport()->width() / 2;
580 y -= sa->viewport()->height() / 2;
582 sourceX = sa->horizontalScrollBar()->value();
586 sourceY = sa->verticalScrollBar()->value();
591 sa->horizontalScrollBar()->setValue(targetX);
592 sa->verticalScrollBar()->setValue(targetY);
606 QAbstractScrollArea* sa =
607 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
608 double p =
static_cast<double>(
i)/100.0;
611 sa->horizontalScrollBar()->setValue(
sourceX+static_cast<int>(xdiff));
612 sa->verticalScrollBar()->setValue(
sourceY+static_cast<int>(ydiff));
617 QMutexLocker locker(&
mutex);
624 int failedInspectorType = -1;
625 int failedInspector = -1;
626 bool needCentering =
false;
637 needCentering =
true;
649 failedInspectorType = 0;
653 failedInspectorType = -1;
697 switch (curSpace->
status()) {
710 if (inspectorNo==-1) {
713 failedInspectorType = 1;
716 failedInspectorType = -1;
720 failedInspectorType = 1;
721 failedInspector = inspectorNo;
723 failedInspectorType = -1;
730 switch (failedInspectorType) {
732 std::cerr <<
"Exception in move inspector "
736 std::cerr <<
"Exception in double-click inspector "
740 std::cerr <<
"Exception ";
743 std::cerr <<
": " << e.
what() <<
"." << std::endl;
744 std::cerr <<
"Stopping..." << std::endl;
745 std::exit(EXIT_FAILURE);
760 TreeCanvas::inspectSolution(
const Space* s) {
761 int failedInspectorType = -1;
762 int failedInspector = -1;
769 failedInspectorType = 1;
772 failedInspectorType = -1;
776 }
catch (Exception e) {
777 switch (failedInspectorType) {
779 std::cerr <<
"Exception in move inspector "
783 std::cerr <<
"Exception in solution inspector "
787 std::cerr <<
"Exception ";
790 std::cerr <<
": " << e.what() <<
"." << std::endl;
791 std::cerr <<
"Stopping..." << std::endl;
792 std::exit(EXIT_FAILURE);
804 QMutexLocker locker(&
mutex);
818 int rootIdx =
na->allocate(rootSpace);
819 assert(rootIdx == 0); (void) rootIdx;
837 QMutexLocker locker(&
mutex);
841 QInputDialog::getText(
this,
"Add bookmark",
"Name:",
842 QLineEdit::Normal,
"",&ok);
847 text = QString(
"Node ")+QString().setNum(
bookmarks.size());
862 QMutexLocker locker(&
mutex);
876 QMutexLocker locker(&
mutex);
881 while (nextAlt >= 0) {
892 QMutexLocker locker(&
mutex);
895 setCursor(QCursor(Qt::CrossCursor));
900 QMutexLocker locker(&
mutex);
903 setCursor(QCursor(Qt::CrossCursor));
913 QMutexLocker locker(&
mutex);
926 QMutexLocker locker(&
mutex);
949 QMutexLocker locker(&
mutex);
963 QMutexLocker locker(&
mutex);
977 QMutexLocker locker(&
mutex);
984 QMutexLocker locker(&
mutex);
1002 #if QT_VERSION >= 0x040400
1003 QString filename = QFileDialog::getSaveFileName(
this, tr(
"Export tree as pdf"),
"", tr(
"PDF (*.pdf)"));
1004 if (filename !=
"") {
1005 QPrinter printer(QPrinter::ScreenResolution);
1006 QMutexLocker locker(&
mutex);
1009 printer.setFullPage(
true);
1013 printer.setOutputFileName(filename);
1014 QPainter painter(&printer);
1016 painter.setRenderHint(QPainter::Antialiasing);
1018 QRect pageRect = printer.pageRect();
1020 static_cast<double>(pageRect.width()) / (bb.
right - bb.
left +
1023 static_cast<double>(pageRect.height()) /
1026 double printScale =
std::min(newXScale, newYScale);
1027 painter.scale(printScale,printScale);
1032 QRect clip(0,0,0,0);
1045 #if QT_VERSION >= 0x040400
1046 exportNodePDF(
root);
1052 #if QT_VERSION >= 0x040400
1060 if (QPrintDialog(&printer,
this).exec() == QDialog::Accepted) {
1061 QMutexLocker locker(&
mutex);
1064 QRect pageRect = printer.pageRect();
1066 static_cast<double>(pageRect.width()) / (bb.
right - bb.
left +
1069 static_cast<double>(pageRect.height()) /
1072 double printScale =
std::min(newXScale, newYScale)*100;
1075 if (printScale > 400.0)
1077 printScale = printScale / 100.0;
1079 QPainter painter(&printer);
1080 painter.setRenderHint(QPainter::Antialiasing);
1081 painter.scale(printScale,printScale);
1082 painter.translate(
xtrans, 0);
1083 QRect clip(0,0,0,0);
1093 switch (event->type()) {
1094 case QEvent::ToolTip:
1096 QHelpEvent* he =
static_cast<QHelpEvent*
>(
event);
1101 case QEvent::MouseButtonDblClick:
1102 case QEvent::MouseButtonPress:
1103 case QEvent::MouseButtonRelease:
1104 case QEvent::MouseMove:
1106 QMouseEvent* me =
static_cast<QMouseEvent*
>(
event);
1111 case QEvent::ContextMenu:
1113 QContextMenuEvent* ce =
static_cast<QContextMenuEvent*
>(
event);
1121 QAbstractScrollArea* sa =
1122 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1123 int xoff = sa->horizontalScrollBar()->value()/
scale;
1124 int yoff = sa->verticalScrollBar()->value()/
scale;
1129 if (w < sa->viewport()->width())
1130 xoff -= (sa->viewport()->width()-w)/2;
1134 static_cast<int>(x/scale-
xtrans+xoff),
1135 static_cast<int>((y-30)/scale+yoff));
1141 if (
mutex.tryLock()) {
1142 if (event->type() == QEvent::ToolTip) {
1146 QHelpEvent* he =
static_cast<QHelpEvent*
>(
event);
1147 QToolTip::showText(he->globalPos(),
1150 QToolTip::hideText();
1167 QPainter painter(
this);
1168 painter.setRenderHint(QPainter::Antialiasing);
1170 QAbstractScrollArea* sa =
1171 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1172 int xoff = sa->horizontalScrollBar()->value()/
scale;
1173 int yoff = sa->verticalScrollBar()->value()/
scale;
1178 if (w < sa->viewport()->width())
1179 xoff -= (sa->viewport()->width()-w)/2;
1181 QRect origClip =
event->rect();
1182 painter.translate(0, 30);
1183 painter.scale(scale,scale);
1184 painter.translate(
xtrans-xoff, -yoff);
1185 QRect clip(static_cast<int>(origClip.x()/scale-
xtrans+xoff),
1186 static_cast<int>(origClip.y()/scale+yoff),
1187 static_cast<int>(origClip.width()/
scale),
1188 static_cast<int>(origClip.height()/
scale));
1205 if (
mutex.tryLock()) {
1206 if(event->button() == Qt::LeftButton) {
1222 if (
mutex.tryLock()) {
1238 QAbstractScrollArea* sa =
1239 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1241 int w = sa->horizontalScrollBar()->maximum()+e->oldSize().width();
1242 int h = sa->verticalScrollBar()->maximum()+e->oldSize().height();
1244 sa->horizontalScrollBar()->setRange(0,w-e->size().width());
1245 sa->verticalScrollBar()->setRange(0,h-e->size().height());
1246 sa->horizontalScrollBar()->setPageStep(e->size().width());
1247 sa->verticalScrollBar()->setPageStep(e->size().height());
1252 if (event->modifiers() & Qt::ShiftModifier) {
1254 if (event->orientation() == Qt::Vertical && !
autoZoom)
1255 scaleTree(scale*100+ceil(static_cast<double>(event->delta())/4.0),
1256 event->x(),
event->y());
1281 QMutexLocker locker(&
mutex);
1284 Space* curSpace = NULL;
1287 if (curSpace == NULL)
1292 std::cerr <<
"Exception in move inspector " << i
1293 <<
": " << e.
what() <<
"." << std::endl;
1294 std::cerr <<
"Stopping..." << std::endl;
1295 std::exit(EXIT_FAILURE);
1307 setCursor(QCursor(Qt::ArrowCursor));
1315 if (
mutex.tryLock()) {
1316 if (event->button() == Qt::LeftButton) {
1322 Space* curSpace = NULL;
1323 Space* compareSpace = NULL;
1326 if (curSpace == NULL) {
1334 switch (compareSpace->
status()) {
1347 comparators[
i].first->compare(*curSpace,*compareSpace);
1355 setCursor(QCursor(Qt::ArrowCursor));