00001
00002
00003
00004
00005
00006
00007 #include "DataKey.h"
00008 #include "GraphicsItemType.h"
00009 #include "GraphicsView.h"
00010 #include "LoadFileInfo.h"
00011 #include "Logger.h"
00012 #include "MainWindow.h"
00013 #include "Point.h"
00014 #include <QApplication>
00015 #include <QDebug>
00016 #include <QDropEvent>
00017 #include <QGraphicsPixmapItem>
00018 #include <QGraphicsPolygonItem>
00019 #include <QGraphicsScene>
00020 #include <QMimeData>
00021 #include <QMouseEvent>
00022 #include <QScrollBar>
00023 #include "QtToString.h"
00024
00025 extern const QString AXIS_CURVE_NAME;
00026
00027 GraphicsView::GraphicsView(QGraphicsScene *scene,
00028 MainWindow &mainWindow) :
00029 QGraphicsView (scene)
00030 {
00031 connect (this, SIGNAL (signalContextMenuEvent (QString)), &mainWindow, SLOT (slotContextMenuEvent (QString)));
00032 connect (this, SIGNAL (signalDraggedDigFile (QString)), &mainWindow, SLOT (slotFileOpenDraggedDigFile (QString)));
00033 connect (this, SIGNAL (signalDraggedImage (QImage)), &mainWindow, SLOT (slotFileImportDraggedImage (QImage)));
00034 connect (this, SIGNAL (signalDraggedImageUrl (QUrl)), &mainWindow, SLOT (slotFileImportDraggedImageUrl (QUrl)));
00035 connect (this, SIGNAL (signalKeyPress (Qt::Key, bool)), &mainWindow, SLOT (slotKeyPress (Qt::Key, bool)));
00036 connect (this, SIGNAL (signalLeave ()), &mainWindow, SLOT (slotLeave ()));
00037 connect (this, SIGNAL (signalMouseMove(QPointF)), &mainWindow, SLOT (slotMouseMove (QPointF)));
00038 connect (this, SIGNAL (signalMousePress (QPointF)), &mainWindow, SLOT (slotMousePress (QPointF)));
00039 connect (this, SIGNAL (signalMouseRelease (QPointF)), &mainWindow, SLOT (slotMouseRelease (QPointF)));
00040 connect (this, SIGNAL (signalViewZoomIn ()), &mainWindow, SLOT (slotViewZoomInFromWheelEvent ()));
00041 connect (this, SIGNAL (signalViewZoomOut ()), &mainWindow, SLOT (slotViewZoomOutFromWheelEvent ()));
00042
00043 setMouseTracking (true);
00044 setAcceptDrops (true);
00045 setEnabled (true);
00046 setRenderHints(QPainter::Antialiasing);
00047 setBackgroundBrush (QBrush (QColor (Qt::gray)));
00048 verticalScrollBar()->setCursor (QCursor (Qt::ArrowCursor));
00049 horizontalScrollBar()->setCursor (QCursor (Qt::ArrowCursor));
00050
00051
00052 setWhatsThis (tr ("Main Window\n\n"
00053 "After an image file is imported, or an Engauge Document opened, an image appears in this area. "
00054 "Points are added to the image.\n\n"
00055 "If the image is a graph with two axes and one or more curves, then three axis points must be "
00056 "created along those axes. Just put two axis points on one axis and a third axis point on the other "
00057 "axis, as far apart as possible for higher accuracy. Then curve points can be added along the curves.\n\n"
00058 "If the image is a map with a scale to define length, then two axis points must be "
00059 "created at either end of the scale. Then curve points can be added.\n\n"
00060 "Zooming the image in or out is performed using any of several methods:\n"
00061 "1) rotating the mouse wheel when the cursor is outside of the image\n"
00062 "2) pressing the minus or plus keys\n"
00063 "3) selecting a new zoom setting from the View/Zoom menu"));
00064 }
00065
00066 GraphicsView::~GraphicsView()
00067 {
00068 }
00069
00070 void GraphicsView::contextMenuEvent (QContextMenuEvent *event)
00071 {
00072 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::contextMenuEvent";
00073
00074 QList<QGraphicsItem*> items = scene()->selectedItems ();
00075
00076 if (items.count () == 1) {
00077
00078 QGraphicsItem *item = items.first ();
00079 QString pointIdentifier = item->data (DATA_KEY_IDENTIFIER).toString ();
00080 GraphicsItemType type = (GraphicsItemType) item->data (DATA_KEY_GRAPHICS_ITEM_TYPE).toInt ();
00081 QString curveName = Point::curveNameFromPointIdentifier (pointIdentifier);
00082
00083 if ((type == GRAPHICS_ITEM_TYPE_POINT) &&
00084 (curveName == AXIS_CURVE_NAME)) {
00085
00086
00087 emit signalContextMenuEvent (pointIdentifier);
00088 event->accept ();
00089
00090 return;
00091 }
00092 }
00093
00094 QGraphicsView::contextMenuEvent (event);
00095 }
00096
00097 void GraphicsView::dragEnterEvent (QDragEnterEvent *event)
00098 {
00099 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dragEnterEvent " << (event->mimeData ()->hasUrls () ? "urls" : "non-urls");
00100
00101 if (event->mimeData ()->hasImage () ||
00102 event->mimeData ()->hasUrls ()) {
00103 event->acceptProposedAction();
00104 }
00105 }
00106
00107 void GraphicsView::dragMoveEvent (QDragMoveEvent *event)
00108 {
00109 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dragMoveEvent";
00110
00111 if (event->mimeData ()->hasImage () ||
00112 event->mimeData ()->hasUrls ()) {
00113 event->acceptProposedAction();
00114 }
00115 }
00116
00117 void GraphicsView::dropEvent (QDropEvent *event)
00118 {
00119 const QString MIME_FORMAT_TEXT_PLAIN ("text/plain");
00120
00121
00122 QList<QUrl> urlList = event->mimeData ()->urls ();
00123 QString urls;
00124 QTextStream str (&urls);
00125 QList<QUrl>::const_iterator itr;
00126 for (itr = urlList.begin (); itr != urlList.end (); itr++) {
00127 QUrl url = *itr;
00128 str << " url=" << url.toString () << " ";
00129 }
00130
00131 QString textPlain (event->mimeData()->data (MIME_FORMAT_TEXT_PLAIN));
00132
00133 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dropEvent"
00134 << " formats=(" << event->mimeData()->formats().join (", ").toLatin1().data() << ")"
00135 << " hasUrls=" << (event->mimeData()->hasUrls() ? "yes" : "no")
00136 << " urlCount=" << urlList.count()
00137 << " urls=(" << urls.toLatin1().data() << ")"
00138 << " text=" << textPlain.toLatin1().data()
00139 << " hasImage=" << (event->mimeData()->hasImage() ? "yes" : "no");
00140
00141 LoadFileInfo loadFileInfo;
00142 if (loadFileInfo.loadsAsDigFile (textPlain)) {
00143
00144 LOG4CPP_INFO_S ((*mainCat)) << "QGraphicsView::dropEvent dig file";
00145 QUrl url (textPlain);
00146 emit signalDraggedDigFile (url.toLocalFile());
00147 event->acceptProposedAction();
00148
00149 } else if (event->mimeData ()->hasImage ()) {
00150
00151
00152 QImage image = qvariant_cast<QImage> (event->mimeData ()->imageData ());
00153 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dropEvent image";
00154 emit signalDraggedImage (image);
00155
00156 } else if (event->mimeData ()->hasUrls () &&
00157 urlList.count () > 0) {
00158
00159
00160
00161 QUrl url = urlList.at(0);
00162 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dropEvent url=" << url.toString ().toLatin1 ().data ();
00163 emit signalDraggedImageUrl (url);
00164 event->acceptProposedAction();
00165
00166 } else {
00167
00168 LOG4CPP_INFO_S ((*mainCat)) << "GraphicsView::dropEvent dropped";
00169 QGraphicsView::dropEvent (event);
00170
00171 }
00172 }
00173
00174 bool GraphicsView::inBounds (const QPointF &posScreen)
00175 {
00176 QRectF boundingRect = scene()->sceneRect();
00177
00178 return 0 <= posScreen.x () &&
00179 0 <= posScreen.y () &&
00180 posScreen.x () < boundingRect.width() &&
00181 posScreen.y () < boundingRect.height();
00182 }
00183
00184 void GraphicsView::keyPressEvent (QKeyEvent *event)
00185 {
00186 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsView::keyPressEvent";
00187
00188
00189 Qt::Key key = (Qt::Key) event->key();
00190
00191 bool atLeastOneSelectedItem = (scene ()->selectedItems ().count () > 0);
00192
00193 if (key == Qt::Key_Down ||
00194 key == Qt::Key_Left ||
00195 key == Qt::Key_Right ||
00196 key == Qt::Key_Up) {
00197
00198 emit signalKeyPress (key, atLeastOneSelectedItem);
00199 event->accept();
00200
00201 } else {
00202
00203 QGraphicsView::keyPressEvent (event);
00204
00205 }
00206 }
00207
00208 void GraphicsView::leaveEvent (QEvent *event)
00209 {
00210 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsView::leaveEvent";
00211
00212 emit signalLeave ();
00213
00214 QGraphicsView::leaveEvent (event);
00215 }
00216
00217 void GraphicsView::mouseMoveEvent (QMouseEvent *event)
00218 {
00219
00220
00221
00222 QPointF posScreen = mapToScene (event->pos ());
00223
00224 if (!inBounds (posScreen)) {
00225
00226
00227 posScreen = QPointF (-1.0, -1.0);
00228 }
00229
00230 emit signalMouseMove (posScreen);
00231
00232 QGraphicsView::mouseMoveEvent (event);
00233 }
00234
00235 void GraphicsView::mousePressEvent (QMouseEvent *event)
00236 {
00237 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsView::mousePressEvent";
00238
00239 QPointF posScreen = mapToScene (event->pos ());
00240
00241 if (!inBounds (posScreen)) {
00242
00243
00244 posScreen = QPointF (-1.0, -1.0);
00245 }
00246
00247 emit signalMousePress (posScreen);
00248
00249 QGraphicsView::mousePressEvent (event);
00250 }
00251
00252 void GraphicsView::mouseReleaseEvent (QMouseEvent *event)
00253 {
00254 LOG4CPP_DEBUG_S ((*mainCat)) << "GraphicsView::mouseReleaseEvent signalMouseRelease";
00255
00256 QPointF posScreen = mapToScene (event->pos ());
00257
00258 if (!inBounds (posScreen)) {
00259
00260
00261 posScreen = QPointF (-1.0, -1.0);
00262 }
00263
00264
00265
00266
00267 int bitFlag = (event->buttons () & Qt::RightButton);
00268 bool isRightClick = (bitFlag != 0);
00269
00270 if (!isRightClick) {
00271
00272
00273 emit signalMouseRelease (posScreen);
00274
00275 }
00276
00277 QGraphicsView::mouseReleaseEvent (event);
00278 }
00279
00280 void GraphicsView::wheelEvent(QWheelEvent *event)
00281 {
00282 const int ANGLE_THRESHOLD = 15;
00283 const int DELTAS_PER_DEGREE = 8;
00284
00285 QPoint numDegrees = event->angleDelta() / DELTAS_PER_DEGREE;
00286
00287 LOG4CPP_INFO_S ((*mainCat)) << "MainWindow::wheelEvent"
00288 << " degrees=" << numDegrees.y()
00289 << " phase=" << event->phase();
00290
00291
00292
00293
00294
00295 if ((event->modifiers() & Qt::ControlModifier) != 0) {
00296
00297 if (numDegrees.y() >= ANGLE_THRESHOLD) {
00298
00299
00300 emit signalViewZoomIn();
00301
00302 } else if (numDegrees.y() <= -ANGLE_THRESHOLD) {
00303
00304
00305 emit signalViewZoomOut();
00306
00307 }
00308
00309
00310 event->accept();
00311
00312 } else {
00313
00314
00315 QGraphicsView::wheelEvent (event);
00316
00317 }
00318 }