/** ** ** @RDE_HEADER@ ** Abstract Event Dispatcher for Qt5 ** $Id$ ** $HeadURL$ ** $Author$ ** ** ----------------------------------------------------------------------------------------------- ** ** Hardware-Environment: Intel-PC ** Software-Environment: Windows 7, Qt 5.4. ArcGIS 10.2.5 ** ** Language ........: C++ 11 ** ** ----------------------------------------------------------------------------------------------- ** ** Author ...........: Jörg Turla, SPD G, Tel. 3132 ** ** ----------------------------------------------------------------------------------------------- ** ** Notes .........: ** ** 28.04.2003, JT : First edition for use with Qt4 in START Feature Editor fee ** 25.03.2015, JT : Refactoring for use with Qt5 ** ** ----------------------------------------------------------------------------------------------- */ #pragma once #include #include #include #include #include #include #include class QWidget; class QWheelEvent; class QGestureRecognizer; namespace SituationMap { namespace RB { /** @class AbstractEventDispatcher abstract_event_dispatcher.h @brief Base class of Qt event filter implementations to handle user interactions of map window An EventDispatcher installs an event filter on a QWidget to receive all events that are send to the widget. Depending on the type of event and the state of the event dispatcher the event will be processed by the dispatcher and stopped or forwarded to the QWidget. In case of processing the event methodes of the EventActionInterface are called to controll a rubberband. @see EventDelegater, EventDispatcher, EventMouseNavigator */ class AbstractEventDispatcher : public QObject { friend class EventDelegater; Q_OBJECT public: /** @brief Logical interface between EventDispatcher and Rubberband Defines interface functions the EventDispatcher will call to control a rubberband. The rubberband class is derived from EventActionInterface and overrides the interface functions to implement them. The mapping user interaction to interface action is defined the derived classes of AbstractEventDispatcher. */ class EventActionInterface { public: EventActionInterface() = default; virtual ~EventActionInterface() = default; virtual void unlinkEventDispatcher( AbstractEventDispatcher * causer ) = 0; virtual bool selectAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool multiSelectAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool setCoordinateAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool moveAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool movePickedAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual void resetAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool contextMenuAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool completeStateAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool deleteAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool undoAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool applyAndEndAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; virtual bool abortAction ( AbstractEventDispatcher * causer, int x, int y ) = 0; }; /* EventActionInterface */ /** @name Construction & Destruction @{ */ AbstractEventDispatcher( QWidget * getEventsFrom ); AbstractEventDispatcher( QWidget * getEventsFrom, EventActionInterface* ); virtual ~AbstractEventDispatcher(); AbstractEventDispatcher(const AbstractEventDispatcher &) = delete; AbstractEventDispatcher & operator = (const AbstractEventDispatcher &) = delete; /** @} */ /** Conceal deleteLater slot. Use onDo_delete() instead to avoid "QCoreApplication::postEvent: Unexpected null receiver" warning. */ void deleteLater() = delete; inline void setEventActions(EventActionInterface * eventActions) { _eventActions = eventActions; } inline bool hasGrab() const { return _hasGrab; } inline void setCursor(const QCursor & cursor) { _dispatcherCursor = cursor; } void setWhatsThis(const QString & whatsThis); virtual void grab(); virtual void ungrab(); public slots: /** @brief Slot calling internal \c KickTheBucket methode Calls internal methode \c KickTheBucket. Be careful using this function. Should only be used from implementations of \c EventActionInterface methodes or \c EventDelegater class. */ void onDo_kickTheBucket(); /** @brief Slot calling \c deleteLater function of QObject Never use \c delete directly for EventDispatcher class. Instead of use \c onDo_delete() function. */ void onDo_delete(); protected: QWidget * _getEventsFrom; bool _cursorIsInWidget; inline bool hasFinished() { return _finishFlag; } inline bool hasActiveEvent() { return _activeEvent; } inline void setActiveEvent(bool val) { _activeEvent = val; } /** @brief Destroying EventDispatcher as result of an incoming event. As result of an incomming event (e.g. Keypress ESC) the EventDispatcher will stop, emiting signal \c signalKickTheBucket() and calls methode \c EventActionInterface::unlinkEventDispatcher() before setup \c deleteLater() call to destroy it self. */ virtual void KickTheBucket(); inline void unlinkEventDispatcher() { if (_eventActions) { _eventActions -> unlinkEventDispatcher( this ); _eventActions = nullptr; } } /* unlinkEventDispatcher */ inline bool callEventAction( bool( EventActionInterface::*actionMethodePtr)( AbstractEventDispatcher*,int,int), int x, int y ) { if (_eventActions == nullptr) return false; return (_eventActions->*actionMethodePtr)( this, x, y ); } /* callEventAction */ /** Event filter function to override to implement event handling. To workaround a cursor handling bug in QGraphicsView it is necessary to call the eventFilter function of this base class, which will monitor enter and leave events. */ virtual bool eventFilter( QObject * widget, QEvent * e ); inline EventActionInterface * getEventActions() const { return _eventActions; } void setCursorToWidget( const QCursor & cursor ); QCursor getCursorFromWidget(); ulong _ignoreMouseMoveTimestamp; bool _synthesisTouchFromMouseEvents; static unsigned int _applyGestureID; private: void initDispatcher(); bool _deleteRequested; bool _hasGrab; bool _finishFlag; bool _restoreCursor; bool _restoreMouseTracking; QCursor _cursorToRestore; bool _activeEvent; QCursor _dispatcherCursor; QString _whatsThisBackup; EventActionInterface * _eventActions; static QGestureRecognizer * _applyGestureDetection; signals: void signalKickTheBucket(); }; /* EventDispatcher */ } } /* namespace SituationMap::RB */