Skip to content
Permalink
Browse files

Drag&Drop support for GeoPackage layers

  • Loading branch information
cedi4155476 committed Jun 26, 2015
1 parent 16ad2f8 commit 4420b3bf99d045a01498acffe77fedc95cd606f2
@@ -21,7 +21,7 @@
"""

from PyQt4.QtCore import Qt, QObject, SIGNAL, qDebug, QByteArray, QMimeData, QDataStream, QIODevice, QFileInfo, \
QAbstractItemModel, QModelIndex
QAbstractItemModel, QModelIndex, QSettings
from PyQt4.QtGui import QApplication, QIcon, QMessageBox

from .db_plugins import supportedDbTypes, createDbPlugin
@@ -359,6 +359,10 @@ def flags(self, index):

if index.column() == 0:
item = index.internalPointer()

if not isinstance(item, SchemaItem) and not isinstance(item, TableItem):
flags |= Qt.ItemIsDropEnabled

if isinstance(item, SchemaItem) or isinstance(item, TableItem):
flags |= Qt.ItemIsEditable

@@ -509,31 +513,50 @@ def dropMimeData(self, data, action, row, column, parent):
added = 0

if data.hasUrls():
for u in data.urls():
filename = u.toLocalFile()
if filename == "":
continue

if qgis.core.QgsRasterLayer.isValidRasterFileName(filename):
layerType = 'raster'
providerKey = 'gdal'
else:
layerType = 'vector'
providerKey = 'ogr'

layerName = QFileInfo(filename).completeBaseName()

if self.importLayer(layerType, providerKey, layerName, filename, parent):
added += 1

if data.hasFormat(self.QGIS_URI_MIME):
for uri in qgis.core.QgsMimeDataUtils.decodeUriList(data):
if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent):
added += 1
if row == -1 and column == -1:
for u in data.urls():
filename = u.toLocalFile()
if self.addConnection(filename, parent):
added += 1
else:
for u in data.urls():
filename = u.toLocalFile()
if filename == "":
continue

if qgis.core.QgsRasterLayer.isValidRasterFileName(filename):
layerType = 'raster'
providerKey = 'gdal'
else:
layerType = 'vector'
providerKey = 'ogr'

layerName = QFileInfo(filename).completeBaseName()

if self.importLayer(layerType, providerKey, layerName, filename, parent):
added += 1

if data.hasFormat(self.QGIS_URI_MIME):
for uri in qgis.core.QgsMimeDataUtils.decodeUriList(data):
if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent):
added += 1

return added > 0


def addConnection(self, filename, index):
file = filename.split("/")[-1]
if filename == "":
return False
s = QSettings()
connKey = index.internalPointer().getItemData().connectionSettingsKey()
conn = index.internalPointer().getItemData().connectionSettingsFileKey()
s.beginGroup("/%s/%s" % (connKey, file))
s.setValue(conn, filename)
self.treeView.setCurrentIndex(index)
self.treeView.mainWindow.refreshActionSlot()
return True

def importLayer(self, layerType, providerKey, layerName, uriString, parent):
if not self.isImportVectorAvail:
return False
@@ -132,6 +132,11 @@ def connectionSettingsKey(self):
# return the key used to store the connections in settings
pass

@classmethod
def connectionSettingsFileKey(self):
# return the filekey for the settings
pass

@classmethod
def connections(self):
# get the list of connections
@@ -632,6 +637,9 @@ def uri(self):

def mimeUri(self):
layerType = "raster" if self.type == Table.RasterType else "vector"
if self.database().connector.isgpkg():
url = str(self.database().connector._connectionInfo() + "|layername=" + self.name)
return u"%s:%s:%s:%s" % (layerType, "ogr", self.name, url)
return u"%s:%s:%s:%s" % (layerType, self.database().dbplugin().providerName(), self.name, self.uri().uri())

def toMapLayer(self):
@@ -62,6 +62,10 @@ def providerName(self):
def connectionSettingsKey(self):
return '/PostgreSQL/connections'

@classmethod
def connectionSettingsFileKey(self):
return "database"

def databasesFactory(self, connection, uri):
return PGDatabase(connection, uri)

@@ -125,6 +125,15 @@ def hasTableColumnEditingSupport(self):
def hasCreateSpatialViewSupport(self):
return True

def isgpkg(self):
info = float(self.getInfo()[0][:-2])
if info < 4.2:
result = self.uri().database()[-5:] == ".gpkg"
else:
sql = u"SELECT HasGeoPackage()"
result = self._execute(None, sql).fetchone()[0] == 1
return result

def fieldTypes(self):
return [
"integer", "bigint", "smallint", # integers
@@ -51,7 +51,7 @@ def typeName(self):

@classmethod
def typeNameString(self):
return 'SpatiaLite'
return 'SpatiaLite/Geopackage'

@classmethod
def providerName(self):
@@ -61,6 +61,10 @@ def providerName(self):
def connectionSettingsKey(self):
return '/SpatiaLite/connections'

@classmethod
def connectionSettingsFileKey(self):
return "sqlitepath"

def databasesFactory(self, connection, uri):
return SLDatabase(connection, uri)

@@ -20,8 +20,8 @@
***************************************************************************/
"""

