Drag&Drop support for GeoPackage layers

This commit is contained in:
Cedric Christen 2015-06-26 16:35:31 +02:00
parent 16ad2f82d4
commit 4420b3bf99
8 changed files with 97 additions and 21 deletions

View File

@ -21,7 +21,7 @@ email : brush.tyler@gmail.com
""" """
from PyQt4.QtCore import Qt, QObject, SIGNAL, qDebug, QByteArray, QMimeData, QDataStream, QIODevice, QFileInfo, \ 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 PyQt4.QtGui import QApplication, QIcon, QMessageBox
from .db_plugins import supportedDbTypes, createDbPlugin from .db_plugins import supportedDbTypes, createDbPlugin
@ -359,6 +359,10 @@ class DBModel(QAbstractItemModel):
if index.column() == 0: if index.column() == 0:
item = index.internalPointer() item = index.internalPointer()
if not isinstance(item, SchemaItem) and not isinstance(item, TableItem):
flags |= Qt.ItemIsDropEnabled
if isinstance(item, SchemaItem) or isinstance(item, TableItem): if isinstance(item, SchemaItem) or isinstance(item, TableItem):
flags |= Qt.ItemIsEditable flags |= Qt.ItemIsEditable
@ -509,31 +513,50 @@ class DBModel(QAbstractItemModel):
added = 0 added = 0
if data.hasUrls(): if data.hasUrls():
for u in data.urls(): if row == -1 and column == -1:
filename = u.toLocalFile() for u in data.urls():
if filename == "": filename = u.toLocalFile()
continue 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): if qgis.core.QgsRasterLayer.isValidRasterFileName(filename):
layerType = 'raster' layerType = 'raster'
providerKey = 'gdal' providerKey = 'gdal'
else: else:
layerType = 'vector' layerType = 'vector'
providerKey = 'ogr' providerKey = 'ogr'
layerName = QFileInfo(filename).completeBaseName() layerName = QFileInfo(filename).completeBaseName()
if self.importLayer(layerType, providerKey, layerName, filename, parent): if self.importLayer(layerType, providerKey, layerName, filename, parent):
added += 1 added += 1
if data.hasFormat(self.QGIS_URI_MIME): if data.hasFormat(self.QGIS_URI_MIME):
for uri in qgis.core.QgsMimeDataUtils.decodeUriList(data): for uri in qgis.core.QgsMimeDataUtils.decodeUriList(data):
if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent): if self.importLayer(uri.layerType, uri.providerKey, uri.name, uri.uri, parent):
added += 1 added += 1
return added > 0 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): def importLayer(self, layerType, providerKey, layerName, uriString, parent):
if not self.isImportVectorAvail: if not self.isImportVectorAvail:
return False return False

View File

@ -132,6 +132,11 @@ class DBPlugin(QObject):
# return the key used to store the connections in settings # return the key used to store the connections in settings
pass pass
@classmethod
def connectionSettingsFileKey(self):
# return the filekey for the settings
pass
@classmethod @classmethod
def connections(self): def connections(self):
# get the list of connections # get the list of connections
@ -632,6 +637,9 @@ class Table(DbItemObject):
def mimeUri(self): def mimeUri(self):
layerType = "raster" if self.type == Table.RasterType else "vector" 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()) return u"%s:%s:%s:%s" % (layerType, self.database().dbplugin().providerName(), self.name, self.uri().uri())
def toMapLayer(self): def toMapLayer(self):

View File

@ -62,6 +62,10 @@ class PostGisDBPlugin(DBPlugin):
def connectionSettingsKey(self): def connectionSettingsKey(self):
return '/PostgreSQL/connections' return '/PostgreSQL/connections'
@classmethod
def connectionSettingsFileKey(self):
return "database"
def databasesFactory(self, connection, uri): def databasesFactory(self, connection, uri):
return PGDatabase(connection, uri) return PGDatabase(connection, uri)

View File

@ -125,6 +125,15 @@ class SpatiaLiteDBConnector(DBConnector):
def hasCreateSpatialViewSupport(self): def hasCreateSpatialViewSupport(self):
return True 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): def fieldTypes(self):
return [ return [
"integer", "bigint", "smallint", # integers "integer", "bigint", "smallint", # integers

View File

@ -51,7 +51,7 @@ class SpatiaLiteDBPlugin(DBPlugin):
@classmethod @classmethod
def typeNameString(self): def typeNameString(self):
return 'SpatiaLite' return 'SpatiaLite/Geopackage'
@classmethod @classmethod
def providerName(self): def providerName(self):
@ -61,6 +61,10 @@ class SpatiaLiteDBPlugin(DBPlugin):
def connectionSettingsKey(self): def connectionSettingsKey(self):
return '/SpatiaLite/connections' return '/SpatiaLite/connections'
@classmethod
def connectionSettingsFileKey(self):
return "sqlitepath"
def databasesFactory(self, connection, uri): def databasesFactory(self, connection, uri):
return SLDatabase(connection, uri) return SLDatabase(connection, uri)

View File

@ -20,8 +20,8 @@ email : brush.tyler@gmail.com
***************************************************************************/ ***************************************************************************/
""" """
from PyQt4.QtCore import SIGNAL, SLOT from PyQt4.QtCore import SIGNAL, SLOT, QSettings, Qt
from PyQt4.QtGui import QWidget, QTreeView, QMenu, QLabel from PyQt4.QtGui import QWidget, QTreeView, QMenu, QLabel, QFileDialog
from qgis.core import QgsMapLayerRegistry, QgsMessageLog from qgis.core import QgsMapLayerRegistry, QgsMessageLog
from qgis.gui import QgsMessageBar, QgsMessageBarItem from qgis.gui import QgsMessageBar, QgsMessageBarItem
@ -90,6 +90,12 @@ class DBTree(QTreeView):
return item return item
return None 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): def itemChanged(self, index):
self.setCurrentIndex(index) self.setCurrentIndex(index)
@ -123,6 +129,10 @@ class DBTree(QTreeView):
elif isinstance(item, DBPlugin) and item.database() is not None: elif isinstance(item, DBPlugin) and item.database() is not None:
menu.addAction(self.tr("Re-connect"), self.reconnect) 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(): if not menu.isEmpty():
menu.exec_(ev.globalPos()) menu.exec_(ev.globalPos())
@ -135,6 +145,23 @@ class DBTree(QTreeView):
if isinstance(item, (Table, Schema)): if isinstance(item, (Table, Schema)):
self.edit(index) 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): def delete(self):
item = self.currentItem() item = self.currentItem()
if isinstance(item, (Table, Schema)): if isinstance(item, (Table, Schema)):

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -27,5 +27,6 @@
<file alias="create_table">icons/toolbar/action_new_table.png</file> <file alias="create_table">icons/toolbar/action_new_table.png</file>
<file alias="refresh">icons/toolbar/action_refresh.png</file> <file alias="refresh">icons/toolbar/action_refresh.png</file>
<file alias="sql_window">icons/toolbar/action_sql_window.png</file> <file alias="sql_window">icons/toolbar/action_sql_window.png</file>
<file alias="delete">icons/toolbar/action_delete.png</file>
</qresource> </qresource>
</RCC> </RCC>