38 #include <QtGui/QPainter>
40 #include <QPrintDialog>
54 namespace Gecode {
namespace Gist {
59 , mutex(QMutex::Recursive)
60 , layoutMutex(QMutex::Recursive)
62 , compareNodes(false), compareNodesBeforeFP(false)
63 , autoHideFailed(true), autoZoom(false)
64 , refresh(500), refreshPause(0), smoothScrollAndZoom(false)
65 , moveDuringSearch(false)
67 , scrollTimeLine(1000), targetX(0), sourceX(0), targetY(0), sourceY(0)
68 , targetW(0), targetH(0), targetScale(0)
69 , layoutDoneTimerId(0) {
70 QMutexLocker locker(&
mutex);
80 int rootIdx =
na->allocate(rootSpace);
81 assert(rootIdx == 0); (void) rootIdx;
89 setAutoFillBackground(
true);
98 Qt::BlockingQueuedConnection);
100 this, SLOT(inspectSolution(
const Space*)));
102 this, SLOT(inspectSolution(
const Space*)),
103 Qt::BlockingQueuedConnection);
107 Qt::BlockingQueuedConnection);
115 scaleBar =
new QSlider(Qt::Vertical,
this);
116 scaleBar->setObjectName(
"scaleBar");
120 connect(
scaleBar, SIGNAL(valueChanged(
int)),
130 qRegisterMetaType<Statistics>(
"Statistics");
177 comparators.append(QPair<Comparator*,bool>(c,
false));
190 QSize viewport_size =
size();
191 QAbstractScrollArea* sa =
192 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
195 zoomx = viewport_size.width()/2;
197 zoomy = viewport_size.height()/2;
199 int xoff = (sa->horizontalScrollBar()->value()+zoomx)/
scale;
200 int yoff = (sa->verticalScrollBar()->value()+zoomy)/
scale;
205 scale = (
static_cast<double>(scale0)) / 100.0;
213 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
214 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
215 sa->horizontalScrollBar()->setPageStep(viewport_size.width());
216 sa->verticalScrollBar()->setPageStep(viewport_size.height());
223 sa->horizontalScrollBar()->setValue(xoff-zoomx);
224 sa->verticalScrollBar()->setValue(yoff-zoomy);
232 QMutexLocker locker(&
mutex);
244 QSize viewport_size =
size();
245 QAbstractScrollArea* sa =
246 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
247 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
248 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
249 sa->horizontalScrollBar()->setPageStep(viewport_size.width());
250 sa->verticalScrollBar()->setPageStep(viewport_size.height());
269 QSize viewport_size =
size();
270 QAbstractScrollArea* sa =
271 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
272 sa->horizontalScrollBar()->setRange(0,w-viewport_size.width());
273 sa->verticalScrollBar()->setRange(0,h-viewport_size.height());
302 SearcherThread::updateCanvas(
void) {
328 int scale0 =
static_cast<int>(t->
scale*100);
330 QWidget*
p = t->parentWidget();
333 static_cast<double>(p->width()) / (bb.right - bb.left +
336 static_cast<double>(p->height()) /
339 scale0 =
static_cast<int>(
std::min(newXScale, newYScale)*100);
344 double scale = (
static_cast<double>(scale0)) / 100.0;
388 std::stack<SearchItem> stck;
392 static_cast<long unsigned int>(depth+stck.size()));
433 static_cast<long unsigned int>(depth+stck.size()));
457 QMutexLocker locker(&
mutex);
463 QMutexLocker locker(&
mutex);
469 QMutexLocker locker(&
mutex);
478 QMutexLocker locker(&
mutex);
487 QMutexLocker locker(&
mutex);
497 QMutexLocker locker(&
mutex);
506 QMutexLocker locker(&
mutex);
521 int zoomCurrent =
static_cast<int>(scale*100);
540 QWidget* p = parentWidget();
543 static_cast<double>(p->width()) / (bb.
right - bb.
left +
549 int scale0 =
static_cast<int>(
std::min(newXScale, newYScale)*100);
559 int zoomCurrent =
static_cast<int>(scale*100);
560 int targetZoom = scale0;
572 QMutexLocker locker(&
mutex);
583 x =
static_cast<int>((
xtrans+
x)*scale); y =
static_cast<int>(y*
scale);
585 QAbstractScrollArea* sa =
586 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
588 x -= sa->viewport()->width() / 2;
589 y -= sa->viewport()->height() / 2;
591 sourceX = sa->horizontalScrollBar()->value();
595 sourceY = sa->verticalScrollBar()->value();
600 sa->horizontalScrollBar()->setValue(targetX);
601 sa->verticalScrollBar()->setValue(targetY);
615 QAbstractScrollArea* sa =
616 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
617 double p =
static_cast<double>(
i)/100.0;
620 sa->horizontalScrollBar()->setValue(
sourceX+static_cast<int>(xdiff));
621 sa->verticalScrollBar()->setValue(
sourceY+static_cast<int>(ydiff));
626 QMutexLocker locker(&
mutex);
633 int failedInspectorType = -1;
634 int failedInspector = -1;
635 bool needCentering =
false;
646 needCentering =
true;
658 failedInspectorType = 0;
671 failedInspectorType = -1;
707 "Something went wrong - probably an incorrect brancher");
717 switch (curSpace->
status()) {
730 if (inspectorNo==-1) {
733 failedInspectorType = 1;
736 failedInspectorType = -1;
740 failedInspectorType = 1;
741 failedInspector = inspectorNo;
743 failedInspectorType = -1;
750 switch (failedInspectorType) {
752 qFatal(
"Exception in move inspector %d: %s.\n Stopping.",
753 failedInspector, e.
what());
756 qFatal(
"Exception in double click inspector %d: %s.\n Stopping.",
757 failedInspector, e.
what());
760 qFatal(
"Exception: %s.\n Stopping.", e.
what());
778 QMutexLocker locker(&
mutex);
786 QMutexLocker locker(&
mutex);
794 TreeCanvas::inspectSolution(
const Space* s) {
795 int failedInspectorType = -1;
796 int failedInspector = -1;
803 failedInspectorType = 1;
806 failedInspectorType = -1;
810 }
catch (Exception& e) {
811 switch (failedInspectorType) {
813 qFatal(
"Exception in move inspector %d: %s.\n Stopping.",
814 failedInspector, e.what());
817 qFatal(
"Exception in solution inspector %d: %s.\n Stopping.",
818 failedInspector, e.what());
821 qFatal(
"Exception: %s.\n Stopping.", e.what());
835 QMutexLocker locker(&
mutex);
849 int rootIdx =
na->allocate(rootSpace);
850 assert(rootIdx == 0); (void) rootIdx;
868 QMutexLocker locker(&
mutex);
872 QInputDialog::getText(
this,
"Add bookmark",
"Name:",
873 QLineEdit::Normal,
"",&ok);
878 text = QString(
"Node ")+QString().setNum(
bookmarks.size());
893 QMutexLocker locker(&
mutex);
907 QMutexLocker locker(&
mutex);
912 while (nextAlt >= 0) {
923 QMutexLocker locker(&
mutex);
926 setCursor(QCursor(Qt::CrossCursor));
931 QMutexLocker locker(&
mutex);
934 setCursor(QCursor(Qt::CrossCursor));
944 QMutexLocker locker(&
mutex);
957 QMutexLocker locker(&
mutex);
980 QMutexLocker locker(&
mutex);
994 QMutexLocker locker(&
mutex);
1008 QMutexLocker locker(&
mutex);
1015 QMutexLocker locker(&
mutex);
1033 #if QT_VERSION >= 0x040400
1034 QString filename = QFileDialog::getSaveFileName(
this, tr(
"Export tree as pdf"),
"", tr(
"PDF (*.pdf)"));
1035 if (filename !=
"") {
1036 QPrinter printer(QPrinter::ScreenResolution);
1037 QMutexLocker locker(&
mutex);
1040 printer.setFullPage(
true);
1044 printer.setOutputFileName(filename);
1045 QPainter painter(&printer);
1047 painter.setRenderHint(QPainter::Antialiasing);
1049 QRect pageRect = printer.pageRect();
1051 static_cast<double>(pageRect.width()) / (bb.
right - bb.
left +
1054 static_cast<double>(pageRect.height()) /
1057 double printScale =
std::min(newXScale, newYScale);
1058 painter.scale(printScale,printScale);
1063 QRect clip(0,0,0,0);
1076 #if QT_VERSION >= 0x040400
1077 exportNodePDF(
root);
1083 #if QT_VERSION >= 0x040400
1091 if (QPrintDialog(&printer,
this).exec() == QDialog::Accepted) {
1092 QMutexLocker locker(&
mutex);
1095 QRect pageRect = printer.pageRect();
1097 static_cast<double>(pageRect.width()) / (bb.
right - bb.
left +
1100 static_cast<double>(pageRect.height()) /
1103 double printScale =
std::min(newXScale, newYScale)*100;
1106 if (printScale > 400.0)
1108 printScale = printScale / 100.0;
1110 QPainter painter(&printer);
1111 painter.setRenderHint(QPainter::Antialiasing);
1112 painter.scale(printScale,printScale);
1113 painter.translate(
xtrans, 0);
1114 QRect clip(0,0,0,0);
1124 switch (event->type()) {
1125 case QEvent::ToolTip:
1127 QHelpEvent* he =
static_cast<QHelpEvent*
>(
event);
1132 case QEvent::MouseButtonDblClick:
1133 case QEvent::MouseButtonPress:
1134 case QEvent::MouseButtonRelease:
1135 case QEvent::MouseMove:
1137 QMouseEvent* me =
static_cast<QMouseEvent*
>(
event);
1142 case QEvent::ContextMenu:
1144 QContextMenuEvent* ce =
static_cast<QContextMenuEvent*
>(
event);
1152 QAbstractScrollArea* sa =
1153 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1154 int xoff = sa->horizontalScrollBar()->value()/
scale;
1155 int yoff = sa->verticalScrollBar()->value()/
scale;
1160 if (w < sa->viewport()->width())
1161 xoff -= (sa->viewport()->width()-w)/2;
1165 static_cast<int>(x/scale-
xtrans+xoff),
1166 static_cast<int>((y-30)/scale+yoff));
1172 if (
mutex.tryLock()) {
1173 if (event->type() == QEvent::ToolTip) {
1176 QHelpEvent* he =
static_cast<QHelpEvent*
>(
event);
1177 QToolTip::showText(he->globalPos(),
1181 QToolTip::hideText();
1186 return QWidget::event(event);
1198 QPainter painter(
this);
1199 painter.setRenderHint(QPainter::Antialiasing);
1201 QAbstractScrollArea* sa =
1202 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1203 int xoff = sa->horizontalScrollBar()->value()/
scale;
1204 int yoff = sa->verticalScrollBar()->value()/
scale;
1209 if (w < sa->viewport()->width())
1210 xoff -= (sa->viewport()->width()-w)/2;
1212 QRect origClip =
event->rect();
1213 painter.translate(0, 30);
1214 painter.scale(scale,scale);
1215 painter.translate(
xtrans-xoff, -yoff);
1216 QRect clip(static_cast<int>(origClip.x()/scale-
xtrans+xoff),
1217 static_cast<int>(origClip.y()/scale+yoff),
1218 static_cast<int>(origClip.width()/
scale),
1219 static_cast<int>(origClip.height()/
scale));
1236 if (
mutex.tryLock()) {
1237 if(event->button() == Qt::LeftButton) {
1253 if (
mutex.tryLock()) {
1269 QAbstractScrollArea* sa =
1270 static_cast<QAbstractScrollArea*
>(parentWidget()->parentWidget());
1272 int w = sa->horizontalScrollBar()->maximum()+e->oldSize().width();
1273 int h = sa->verticalScrollBar()->maximum()+e->oldSize().height();
1275 sa->horizontalScrollBar()->setRange(0,w-e->size().width());
1276 sa->verticalScrollBar()->setRange(0,h-e->size().height());
1277 sa->horizontalScrollBar()->setPageStep(e->size().width());
1278 sa->verticalScrollBar()->setPageStep(e->size().height());
1283 if (event->modifiers() & Qt::ShiftModifier) {
1285 if (event->orientation() == Qt::Vertical && !
autoZoom)
1286 scaleTree(scale*100+ceil(static_cast<double>(event->delta())/4.0),
1287 event->x(),
event->y());
1316 Space* curSpace = NULL;
1319 if (curSpace == NULL)
1324 qFatal(
"Exception in move inspector %d: %s.\n Stopping.",
1337 setCursor(QCursor(Qt::ArrowCursor));
1347 if (
mutex.tryLock()) {
1348 if (event->button() == Qt::LeftButton) {
1354 Space* curSpace = NULL;
1355 Space* compareSpace = NULL;
1358 if (curSpace == NULL) {
1366 switch (compareSpace->
status()) {
1380 comparators[
i].first->compare(*curSpace,*compareSpace);
1382 qFatal(
"Exception in comparator %d: %s.\n Stopping.",
1392 setCursor(QCursor(Qt::ArrowCursor));