32 changes: 10 additions & 22 deletions src/app/qgisapp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@
#include "qgsmaptip.h"
#include "qgsmergeattributesdialog.h"
#include "qgsmessageviewer.h"
#include "qgsmimedatautils.h"
#include "qgsnewvectorlayerdialog.h"
#include "qgsoptions.h"
#include "qgspastetransformations.h"
Expand Down Expand Up @@ -681,31 +682,18 @@ void QgisApp::dropEvent( QDropEvent *event )
openFile( fileName );
}
}
if ( event->mimeData()->hasFormat( "application/x-vnd.qgis.qgis.uri" ) )
if ( QgsMimeDataUtils::isUriList( event->mimeData() ) )
{
QByteArray encodedData = event->mimeData()->data( "application/x-vnd.qgis.qgis.uri" );
QDataStream stream( &encodedData, QIODevice::ReadOnly );
QString xUri; // extended uri: layer_type:provider_key:uri
while ( !stream.atEnd() )
QgsMimeDataUtils::UriList lst = QgsMimeDataUtils::decodeUriList( event->mimeData() );
foreach( const QgsMimeDataUtils::Uri& u, lst )
{
stream >> xUri;
QgsDebugMsg( xUri );
QRegExp rx( "^([^:]+):([^:]+):([^:]+):(.+)" );
if ( rx.indexIn( xUri ) != -1 )
if ( u.layerType == "vector" )
{
QString layerType = rx.cap( 1 );
QString providerKey = rx.cap( 2 );
QString name = rx.cap( 3 );
QString uri = rx.cap( 4 );
QgsDebugMsg( "type: " + layerType + " key: " + providerKey + " name: " + name + " uri: " + uri );
if ( layerType == "vector" )
{
addVectorLayer( uri, name, providerKey );
}
else if ( layerType == "raster" )
{
addRasterLayer( uri, name, providerKey, QStringList(), QStringList(), QString(), QString() );
}
addVectorLayer( u.uri, u.name, u.providerKey );
}
else if ( u.layerType == "raster" )
{
addRasterLayer( u.uri, u.name, u.providerKey, QStringList(), QStringList(), QString(), QString() );
}
}
}
Expand Down
19 changes: 16 additions & 3 deletions src/app/qgsbrowserdockwidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class QgsBrowserTreeView : public QTreeView
setSelectionMode( QAbstractItemView::ExtendedSelection );
setContextMenuPolicy( Qt::CustomContextMenu );
setHeaderHidden( true );
setDropIndicatorShown( true );
}

void dragEnterEvent( QDragEnterEvent* e )
Expand All @@ -42,9 +43,21 @@ class QgsBrowserTreeView : public QTreeView
}
void dragMoveEvent( QDragMoveEvent* e )
{
// ignore all possibilities where an item could be dropped
// because we want that user drops the item on canvas / legend / app
e->ignore();
// do not accept drops above/below items
/*if ( dropIndicatorPosition() != QAbstractItemView::OnItem )
{
QgsDebugMsg("drag not on item");
e->ignore();
return;
}*/

QTreeView::dragMoveEvent( e );

if ( !e->provides( "application/x-vnd.qgis.qgis.uri" ) )
{
e->ignore();
return;
}
}
};

Expand Down
109 changes: 27 additions & 82 deletions src/app/spatialite/qgsnewspatialitelayerdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

#include "qgsspatialitesridsdialog.h"
#include "qgsapplication.h"
#include "qgsproviderregistry.h"
#include "qgisapp.h" // <- for theme icons
#include <qgsvectorlayer.h>
#include <qgsmaplayerregistry.h>
Expand All @@ -33,6 +34,7 @@
#include <QLineEdit>
#include <QMessageBox>
#include <QFileDialog>
#include <QLibrary>

#include <spatialite.h>

Expand Down Expand Up @@ -187,101 +189,43 @@ void QgsNewSpatialiteLayerDialog::on_pbnFindSRID_clicked()
}
}