from PyQt4.QtCore import SIGNAL, SLOT
from PyQt4.QtGui import QWidget, QTreeView, QMenu, QLabel
from PyQt4.QtCore import SIGNAL, SLOT, QSettings, Qt
from PyQt4.QtGui import QWidget, QTreeView, QMenu, QLabel, QFileDialog

from qgis.core import QgsMapLayerRegistry, QgsMessageLog
from qgis.gui import QgsMessageBar, QgsMessageBarItem
@@ -90,6 +90,12 @@ def currentTable(self):
return item
return None

def openConnection(self):
index = self.selectedIndexes()[0]
if index:
if index.data() != "PostGIS":
filename = QFileDialog.getOpenFileName(self, "Open File")
self.model().addConnection(filename, index)

def itemChanged(self, index):
self.setCurrentIndex(index)
@@ -123,6 +129,10 @@ def contextMenuEvent(self, ev):

elif isinstance(item, DBPlugin) and item.database() is not None:
menu.addAction(self.tr("Re-connect"), self.reconnect)
menu.addAction(self.tr("Delete"), self.delActionSlot)

elif not index.parent().data():
menu.addAction(self.tr("New Connection..."), self.openConnection)

if not menu.isEmpty():
menu.exec_(ev.globalPos())
@@ -135,6 +145,23 @@ def rename(self):
if isinstance(item, (Table, Schema)):
self.edit(index)

def delActionSlot(self):
db = self.currentDatabase()
path = db.uri().database()
connkey = db.connection().connectionSettingsKey()
self.deletedb(path, connkey)

index = self.currentIndex().parent()
self.setCurrentIndex(index)
self.mainWindow.refreshActionSlot()

def deletedb(self, path, conn):
paths = path.split("/")
path = paths[-1]
s = QSettings()
s.beginGroup("/%s/%s" % (conn, path))
s.remove("")

def delete(self):
item = self.currentItem()
if isinstance(item, (Table, Schema)):
Binary file not shown.
@@ -27,5 +27,6 @@
<file alias="create_table">icons/toolbar/action_new_table.png</file>
<file alias="refresh">icons/toolbar/action_refresh.png</file>
<file alias="sql_window">icons/toolbar/action_sql_window.png</file>
<file alias="delete">icons/toolbar/action_delete.png</file>
</qresource>
</RCC>

1 comment on commit 4420b3b

@gioman

This comment has been minimized.

Copy link
Contributor

@gioman gioman commented on 4420b3b Jul 30, 2015

Is this the commit that added Geopackage support to DB Manager? I have just tested QGIS master and while it is possible to add new geopackage connections (in DB Manager) then all the layers/tables are listed as geometryless and anyway is not possible to add them to the project. Adding geopackage layers using the "add vector" dialog works. Geopackage connections are still not working in the QGIS browser.

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