Add native platform interface for usb storage events

Allows native interfaces to send a signal when a USB storage device
is inserted/removed

Refs #14481
This commit is contained in:
Nyall Dawson 2018-09-18 11:09:37 +10:00
parent c817e38be2
commit 035c78be3c
5 changed files with 85 additions and 6 deletions

View File

@ -1321,8 +1321,11 @@ QgisApp::QgisApp( QSplashScreen *splash, bool restorePlugins, bool skipVersionCh
QgsGui::instance()->nativePlatformInterface()->initializeMainWindow( windowHandle(),
QgsApplication::applicationName(),
QgsApplication::organizationName(),
Qgis::QGIS_VERSION
);
Qgis::QGIS_VERSION );
connect( QgsGui::instance()->nativePlatformInterface(), &QgsNative::usbStorageNotification, this, [ = ]( const QString & path, bool inserted )
{
QgsDebugMsg( QStringLiteral( "USB STORAGE NOTIFICATION! %1 %2" ).arg( path ).arg( inserted ? QStringLiteral( "inserted" ) : QStringLiteral( "removed" ) ) );
} );
// setup application progress reports from task manager
connect( QgsApplication::taskManager(), &QgsTaskManager::taskAdded, this, []

View File

@ -36,6 +36,10 @@ SET(QGIS_NATIVE_SRCS
qgsnative.cpp
)
SET (QGIS_NATIVE_MOC_HDRS
qgsnative.h
)
IF(APPLE)
SET(QGIS_APP_OBJC_SRCS
mac/cocoainitializer.mm
@ -54,6 +58,10 @@ IF(WIN32)
../../external/wintoast/src/wintoastlib.cpp
win/qgswinnative.cpp
)
SET (QGIS_NATIVE_MOC_HDRS
${QGIS_NATIVE_MOC_HDRS}
win/qgswinnative.h
)
SET(QGIS_NATIVE_SRCS ${QGIS_NATIVE_SRCS}
${QGIS_APP_WIN32_SRCS}
)
@ -72,6 +80,8 @@ SET(QGIS_NATIVE_HDRS
qgsnative.h
)
QT5_WRAP_CPP(QGIS_NATIVE_MOC_SRCS ${QGIS_NATIVE_MOC_HDRS})
# install headers
IF(APPLE)
@ -107,7 +117,7 @@ ENDIF(WIN32)
#############################################################
# qgis_native library
ADD_LIBRARY(qgis_native SHARED ${QGIS_NATIVE_SRCS} ${QGIS_NATIVE_HDRS})
ADD_LIBRARY(qgis_native SHARED ${QGIS_NATIVE_SRCS} ${QGIS_NATIVE_MOC_SRCS} ${QGIS_NATIVE_HDRS} ${QGIS_NATIVE_MOC_HDRS})
SET_PROPERTY(TARGET qgis_native PROPERTY POSITION_INDEPENDENT_CODE ON)
GENERATE_EXPORT_HEADER(

View File

@ -22,6 +22,7 @@
#include <QImage>
#include <QVariant>
#include <vector>
#include <QObject>
class QString;
class QWindow;
@ -33,8 +34,10 @@ class QWindow;
* are implemented in subclasses to provide platform abstraction.
* \since QGIS 3.0
*/
class NATIVE_EXPORT QgsNative
class NATIVE_EXPORT QgsNative : public QObject
{
Q_OBJECT
public:
//! Native interface capabilities
@ -215,6 +218,21 @@ class NATIVE_EXPORT QgsNative
* \since QGIS 3.4
*/
virtual void onRecentProjectsChanged( const std::vector< RecentProjectProperties > &recentProjects );
signals:
/**
* Emitted whenever a USB storage device has been inserted or removed.
*
* The \a path argument gives the file path to the device (if available).
*
* If \a inserted is true then the device was inserted. If \a inserted is false then
* the device was removed.
*
* \since QGIS 3.4
*/
void usbStorageNotification( const QString &path, bool inserted );
};
Q_DECLARE_OPERATORS_FOR_FLAGS( QgsNative::Capabilities )

View File

@ -21,12 +21,14 @@
#include <QString>
#include <QDir>
#include <QWindow>
#include <QAbstractEventDispatcher>
#include <QtWinExtras/QWinTaskbarButton>
#include <QtWinExtras/QWinTaskbarProgress>
#include <QtWinExtras/QWinJumpList>
#include <QtWinExtras/QWinJumpListItem>
#include <QtWinExtras/QWinJumpListCategory>
#include "wintoastlib.h"
#include <Dbt.h>
QgsNative::Capabilities QgsWinNative::capabilities() const
{
@ -57,6 +59,10 @@ void QgsWinNative::initializeMainWindow( QWindow *window,
mWinToastInitialized = true;
mCapabilities = mCapabilities | NativeDesktopNotifications;
}
mNativeEventFilter = new QgsWinNativeEventFilter();
QAbstractEventDispatcher::instance()->installNativeEventFilter( mNativeEventFilter );
connect( mNativeEventFilter, &QgsWinNativeEventFilter::usbStorageNotification, this, &QgsNative::usbStorageNotification );
}
void QgsWinNative::cleanup()
@ -156,3 +162,27 @@ QgsNative::NotificationResult QgsWinNative::showDesktopNotification( const QStri
return result;
}
bool QgsWinNativeEventFilter::nativeEventFilter( const QByteArray &, void *message, long * )
{
MSG *pWindowsMessage = static_cast<MSG *>( message );
unsigned int wParam = pWindowsMessage->wParam;
if ( wParam == DBT_DEVICEARRIVAL || wParam == DBT_DEVICEREMOVECOMPLETE )
{
long lParam = pWindowsMessage->lParam;
unsigned long deviceType = reinterpret_cast<DEV_BROADCAST_HDR *>( lParam )->dbch_devicetype;
if ( deviceType == DBT_DEVTYP_VOLUME )
{
unsigned long unitmask = reinterpret_cast<DEV_BROADCAST_VOLUME *>( lParam )->dbcv_unitmask;
for ( int i = 0; i < 32; ++i )
{
if ( ( unitmask & ( 1 << i ) ) != 0 )
{
const QChar drive( 65 + i );
emit usbStorageNotification( QStringLiteral( "%1:/" ).arg( drive ), wParam == DBT_DEVICEARRIVAL );
}
}
}
}
return false;
}

View File

@ -19,14 +19,30 @@
#define QGSMACNATIVE_H
#include "qgsnative.h"
#include <windows.h>
#include <shlobj.h>
#include <QAbstractNativeEventFilter>
#include <Windows.h>
#include <ShlObj.h>
#pragma comment(lib,"Shell32.lib")
class QWinTaskbarButton;
class QWinTaskbarProgress;
class QWindow;
class QgsWinNativeEventFilter : public QObject, public QAbstractNativeEventFilter
{
Q_OBJECT
public:
bool nativeEventFilter( const QByteArray &eventType, void *message, long * ) override;
signals:
void usbStorageNotification( const QString &path, bool inserted );
};
class NATIVE_EXPORT QgsWinNative : public QgsNative
{
public:
@ -49,6 +65,8 @@ class NATIVE_EXPORT QgsWinNative : public QgsNative
bool mWinToastInitialized = false;
QWinTaskbarButton *mTaskButton = nullptr;
QWinTaskbarProgress *mTaskProgress = nullptr;
QgsWinNativeEventFilter *mNativeEventFilter = nullptr;
};
#endif // QGSMACNATIVE_H