+/**
+ * Catches an entity which is close to the given position 'pos'.
+ *
+ * @param pos A graphic coordinate.
+ * @param level The level of resolving for iterating through the entity
+ * container
+ * @return Pointer to the entity or NULL.
+ */
+Entity * GraphicView::CatchEntity(const Vector & pos, RS2::ResolveLevel level)
+{
+ DEBUG->print("GraphicView::CatchEntity");
+
+ // Set default distance for points inside solids
+ double dist = toGraphDX(snapRange) * 0.9;
+ Entity * entity = container->getNearestEntity(pos, &dist, level);
+
+ // DEBUGGING INFO
+ int idx = -1;
+
+ if (entity && entity->getParent())
+ idx = entity->getParent()->findEntity(entity);
+ // END DEBUGGING INFO
+
+ if (entity && dist <= toGraphDX(snapRange))
+ {
+ // Highlight:
+ DEBUG->print("GraphicView::CatchEntity: found: idx=%d", idx);
+ return entity;
+ }
+
+ DEBUG->print("GraphicView::CatchEntity: not found");
+ return NULL;
+}
+
+/**
+ * Catches an entity which is close to the mouse cursor.
+ *
+ * @param e A mouse event.
+ * @param level The level of resolving for iterating through the entity
+ * container
+ * @return Pointer to the entity or NULL.
+ */
+Entity * GraphicView::CatchEntity(QMouseEvent * e, RS2::ResolveLevel level)
+{
+ return CatchEntity(Vector(toGraphX(e->x()), toGraphY(e->y())), level);
+}
+
+/**
+ * @return Pointer to the entity which was the key entity for the last
+ * successful snapping action. If the snap mode is "end point" the key entity
+ * is the entity whose end point was caught. If the snap mode didn't require an
+ * entity (e.g. free, grid) this method will return NULL.
+ */
+Entity * GraphicView::GetSnapperEntity()
+{
+ return snapEntity;
+}
+
+/**
+ * Snap to a coordinate in the drawing using the current snap mode.
+ *
+ * @param e A mouse event.
+ * @return The coordinates of the point or an invalid vector.
+ */
+Vector GraphicView::SnapPoint(QMouseEvent * e)
+{
+ DEBUG->print("GraphicView::SnapPoint");
+ /*Vector*/ snapSpot = Vector(false);
+
+ if (!e)
+ {
+ DEBUG->print(Debug::D_WARNING, "GraphicView::SnapPoint: QMouseEvent is NULL");
+ return snapSpot;
+ }
+
+ Vector mouseCoord = toGraph(e->x(), e->y());
+
+// switch (snapMode)
+ switch (defaultSnapMode)
+ {
+ case RS2::SnapFree:
+// snapSpot = snapFree(mouseCoord);
+ snapEntity = NULL;
+ snapSpot = mouseCoord;
+ break;
+
+ case RS2::SnapEndpoint:
+// snapSpot = snapEndpoint(mouseCoord);
+ snapSpot = container->getNearestEndpoint(mouseCoord, NULL);
+ break;
+
+ case RS2::SnapGrid:
+ snapSpot = SnapGrid(mouseCoord);
+ break;
+
+ case RS2::SnapOnEntity:
+// snapSpot = snapOnEntity(mouseCoord);
+ snapSpot = container->getNearestPointOnEntity(mouseCoord, true, NULL, &snapEntity);
+ break;
+
+ case RS2::SnapCenter:
+// snapSpot = snapCenter(mouseCoord);
+ snapSpot = container->getNearestCenter(mouseCoord, NULL);
+ break;
+
+ case RS2::SnapMiddle:
+// snapSpot = snapMiddle(mouseCoord);
+ snapSpot = container->getNearestMiddle(mouseCoord, NULL);
+ break;
+
+ case RS2::SnapDist:
+// snapSpot = snapDist(mouseCoord);
+ snapSpot = container->getNearestDist(snapDistance, mouseCoord, NULL);
+ break;
+
+ case RS2::SnapIntersection:
+// snapSpot = snapIntersection(mouseCoord);
+ snapSpot = container->getNearestIntersection(mouseCoord, NULL);
+ break;
+
+ default:
+ break;
+ }
+
+ // This is declared here because I really, really hate extraneous braces in
+ // my switch statements. :-P
+ Vector relZero = getRelativeZero();
+ Vector restrictX = Vector(relZero.x, snapSpot.y);
+ Vector restrictY = Vector(snapSpot.x, relZero.y);
+// Vector snapCoord;
+ // Handle snap restrictions that can be activated in addition to the ones above:
+// switch (snapRes)
+ switch (defaultSnapRes)
+ {
+ case RS2::RestrictOrthogonal:
+//// snapCoord = restrictOrthogonal(snapSpot);
+// rz = graphicView->getRelativeZero();
+// retx = Vector(rz.x, snapSpot.y);
+// rety = Vector(snapSpot.x, rz.y);
+ snapCoord = (restrictX.distanceTo(snapSpot) < restrictY.distanceTo(snapSpot) ?
+ restrictX : restrictY);
+ break;
+ case RS2::RestrictHorizontal:
+//// snapCoord = restrictHorizontal(snapSpot);
+// rz = graphicView->getRelativeZero();
+// snapCoord = Vector(snapSpot.x, rz.y);
+ snapCoord = restrictY;
+ break;
+ case RS2::RestrictVertical:
+//// snapCoord = restrictVertical(snapSpot);
+// rz = graphicView->getRelativeZero();
+// snapCoord = Vector(rz.x, snapSpot.y);
+ snapCoord = restrictX;
+ break;
+ default:
+ case RS2::RestrictNothing:
+ snapCoord = snapSpot;
+ break;
+ }
+
+ if (DIALOGFACTORY)
+ DIALOGFACTORY->updateCoordinateWidget(snapCoord, snapCoord - relZero);
+
+ DEBUG->print("GraphicView::SnapPoint: OK");
+
+ return snapCoord;
+}
+
+/**
+ * Snaps to a grid point.
+ *
+ * @param coord The mouse coordinate.
+ * @return The coordinates of the point or an invalid vector.
+ */
+Vector GraphicView::SnapGrid(Vector coord)
+{
+ DEBUG->print("GraphicView::snapGrid begin");
+
+ Vector vec(false);
+ double dist = 0.0;
+
+ DEBUG->print("GraphicView::snapGrid 001");
+
+ if (grid)
+ {
+ DEBUG->print("GraphicView::snapGrid 002");
+ Vector * pts = grid->getPoints();
+ DEBUG->print("GraphicView::snapGrid 003");
+ int closest = -1;
+ dist = 32000.00;
+ DEBUG->print("GraphicView::snapGrid 004");
+
+ for(int i=0; i<grid->count(); ++i)
+ {
+ double d = pts[i].distanceTo(coord);
+
+ if (d < dist)
+ {
+ closest = i;
+ dist = d;
+ }
+ }
+
+ DEBUG->print("GraphicView::snapGrid 005");
+
+ if (closest >= 0)
+ vec = pts[closest];
+
+ DEBUG->print("GraphicView::snapGrid 006");
+ }
+
+ snapEntity = NULL;
+
+ DEBUG->print("GraphicView::snapGrid end");
+
+ return vec;
+}
+
+void GraphicView::DrawSnapper(PaintInterface * painter)
+{
+//Is "finished" used at all? Seems it's used only in ActionInterface, and it's commented out
+// if (finished || !snapSpot.valid || !snapCoord.valid)
+ if (!snapSpot.valid || !snapCoord.valid)
+#if 1
+{
+printf("DrawSnapper: snapSpot=%s, snapCoord=%s...\n", (snapSpot.valid ? "valid" : "INVALID"), (snapCoord.valid ? "valid" : "INVALID"));
+#endif
+ return;
+#if 1
+}
+#endif
+
+ // Snap point (need to make sure the brush is NULL!)
+// painter->setPen(Pen(Color(0, 127, 255), RS2::Width00, RS2::DashLine));
+ painter->setPen(Pen(Color(255, 127, 0), RS2::Width00, RS2::DashLine));
+ painter->drawCircle(toGui(snapCoord), 4);
+
+ // Crosshairs
+ if (showCrosshairs)
+ {
+ painter->setPen(Pen(Color(0, 255, 255), RS2::Width00, RS2::DashLine));
+ painter->drawLine(Vector(0, toGuiY(snapCoord.y)),
+ Vector(getWidth(), toGuiY(snapCoord.y)));
+ painter->drawLine(Vector(toGuiX(snapCoord.x), 0),
+ Vector(toGuiX(snapCoord.x), getHeight()));
+ }
+
+ // Cursor
+ if (snapCoord != snapSpot)
+ {
+ painter->drawLine(toGui(snapSpot) + Vector(-5, 0), toGui(snapSpot) + Vector(-1, 4));
+ painter->drawLine(toGui(snapSpot) + Vector(0, 5), toGui(snapSpot) + Vector(4, 1));
+ painter->drawLine(toGui(snapSpot) + Vector(5, 0), toGui(snapSpot) + Vector(1, -4));
+ painter->drawLine(toGui(snapSpot) + Vector(0, -5), toGui(snapSpot) + Vector(-4, -1));
+ }
+}
+
+void GraphicView::SetSnapperVisible(bool visibility/*= true*/)
+{
+ snapperVisible = visibility;
+}
+
+bool GraphicView::SnapperVisible(void)
+{
+ return snapperVisible;
+}
+
+#if 0
+/*
+only place this is called is in ActionInterface. And its only function is to
+have it not drawn anymore. But, the GraphicView seems to draw it anyway... So
+some other approach is needed...
+*/
+void Snapper::finish()