Skip to content
Permalink
Browse files

Allow QgsCustomDropHandlers to directly operate mime data

and dropped file names

This allows QgsCustomDropHandlers which aren't directly associated
with providers (e.g. for plugins to handle dropped files of
a certain type)
  • Loading branch information
nyalldawson committed Sep 15, 2017
1 parent 373ac45 commit 527bce09ae0ee7f3a9f40118acd8e90c6b4d0a96
Showing with 109 additions and 3 deletions.
  1. +36 −1 python/gui/qgscustomdrophandler.sip
  2. +22 −1 src/app/qgisapp.cpp
  3. +16 −0 src/gui/qgscustomdrophandler.cpp
  4. +35 −1 src/gui/qgscustomdrophandler.h
@@ -14,6 +14,11 @@ class QgsCustomDropHandler
Abstract base class that may be implemented to handle new types of data to be dropped in QGIS.
Implementations will be used when a QgsMimeDataUtils.Uri has layerType equal to "custom",
and the providerKey is equal to key() returned by the implementation.

Alternatively, implementations can override the handleMimeData() or handleFileDrop()
methods to handle QMimeData and file drops directly. Reimplementation of these methods
does not rely on key() matching.

.. versionadded:: 3.0
%End

@@ -29,9 +34,39 @@ Type of custom URI recognized by the handler
:rtype: str
%End

virtual void handleDrop( const QgsMimeDataUtils::Uri &uri ) const = 0;
virtual void handleDrop( const QgsMimeDataUtils::Uri &uri ) const;
%Docstring
Method called from QGIS after a drop event with custom URI known by the handler
%End

virtual void handleMimeData( const QMimeData *data );
%Docstring
Called when the specified mime ``data`` has been dropped onto QGIS.

The base class implementation does nothing.

Subclasses should take care when overriding this method. When a drop event
occurs, Qt will lock the source application of the drag for the duration
of the drop event handling (e.g. dragging files from explorer to QGIS will
lock the explorer window until the drop handling has been complete).

Accordingly, only implementations must be lightweight and return ASAP.
(For instance by copying the relevant parts of ``data`` and then handling
the data after a short timeout).
%End

virtual bool handleFileDrop( const QString &file );
%Docstring
Called when the specified ``file`` has been dropped onto QGIS. If true
is returned, then the handler has accepted this file and it should not
be further processed (e.g. by other QgsCustomDropHandlers).

The base class implementation does nothing.

This method is not called directly while drop handling is occurring,
so the limitations described in handleMimeData() about returning
quickly do not apply.
:rtype: bool
%End
};

@@ -1333,6 +1333,13 @@ void QgisApp::dropEvent( QDropEvent *event )
timer->setSingleShot( true );
timer->setInterval( 50 );

// first, allow custom handlers to directly operate on the mime data
const QList<QgsCustomDropHandler *> handlers = mCustomDropHandlers;
for ( QgsCustomDropHandler *handler : handlers )
{
handler->handleMimeData( event->mimeData() );
}

// get the file list
QList<QUrl>::iterator i;
QList<QUrl>urls = event->mimeData()->urls();
@@ -1405,7 +1412,21 @@ void QgisApp::dropEvent( QDropEvent *event )

for ( const QString &file : qgsAsConst( files ) )
{
openFile( file );
bool handled = false;

// give custom drop handlers first priority at handling the file
const QList<QgsCustomDropHandler *> handlers = mCustomDropHandlers;
for ( QgsCustomDropHandler *handler : handlers )
{
if ( handler->handleFileDrop( file ) )
{
handled = true;
break;
}
}

if ( !handled )
openFile( file );
}

if ( !lst.isEmpty() )
@@ -14,3 +14,19 @@
***************************************************************************/

#include "qgscustomdrophandler.h"

void QgsCustomDropHandler::handleDrop( const QgsMimeDataUtils::Uri &uri ) const
{
Q_UNUSED( uri );
}

void QgsCustomDropHandler::handleMimeData( const QMimeData *data )
{
Q_UNUSED( data );
}

bool QgsCustomDropHandler::handleFileDrop( const QString &file )
{
Q_UNUSED( file );
return false;
}
@@ -23,6 +23,11 @@
* Abstract base class that may be implemented to handle new types of data to be dropped in QGIS.
* Implementations will be used when a QgsMimeDataUtils::Uri has layerType equal to "custom",
* and the providerKey is equal to key() returned by the implementation.
*
* Alternatively, implementations can override the handleMimeData() or handleFileDrop()
* methods to handle QMimeData and file drops directly. Reimplementation of these methods
* does not rely on key() matching.
*
* \since QGIS 3.0
*/
class GUI_EXPORT QgsCustomDropHandler
@@ -34,7 +39,36 @@ class GUI_EXPORT QgsCustomDropHandler
virtual QString key() const = 0;

//! Method called from QGIS after a drop event with custom URI known by the handler
virtual void handleDrop( const QgsMimeDataUtils::Uri &uri ) const = 0;
virtual void handleDrop( const QgsMimeDataUtils::Uri &uri ) const;

/**
* Called when the specified mime \a data has been dropped onto QGIS.
*
* The base class implementation does nothing.
*
* Subclasses should take care when overriding this method. When a drop event
* occurs, Qt will lock the source application of the drag for the duration
* of the drop event handling (e.g. dragging files from explorer to QGIS will
* lock the explorer window until the drop handling has been complete).
*
* Accordingly, only implementations must be lightweight and return ASAP.
* (For instance by copying the relevant parts of \a data and then handling
* the data after a short timeout).
*/
virtual void handleMimeData( const QMimeData *data );

/**
* Called when the specified \a file has been dropped onto QGIS. If true
* is returned, then the handler has accepted this file and it should not
* be further processed (e.g. by other QgsCustomDropHandlers).
*
* The base class implementation does nothing.
*
* This method is not called directly while drop handling is occurring,
* so the limitations described in handleMimeData() about returning
* quickly do not apply.
*/
virtual bool handleFileDrop( const QString &file );
};

#endif // QGSCUSTOMDROPHANDLER_H

0 comments on commit 527bce0

Please sign in to comment.
You can’t perform that action at this time.