void QgsNewSpatialiteLayerDialog::initializeSpatialMetadata( sqlite3 *sqlite_handle )
{
// attempting to perform self-initialization for a newly created DB
int ret;
char sql[1024];
char *errMsg = NULL;
int count = 0;
int i;
char **results;
int rows;
int columns;

if ( sqlite_handle == NULL )
return;
// checking if this DB is really empty
strcpy( sql, "SELECT Count(*) from sqlite_master" );
ret = sqlite3_get_table( sqlite_handle, sql, &results, &rows, &columns, NULL );
if ( ret != SQLITE_OK )
return;
if ( rows < 1 )
;
else
{
for ( i = 1; i <= rows; i++ )
count = atoi( results[( i * columns ) + 0] );
}
sqlite3_free_table( results );

if ( count > 0 )
return;

// all right, it's empty: proceding to initialize
strcpy( sql, "SELECT InitSpatialMetadata()" );
ret = sqlite3_exec( sqlite_handle, sql, NULL, NULL, &errMsg );
if ( ret != SQLITE_OK )
{
QString errCause = tr( "Unable to initialize SpatialMetadata:\n" );
errCause += QString::fromUtf8( errMsg );
QMessageBox::warning( 0, tr( "SpatiaLite Database" ), errCause );
sqlite3_free( errMsg );
return;
}
spatial_ref_sys_init( sqlite_handle, 0 );
}

bool QgsNewSpatialiteLayerDialog::createDb()
{
QSettings settings;
int ret;
sqlite3 *sqlite_handle;
char *errMsg = NULL;

if ( mDatabaseComboBox->currentText().isEmpty() )
QString dbPath = mDatabaseComboBox->currentText();
if ( dbPath.isEmpty() )
return false;

QFile newDb( mDatabaseComboBox->currentText() );
QFile newDb( dbPath );
if ( !newDb.exists() )
{
QgsDebugMsg( "creating a new db" );
QString errCause;
bool res = false;

QFileInfo fullPath = QFileInfo( mDatabaseComboBox->currentText() );
QDir path = fullPath.dir();
QgsDebugMsg( QString( "making this dir: %1" ).arg( path.absolutePath() ) );
QString spatialite_lib = QgsProviderRegistry::instance()->library( "spatialite" );
QLibrary* myLib = new QLibrary( spatialite_lib );
bool loaded = myLib->load();
if ( loaded )
{
QgsDebugMsg( "spatialite provider loaded" );

// Must be sure there is destination directory ~/.qgis
QDir().mkpath( path.absolutePath( ) );
typedef bool ( *createDbProc )( const QString&, QString& );
createDbProc createDbPtr = ( createDbProc ) cast_to_fptr( myLib->resolve( "createDb" ) );
if ( createDbPtr )
{
res = createDbPtr( dbPath, errCause );
}
else
{
errCause = "Resolving createDb(...) failed";
}
}
delete myLib;

// creating/opening the new database
QString dbPath = newDb.fileName();
spatialite_init( 0 );
ret = sqlite3_open_v2( dbPath.toUtf8().constData(), &sqlite_handle, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, NULL );
if ( ret )
if ( !res )
{
// an error occurred
QString errCause = tr( "Could not create a new database\n" );
errCause += QString::fromUtf8( sqlite3_errmsg( sqlite_handle ) );
sqlite3_close( sqlite_handle );
QMessageBox::warning( 0, tr( "SpatiaLite Database" ), errCause );
pbnFindSRID->setEnabled( false );
return false;
}
// activating Foreign Key constraints
ret = sqlite3_exec( sqlite_handle, "PRAGMA foreign_keys = 1", NULL, 0, &errMsg );
if ( ret != SQLITE_OK )
{
QMessageBox::warning( 0, tr( "SpatiaLite Database" ), tr( "Unable to activate FOREIGN_KEY constraints" ) );
sqlite3_free( errMsg );
sqlite3_close( sqlite_handle );
pbnFindSRID->setEnabled( false );
return false;
}
initializeSpatialMetadata( sqlite_handle );

// all done: closing the DB connection
sqlite3_close( sqlite_handle );
}

QFileInfo fi( newDb );
Expand All @@ -293,6 +237,7 @@ bool QgsNewSpatialiteLayerDialog::createDb()

QString key = "/SpatiaLite/connections/" + fi.fileName() + "/sqlitepath";

QSettings settings;
if ( !settings.contains( key ) )
{
settings.setValue( "/SpatiaLite/connections/selected", fi.fileName() + tr( "@" ) + fi.canonicalFilePath() );
Expand Down
3 changes: 0 additions & 3 deletions src/app/spatialite/qgsnewspatialitelayerdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,6 @@ class QgsNewSpatialiteLayerDialog: public QDialog, private Ui::QgsNewSpatialiteL
/** Create a new database */
bool createDb();

/** Initializes SpatialMetadata db-tables */
void initializeSpatialMetadata( sqlite3 *sqlite_handle );

static QString quotedIdentifier( QString id );
static QString quotedValue( QString value );
};
Expand Down
2 changes: 2 additions & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ SET(QGIS_CORE_SRCS
qgsmaprenderer.cpp
qgsmaptopixel.cpp
qgsmessageoutput.cpp
qgsmimedatautils.cpp
qgscredentials.cpp
qgsoverlayobject.cpp
qgspalgeometry.cpp
Expand Down Expand Up @@ -306,6 +307,7 @@ SET(QGIS_CORE_HDRS
qgsmaprenderer.h
qgsmaptopixel.h
qgsmessageoutput.h
qgsmimedatautils.h
qgscredentials.h
qgsoverlayobjectpositionmanager.h
qgspallabeling.h
Expand Down
41 changes: 20 additions & 21 deletions src/core/qgsbrowsermodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "qgis.h"
#include "qgsapplication.h"
#include "qgsdataprovider.h"
#include "qgsmimedatautils.h"
#include "qgslogger.h"
#include "qgsproviderregistry.h"

Expand Down Expand Up @@ -117,6 +118,8 @@ Qt::ItemFlags QgsBrowserModel::flags( const QModelIndex & index ) const
flags |= Qt::ItemIsDragEnabled;
}
}
if ( ptr->acceptDrop() )
flags |= Qt::ItemIsDropEnabled;
return flags;
}

