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