mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
[FEATURE] Drag'n'drop layers from layer tree view to browser dock
Makes it easy to e.g. store your temporary layers in PostGIS
This commit is contained in:
parent
b101510c84
commit
26dd13063e
@ -40,4 +40,10 @@ class QgsMimeDataUtils
|
||||
|
||||
static UriList decodeUriList( const QMimeData* data );
|
||||
|
||||
/**
|
||||
* Returns encoded URI list from a list of layer tree nodes.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
static QByteArray layerTreeNodesToUriList( const QList<QgsLayerTreeNode*>& nodes );
|
||||
|
||||
};
|
||||
|
@ -1273,7 +1273,9 @@ void QgisApp::dragEnterEvent( QDragEnterEvent *event )
|
||||
{
|
||||
if ( event->mimeData()->hasUrls() || event->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
// the mime data are coming from layer tree, so ignore that, do not import those layers again
|
||||
if ( !event->mimeData()->hasFormat( "application/qgis.layertreemodeldata" ) )
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -767,6 +767,12 @@ QgsDockBrowserTreeView::QgsDockBrowserTreeView( QWidget* parent ) : QgsBrowserTr
|
||||
|
||||
void QgsDockBrowserTreeView::dragEnterEvent( QDragEnterEvent* e )
|
||||
{
|
||||
// if this mime data come from layer tree, the proposed action will be MoveAction
|
||||
// but for browser we really need CopyAction
|
||||
if ( e->mimeData()->hasFormat( "application/qgis.layertreemodeldata" ) &&
|
||||
e->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
|
||||
e->setDropAction( Qt::CopyAction );
|
||||
|
||||
// accept drag enter so that our widget will not get ignored
|
||||
// and drag events will not get passed to QgisApp
|
||||
e->accept();
|
||||
@ -782,6 +788,12 @@ void QgsDockBrowserTreeView::dragMoveEvent( QDragMoveEvent* e )
|
||||
return;
|
||||
}*/
|
||||
|
||||
// if this mime data come from layer tree, the proposed action will be MoveAction
|
||||
// but for browser we really need CopyAction
|
||||
if ( e->mimeData()->hasFormat( "application/qgis.layertreemodeldata" ) &&
|
||||
e->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
|
||||
e->setDropAction( Qt::CopyAction );
|
||||
|
||||
QTreeView::dragMoveEvent( e );
|
||||
|
||||
if ( !e->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
|
||||
@ -791,6 +803,17 @@ void QgsDockBrowserTreeView::dragMoveEvent( QDragMoveEvent* e )
|
||||
}
|
||||
}
|
||||
|
||||
void QgsDockBrowserTreeView::dropEvent( QDropEvent *e )
|
||||
{
|
||||
// if this mime data come from layer tree, the proposed action will be MoveAction
|
||||
// but for browser we really need CopyAction
|
||||
if ( e->mimeData()->hasFormat( "application/qgis.layertreemodeldata" ) &&
|
||||
e->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
|
||||
e->setDropAction( Qt::CopyAction );
|
||||
|
||||
QTreeView::dropEvent( e );
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// QgsBrowserTreeFilterProxyModel
|
||||
|
@ -173,6 +173,7 @@ class QgsDockBrowserTreeView : public QgsBrowserTreeView
|
||||
|
||||
void dragEnterEvent( QDragEnterEvent* e ) override;
|
||||
void dragMoveEvent( QDragMoveEvent* e ) override;
|
||||
void dropEvent( QDropEvent* e ) override;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -1011,6 +1011,9 @@ QMimeData* QgsLayerTreeModel::mimeData( const QModelIndexList& indexes ) const
|
||||
QString txt = doc.toString();
|
||||
|
||||
mimeData->setData( "application/qgis.layertreemodeldata", txt.toUtf8() );
|
||||
|
||||
mimeData->setData( "application/x-vnd.qgis.qgis.uri", QgsMimeDataUtils::layerTreeNodesToUriList( nodesFinal ) );
|
||||
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,13 @@
|
||||
#include "qgsmimedatautils.h"
|
||||
|
||||
#include "qgsdataitem.h"
|
||||
#include "qgslayertree.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgspluginlayer.h"
|
||||
#include "qgsrasterdataprovider.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
|
||||
static const char* QGIS_URILIST_MIMETYPE = "application/x-vnd.qgis.qgis.uri";
|
||||
|
||||
@ -70,15 +76,8 @@ bool QgsMimeDataUtils::isUriList( const QMimeData* data )
|
||||
QMimeData* QgsMimeDataUtils::encodeUriList( const QgsMimeDataUtils::UriList& layers )
|
||||
{
|
||||
QMimeData *mimeData = new QMimeData();
|
||||
QByteArray encodedData;
|
||||
|
||||
QDataStream stream( &encodedData, QIODevice::WriteOnly );
|
||||
Q_FOREACH ( const Uri& u, layers )
|
||||
{
|
||||
stream << u.data();
|
||||
}
|
||||
|
||||
mimeData->setData( QGIS_URILIST_MIMETYPE, encodedData );
|
||||
mimeData->setData( QGIS_URILIST_MIMETYPE, uriListToByteArray( layers ) );
|
||||
return mimeData;
|
||||
}
|
||||
|
||||
@ -98,6 +97,52 @@ QgsMimeDataUtils::UriList QgsMimeDataUtils::decodeUriList( const QMimeData* data
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
static void _addLayerTreeNodeToUriList( QgsLayerTreeNode* node, QgsMimeDataUtils::UriList& uris )
|
||||
{
|
||||
if ( QgsLayerTree::isGroup( node ) )
|
||||
{
|
||||
Q_FOREACH ( QgsLayerTreeNode* child, QgsLayerTree::toGroup( node )->children() )
|
||||
_addLayerTreeNodeToUriList( child, uris );
|
||||
}
|
||||
else if ( QgsLayerTree::isLayer( node ) )
|
||||
{
|
||||
QgsLayerTreeLayer* nodeLayer = QgsLayerTree::toLayer( node );
|
||||
if ( !nodeLayer->layer() )
|
||||
return;
|
||||
|
||||
QgsMimeDataUtils::Uri uri;
|
||||
if ( QgsVectorLayer* vlayer = qobject_cast<QgsVectorLayer*>( nodeLayer->layer() ) )
|
||||
{
|
||||
uri.layerType = "vector";
|
||||
uri.name = vlayer->name();
|
||||
uri.providerKey = vlayer->dataProvider()->name();
|
||||
uri.uri = vlayer->dataProvider()->dataSourceUri();
|
||||
}
|
||||
else if ( QgsRasterLayer* rlayer = qobject_cast<QgsRasterLayer*>( nodeLayer->layer() ) )
|
||||
{
|
||||
uri.layerType = "raster";
|
||||
uri.name = rlayer->name();
|
||||
uri.providerKey = rlayer->dataProvider()->name();
|
||||
uri.uri = rlayer->dataProvider()->dataSourceUri();
|
||||
}
|
||||
else
|
||||
{
|
||||
// plugin layers do not have a standard way of storing their URI...
|
||||
return;
|
||||
}
|
||||
uris << uri;
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray QgsMimeDataUtils::layerTreeNodesToUriList( const QList<QgsLayerTreeNode *>& nodes )
|
||||
{
|
||||
UriList uris;
|
||||
Q_FOREACH ( QgsLayerTreeNode* node, nodes )
|
||||
_addLayerTreeNodeToUriList( node, uris );
|
||||
return uriListToByteArray( uris );
|
||||
}
|
||||
|
||||
QString QgsMimeDataUtils::encode( const QStringList& items )
|
||||
{
|
||||
QString encoded;
|
||||
@ -141,3 +186,15 @@ QStringList QgsMimeDataUtils::decode( const QString& encoded )
|
||||
return items;
|
||||
}
|
||||
|
||||
|
||||
QByteArray QgsMimeDataUtils::uriListToByteArray( const QgsMimeDataUtils::UriList& layers )
|
||||
{
|
||||
QByteArray encodedData;
|
||||
|
||||
QDataStream stream( &encodedData, QIODevice::WriteOnly );
|
||||
Q_FOREACH ( const Uri& u, layers )
|
||||
{
|
||||
stream << u.data();
|
||||
}
|
||||
return encodedData;
|
||||
}
|
||||
|
@ -19,6 +19,7 @@
|
||||
#include <QStringList>
|
||||
|
||||
class QgsLayerItem;
|
||||
class QgsLayerTreeNode;
|
||||
|
||||
/** \ingroup core
|
||||
* \class QgsMimeDataUtils
|
||||
@ -62,9 +63,16 @@ class CORE_EXPORT QgsMimeDataUtils
|
||||
|
||||
static UriList decodeUriList( const QMimeData* data );
|
||||
|
||||
/**
|
||||
* Returns encoded URI list from a list of layer tree nodes.
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
static QByteArray layerTreeNodesToUriList( const QList<QgsLayerTreeNode*>& nodes );
|
||||
|
||||
private:
|
||||
static QString encode( const QStringList& items );
|
||||
static QStringList decode( const QString& encoded );
|
||||
static QByteArray uriListToByteArray( const UriList& layers );
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user