Expand Down Expand Up @@ -342,11 +345,7 @@ QStringList QgsBrowserModel::mimeTypes() const

QMimeData * QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const
{
QMimeData *mimeData = new QMimeData();
QByteArray encodedData;

QDataStream stream( &encodedData, QIODevice::WriteOnly );

QgsMimeDataUtils::UriList lst;
foreach( const QModelIndex &index, indexes )
{
if ( index.isValid() )
Expand All @@ -355,25 +354,25 @@ QMimeData * QgsBrowserModel::mimeData( const QModelIndexList &indexes ) const
if ( ptr->type() != QgsDataItem::Layer ) continue;
QgsLayerItem *layer = ( QgsLayerItem* ) ptr;
if ( layer->providerKey() == "wms" ) continue;
QString layerType;
switch ( layer->mapLayerType() )
{
case QgsMapLayer::VectorLayer:
layerType = "vector";
break;
case QgsMapLayer::RasterLayer:
layerType = "raster";
break;
default:
continue;
}
QString xUri = layerType + ":" + layer->providerKey() + ":" + layer->name() + ":" + layer->uri();
stream << xUri;
lst.append( QgsMimeDataUtils::Uri( layer ) );
}
}
return QgsMimeDataUtils::encodeUriList( lst );
}

bool QgsBrowserModel::dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent )
{
Q_UNUSED( row );
Q_UNUSED( column );

QgsDataItem* destItem = dataItem( parent );
if ( !destItem )
{
QgsDebugMsg( "DROP PROBLEM!" );
return false;
}

mimeData->setData( "application/x-vnd.qgis.qgis.uri", encodedData );
return mimeData;
return destItem->handleDrop( data, action );
}

QgsDataItem *QgsBrowserModel::dataItem( const QModelIndex &idx ) const
Expand Down
7 changes: 6 additions & 1 deletion src/core/qgsbrowsermodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,14 @@ class CORE_EXPORT QgsBrowserModel : public QAbstractItemModel
*/
virtual QModelIndex parent( const QModelIndex &index ) const;

/** Returns a list of mime that can describe model indexes */
virtual QStringList mimeTypes() const;

QMimeData * mimeData( const QModelIndexList &indexes ) const;
/** Returns an object that contains serialized items of data corresponding to the list of indexes specified */
virtual QMimeData * mimeData( const QModelIndexList &indexes ) const;

/** Handles the data supplied by a drag and drop operation that ended with the given action */
virtual bool dropMimeData( const QMimeData * data, Qt::DropAction action, int row, int column, const QModelIndex & parent );

QgsDataItem *dataItem( const QModelIndex &idx ) const;

Expand Down
7 changes: 7 additions & 0 deletions src/core/qgsdataitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ typedef int dataCapabilities_t();
typedef QgsDataItem * dataItem_t( QString, QgsDataItem* );



/** base class for all items in the model */
class CORE_EXPORT QgsDataItem : public QObject
{
Expand Down Expand Up @@ -80,6 +81,12 @@ class CORE_EXPORT QgsDataItem : public QObject
// list of actions provided by this item - usually used for popup menu on right-click
virtual QList<QAction*> actions() { return QList<QAction*>(); }

// whether accepts drag&drop'd layers - e.g. for import
virtual bool acceptDrop() { return false; }

// try to process the data dropped on this item
virtual bool handleDrop( const QMimeData * /*data*/, Qt::DropAction /*action*/ ) { return false; }

//

enum Capability
Expand Down
Loading