Skip to content

Commit

Permalink
Allow QgsCustomDropHandlers to directly operate mime data
Browse files Browse the repository at this point in the history
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 527bce0
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 3 deletions.
37 changes: 36 additions & 1 deletion python/gui/qgscustomdrophandler.sip
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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
};

Expand Down
23 changes: 22 additions & 1 deletion src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -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() )
Expand Down
16 changes: 16 additions & 0 deletions src/gui/qgscustomdrophandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
36 changes: 35 additions & 1 deletion src/gui/qgscustomdrophandler.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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.