174 changes: 87 additions & 87 deletions python/plugins/db_manager/db_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,121 +29,121 @@
from .db_plugins.plugin import DBPlugin, Schema, Table

class DBTree(QTreeView):
def __init__(self, mainWindow):
QTreeView.__init__(self, mainWindow)
self.mainWindow = mainWindow
def __init__(self, mainWindow):
QTreeView.__init__(self, mainWindow)
self.mainWindow = mainWindow

self.setModel( DBModel(self) )
self.setHeaderHidden(True)
self.setEditTriggers(QTreeView.EditKeyPressed|QTreeView.SelectedClicked)
self.setModel( DBModel(self) )
self.setHeaderHidden(True)
self.setEditTriggers(QTreeView.EditKeyPressed|QTreeView.SelectedClicked)

self.setDragEnabled(True)
self.setAcceptDrops(True)
self.setDropIndicatorShown(True)
self.setDragEnabled(True)
self.setAcceptDrops(True)
self.setDropIndicatorShown(True)

self.connect(self.selectionModel(), SIGNAL("currentChanged(const QModelIndex&, const QModelIndex&)"), self.currentItemChanged)
self.connect(self, SIGNAL("expanded(const QModelIndex&)"), self.itemChanged)
self.connect(self, SIGNAL("collapsed(const QModelIndex&)"), self.itemChanged)
self.connect(self.model(), SIGNAL("dataChanged(const QModelIndex&, const QModelIndex&)"), self.modelDataChanged)
self.connect(self.model(), SIGNAL("notPopulated"), self.collapse)
self.connect(self.selectionModel(), SIGNAL("currentChanged(const QModelIndex&, const QModelIndex&)"), self.currentItemChanged)
self.connect(self, SIGNAL("expanded(const QModelIndex&)"), self.itemChanged)
self.connect(self, SIGNAL("collapsed(const QModelIndex&)"), self.itemChanged)
self.connect(self.model(), SIGNAL("dataChanged(const QModelIndex&, const QModelIndex&)"), self.modelDataChanged)
self.connect(self.model(), SIGNAL("notPopulated"), self.collapse)

def refreshItem(self, item=None):
if item == None:
item = self.currentItem()
if item == None: return
self.model().refreshItem(item)
def refreshItem(self, item=None):
if item == None:
item = self.currentItem()
if item == None: return
self.model().refreshItem(item)

def showSystemTables(self, show):
pass
def showSystemTables(self, show):
pass

def currentItem(self):
indexes = self.selectedIndexes()
if len(indexes) <= 0:
return
return self.model().getItem(indexes[0])
def currentItem(self):
indexes = self.selectedIndexes()
if len(indexes) <= 0:
return
return self.model().getItem(indexes[0])


def currentDatabase(self):
item = self.currentItem()
if item == None: return
def currentDatabase(self):
item = self.currentItem()
if item == None: return

if isinstance(item, (DBPlugin, Schema, Table)):
return item.database()
return None
if isinstance(item, (DBPlugin, Schema, Table)):
return item.database()
return None

def currentSchema(self):
item = self.currentItem()
if item == None: return
def currentSchema(self):
item = self.currentItem()
if item == None: return

if isinstance(item, (Schema, Table)):
return item.schema()
return None
if isinstance(item, (Schema, Table)):
return item.schema()
return None

def currentTable(self):
item = self.currentItem()
if item == None: return
def currentTable(self):
item = self.currentItem()
if item == None: return

if isinstance(item, Table):
return item
return None
if isinstance(item, Table):
return item
return None


def itemChanged(self, index):
self.setCurrentIndex(index)
self.emit( SIGNAL('selectedItemChanged'), self.currentItem() )
def itemChanged(self, index):
self.setCurrentIndex(index)
self.emit( SIGNAL('selectedItemChanged'), self.currentItem() )

def modelDataChanged(self, indexFrom, indexTo):
self.itemChanged(indexTo)
def modelDataChanged(self, indexFrom, indexTo):
self.itemChanged(indexTo)

def currentItemChanged(self, current, previous):
self.itemChanged(current)
def currentItemChanged(self, current, previous):
self.itemChanged(current)

def contextMenuEvent(self, ev):
index = self.indexAt( ev.pos() )
if not index.isValid():
return
def contextMenuEvent(self, ev):
index = self.indexAt( ev.pos() )
if not index.isValid():
return

if index != self.currentIndex():
self.itemChanged(index)
if index != self.currentIndex():
self.itemChanged(index)

item = self.currentItem()
item = self.currentItem()

menu = QMenu(self)
menu = QMenu(self)

if isinstance(item, (Table, Schema)):
menu.addAction("Rename", self.rename)
menu.addAction("Delete", self.delete)
if isinstance(item, (Table, Schema)):
menu.addAction("Rename", self.rename)
menu.addAction("Delete", self.delete)

if isinstance(item, Table):
menu.addSeparator()
menu.addAction("Add to QGis canvas", self.addLayer)
if isinstance(item, Table):
menu.addSeparator()
menu.addAction("Add to QGis canvas", self.addLayer)

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

if not menu.isEmpty():
menu.exec_(ev.globalPos())
if not menu.isEmpty():
menu.exec_(ev.globalPos())

menu.deleteLater()
menu.deleteLater()

def rename(self):
index = self.currentIndex()
item = self.model().getItem(index)
if isinstance(item, (Table, Schema)):
self.edit( index )
def rename(self):
index = self.currentIndex()
item = self.model().getItem(index)
if isinstance(item, (Table, Schema)):
self.edit( index )

def delete(self):
item = self.currentItem()
if isinstance(item, (Table, Schema)):
self.mainWindow.invokeCallback(item.database().deleteActionSlot)
def delete(self):
item = self.currentItem()
if isinstance(item, (Table, Schema)):
self.mainWindow.invokeCallback(item.database().deleteActionSlot)

def addLayer(self):
table = self.currentTable()
if table is not None:
QgsMapLayerRegistry.instance().addMapLayer(table.toMapLayer())
def addLayer(self):
table = self.currentTable()
if table is not None:
QgsMapLayerRegistry.instance().addMapLayers([table.toMapLayer()])

def reconnect(self):
db = self.currentDatabase()
if db is not None:
self.mainWindow.invokeCallback(db.reconnectActionSlot)
def reconnect(self):
db = self.currentDatabase()
if db is not None:
self.mainWindow.invokeCallback(db.reconnectActionSlot)

378 changes: 189 additions & 189 deletions python/plugins/db_manager/dlg_sql_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,193 +35,193 @@

class DlgSqlWindow(QDialog, Ui_Dialog):

def __init__(self, iface, db, parent=None):
QDialog.__init__(self, parent)
self.iface = iface
self.db = db
self.setupUi(self)
self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()) )

self.defaultLayerName = 'QueryLayer'

settings = QSettings()
self.restoreGeometry(settings.value("/DB_Manager/sqlWindow/geometry").toByteArray())

self.editSql.setAcceptRichText(False)
SqlCompleter(self.editSql, self.db)
SqlHighlighter(self.editSql, self.db)

# allow to copy results
copyAction = QAction("copy", self)
self.viewResult.addAction( copyAction )
copyAction.setShortcuts(QKeySequence.Copy)
QObject.connect(copyAction, SIGNAL("triggered()"), self.copySelectedResults)

self.connect(self.btnExecute, SIGNAL("clicked()"), self.executeSql)
self.connect(self.btnClear, SIGNAL("clicked()"), self.clearSql)
self.connect(self.buttonBox.button(QDialogButtonBox.Close), SIGNAL("clicked()"), self.close)

# hide the load query as layer if feature is not supported
self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport()
self.loadAsLayerGroup.setVisible( self._loadAsLayerAvailable )
if self._loadAsLayerAvailable:
self.layerTypeWidget.hide() # show if load as raster is supported
self.connect(self.loadLayerBtn, SIGNAL("clicked()"), self.loadSqlLayer)
self.connect(self.getColumnsBtn, SIGNAL("clicked()"), self.fillColumnCombos)
self.connect(self.loadAsLayerGroup, SIGNAL("toggled(bool)"), self.loadAsLayerToggled)
self.loadAsLayerToggled(False)


def closeEvent(self, e):
""" save window state """
settings = QSettings()
settings.setValue("/DB_Manager/sqlWindow/geometry", QVariant(self.saveGeometry()))

QDialog.closeEvent(self, e)

def loadAsLayerToggled(self, checked):
self.loadAsLayerGroup.setChecked( checked )
self.loadAsLayerWidget.setVisible( checked )

def getSql(self):
# If the selection obtained from an editor spans a line break,
# the text will contain a Unicode U+2029 paragraph separator
# character instead of a newline \n character
# (see https://qt-project.org/doc/qt-4.8/qtextcursor.html#selectedText)
sql = self.editSql.textCursor().selectedText().replace(unichr(0x2029), "\n")
if sql.isEmpty():
sql = self.editSql.toPlainText()
# try to sanitize query
sql = sql.replace( QRegExp( ";\\s*$" ), "" )
return sql

def clearSql(self):
self.editSql.clear()

def executeSql(self):
sql = self.getSql()
if sql.isEmpty(): return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

# delete the old model
old_model = self.viewResult.model()
self.viewResult.setModel(None)
if old_model: old_model.deleteLater()

self.uniqueCombo.clear()
self.geomCombo.clear()

try:
# set the new model
model = self.db.sqlResultModel( sql, self )
self.viewResult.setModel( model )
self.lblResult.setText("%d rows, %.1f seconds" % (model.affectedRows(), model.secs()))

except BaseError, e:
QApplication.restoreOverrideCursor()
DlgDbError.showError(e, self)
return

cols = self.viewResult.model().columnNames()
cols.sort()
self.uniqueCombo.addItems( cols )
self.geomCombo.addItems( cols )

self.update()
QApplication.restoreOverrideCursor()

def loadSqlLayer(self):
uniqueFieldName = self.uniqueCombo.currentText()
geomFieldName = self.geomCombo.currentText()

if geomFieldName.isEmpty() or uniqueFieldName.isEmpty():
QMessageBox.warning(self, self.tr( "Sorry" ), self.tr( "You must fill the required fields: \ngeometry column - column with unique integer values" ) )
return

query = self.getSql()
if query.isEmpty():
return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

from qgis.core import QgsMapLayer, QgsMapLayerRegistry
layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer

# get a new layer name
names = []
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
names.append( layer.name() )

layerName = self.layerNameEdit.text()
if layerName.isEmpty():
layerName = self.defaultLayerName
newLayerName = layerName
index = 1
while newLayerName in names:
index += 1
newLayerName = u"%s_%d" % (layerName, index)

# create the layer
layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked())
if layer.isValid():
QgsMapLayerRegistry.instance().addMapLayer(layer, True)

QApplication.restoreOverrideCursor()

def fillColumnCombos(self):
query = self.getSql()
if query.isEmpty(): return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.uniqueCombo.clear()
self.geomCombo.clear()

# get a new alias
aliasIndex = 0
while True:
alias = "_%s__%d" % ("subQuery", aliasIndex)
escaped = '\\b("?)' + QRegExp.escape(alias) + '\\1\\b'
if not query.contains( QRegExp(escaped, Qt.CaseInsensitive) ):
break
aliasIndex += 1

# get all the columns
cols = []
connector = self.db.connector
sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % ( unicode(query), connector.quoteId(alias) )

c = None
try:
c = connector._execute(None, sql)
cols = connector._get_cursor_columns(c)

except BaseError as e:
QApplication.restoreOverrideCursor()
DlgDbError.showError(e, self)
return

finally:
if c:
c.close()
del c

cols.sort()
self.uniqueCombo.addItems( cols )
self.geomCombo.addItems( cols )

QApplication.restoreOverrideCursor()

def copySelectedResults(self):
if len(self.viewResult.selectedIndexes()) <= 0:
return
model = self.viewResult.model()

# convert to string using tab as separator
text = model.headerToString( "\t" )
for idx in self.viewResult.selectionModel().selectedRows():
text += "\n" + model.rowToString( idx.row(), "\t" )

QApplication.clipboard().setText( text, QClipboard.Selection )
QApplication.clipboard().setText( text, QClipboard.Clipboard )
def __init__(self, iface, db, parent=None):
QDialog.__init__(self, parent)
self.iface = iface
self.db = db
self.setupUi(self)
self.setWindowTitle( u"%s - %s [%s]" % (self.windowTitle(), db.connection().connectionName(), db.connection().typeNameString()) )

self.defaultLayerName = 'QueryLayer'

settings = QSettings()
self.restoreGeometry(settings.value("/DB_Manager/sqlWindow/geometry").toByteArray())

self.editSql.setAcceptRichText(False)
SqlCompleter(self.editSql, self.db)
SqlHighlighter(self.editSql, self.db)

# allow to copy results
copyAction = QAction("copy", self)
self.viewResult.addAction( copyAction )
copyAction.setShortcuts(QKeySequence.Copy)
QObject.connect(copyAction, SIGNAL("triggered()"), self.copySelectedResults)

self.connect(self.btnExecute, SIGNAL("clicked()"), self.executeSql)
self.connect(self.btnClear, SIGNAL("clicked()"), self.clearSql)
self.connect(self.buttonBox.button(QDialogButtonBox.Close), SIGNAL("clicked()"), self.close)

# hide the load query as layer if feature is not supported
self._loadAsLayerAvailable = self.db.connector.hasCustomQuerySupport()
self.loadAsLayerGroup.setVisible( self._loadAsLayerAvailable )
if self._loadAsLayerAvailable:
self.layerTypeWidget.hide() # show if load as raster is supported
self.connect(self.loadLayerBtn, SIGNAL("clicked()"), self.loadSqlLayer)
self.connect(self.getColumnsBtn, SIGNAL("clicked()"), self.fillColumnCombos)
self.connect(self.loadAsLayerGroup, SIGNAL("toggled(bool)"), self.loadAsLayerToggled)
self.loadAsLayerToggled(False)


def closeEvent(self, e):
""" save window state """
settings = QSettings()
settings.setValue("/DB_Manager/sqlWindow/geometry", QVariant(self.saveGeometry()))

QDialog.closeEvent(self, e)

def loadAsLayerToggled(self, checked):
self.loadAsLayerGroup.setChecked( checked )
self.loadAsLayerWidget.setVisible( checked )

def getSql(self):
# If the selection obtained from an editor spans a line break,
# the text will contain a Unicode U+2029 paragraph separator
# character instead of a newline \n character
# (see https://qt-project.org/doc/qt-4.8/qtextcursor.html#selectedText)
sql = self.editSql.textCursor().selectedText().replace(unichr(0x2029), "\n")
if sql.isEmpty():
sql = self.editSql.toPlainText()
# try to sanitize query
sql = sql.replace( QRegExp( ";\\s*$" ), "" )
return sql

def clearSql(self):
self.editSql.clear()

def executeSql(self):
sql = self.getSql()
if sql.isEmpty(): return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

# delete the old model
old_model = self.viewResult.model()
self.viewResult.setModel(None)
if old_model: old_model.deleteLater()

self.uniqueCombo.clear()
self.geomCombo.clear()

try:
# set the new model
model = self.db.sqlResultModel( sql, self )
self.viewResult.setModel( model )
self.lblResult.setText("%d rows, %.1f seconds" % (model.affectedRows(), model.secs()))

except BaseError, e:
QApplication.restoreOverrideCursor()
DlgDbError.showError(e, self)
return

cols = self.viewResult.model().columnNames()
cols.sort()
self.uniqueCombo.addItems( cols )
self.geomCombo.addItems( cols )

self.update()
QApplication.restoreOverrideCursor()

def loadSqlLayer(self):
uniqueFieldName = self.uniqueCombo.currentText()
geomFieldName = self.geomCombo.currentText()

if geomFieldName.isEmpty() or uniqueFieldName.isEmpty():
QMessageBox.warning(self, self.tr( "Sorry" ), self.tr( "You must fill the required fields: \ngeometry column - column with unique integer values" ) )
return

query = self.getSql()
if query.isEmpty():
return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))

from qgis.core import QgsMapLayer, QgsMapLayerRegistry
layerType = QgsMapLayer.VectorLayer if self.vectorRadio.isChecked() else QgsMapLayer.RasterLayer

# get a new layer name
names = []
for layer in QgsMapLayerRegistry.instance().mapLayers().values():
names.append( layer.name() )

layerName = self.layerNameEdit.text()
if layerName.isEmpty():
layerName = self.defaultLayerName
newLayerName = layerName
index = 1
while newLayerName in names:
index += 1
newLayerName = u"%s_%d" % (layerName, index)

# create the layer
layer = self.db.toSqlLayer(query, geomFieldName, uniqueFieldName, newLayerName, layerType, self.avoidSelectById.isChecked())
if layer.isValid():
QgsMapLayerRegistry.instance().addMapLayers([layer], True)

QApplication.restoreOverrideCursor()

def fillColumnCombos(self):
query = self.getSql()
if query.isEmpty(): return

QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.uniqueCombo.clear()
self.geomCombo.clear()

# get a new alias
aliasIndex = 0
while True:
alias = "_%s__%d" % ("subQuery", aliasIndex)
escaped = '\\b("?)' + QRegExp.escape(alias) + '\\1\\b'
if not query.contains( QRegExp(escaped, Qt.CaseInsensitive) ):
break
aliasIndex += 1

# get all the columns
cols = []
connector = self.db.connector
sql = u"SELECT * FROM (%s\n) AS %s LIMIT 0" % ( unicode(query), connector.quoteId(alias) )

c = None
try:
c = connector._execute(None, sql)
cols = connector._get_cursor_columns(c)

except BaseError as e:
QApplication.restoreOverrideCursor()
DlgDbError.showError(e, self)
return

finally:
if c:
c.close()
del c

cols.sort()
self.uniqueCombo.addItems( cols )
self.geomCombo.addItems( cols )

QApplication.restoreOverrideCursor()

def copySelectedResults(self):
if len(self.viewResult.selectedIndexes()) <= 0:
return
model = self.viewResult.model()

# convert to string using tab as separator
text = model.headerToString( "\t" )
for idx in self.viewResult.selectionModel().selectedRows():
text += "\n" + model.rowToString( idx.row(), "\t" )

QApplication.clipboard().setText( text, QClipboard.Selection )
QApplication.clipboard().setText( text, QClipboard.Clipboard )

176 changes: 88 additions & 88 deletions python/plugins/db_manager/layer_preview.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,92 +29,92 @@
from .db_plugins.plugin import DbError, Table

class LayerPreview(QgsMapCanvas):
def __init__(self, parent=None):
QgsMapCanvas.__init__(self, parent)
self.setCanvasColor(QColor(255,255,255))

self.item = None
self.dirty = False

# reuse settings from QGIS
settings = QSettings()
self.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", QVariant(False) ).toBool() )
self.useImageToRender( settings.value( "/qgis/use_qimage_to_render", QVariant(False) ).toBool() )
action = settings.value( "/qgis/wheel_action", QVariant(0) ).toInt()[0]
zoomFactor = settings.value( "/qgis/zoom_factor", QVariant(2) ).toDouble()[0]
self.setWheelAction( QgsMapCanvas.WheelAction(action), zoomFactor )

self._clear()


def refresh(self):
self.setDirty(True)
self.loadPreview( self.item )

def loadPreview(self, item, force=False):
if item == self.item and not self.dirty:
return
self._clear()
if item is None:
return

if isinstance(item, Table) and item.type in [Table.VectorType, Table.RasterType]:
# update the preview, but first let the manager chance to show the canvas
runPrev = lambda: self._loadTablePreview( item )
QTimer.singleShot(50, runPrev)
else:
return

self.item = item
self.connect(self.item, SIGNAL('aboutToChange'), self.setDirty)

def setDirty(self, val=True):
self.dirty = val

def _clear(self):
""" remove any layers from preview canvas """
if self.item is not None:
self.disconnect(self.item, SIGNAL('aboutToChange'), self.setDirty)
self.item = None
self.dirty = False

self.currentLayerId = None
self.setLayerSet( [] )

def _loadTablePreview(self, table, limit=False):
""" if has geometry column load to map canvas """
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.setRenderFlag(False)
newLayerId = None

if table.geomType:
# limit the query result if required
if limit and table.rowCount > 1000:
uniqueField = table.getValidQGisUniqueFields(True)
if uniqueField == None:
QMessageBox.warning(self, "Sorry", "Unable to find a valid unique field")
return

uri = table.database().uri()
uri.setDataSource("", u"(SELECT * FROM %s LIMIT 1000)" % table.quotedName(), table.geomColumn, "", uniqueField.name)
provider = table.database().dbplugin().providerName()
vl = QgsVectorLayer(uri.uri(), table.name, provider)
else:
vl = table.toMapLayer()

if not vl.isValid():
self.setLayerSet( [] )
else:
newLayerId = vl.id() if hasattr(vl, 'id') else vl.getLayerID()
self.setLayerSet( [ QgsMapCanvasLayer(vl) ] )
QgsMapLayerRegistry.instance().addMapLayer(vl, False)
self.zoomToFullExtent()

# remove old layer (if any) and set new
if self.currentLayerId:
QgsMapLayerRegistry.instance().removeMapLayer(self.currentLayerId, False)
self.currentLayerId = newLayerId

self.setRenderFlag(True)
QApplication.restoreOverrideCursor()
def __init__(self, parent=None):
QgsMapCanvas.__init__(self, parent)
self.setCanvasColor(QColor(255,255,255))

self.item = None
self.dirty = False

# reuse settings from QGIS
settings = QSettings()
self.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", QVariant(False) ).toBool() )
self.useImageToRender( settings.value( "/qgis/use_qimage_to_render", QVariant(False) ).toBool() )
action = settings.value( "/qgis/wheel_action", QVariant(0) ).toInt()[0]
zoomFactor = settings.value( "/qgis/zoom_factor", QVariant(2) ).toDouble()[0]
self.setWheelAction( QgsMapCanvas.WheelAction(action), zoomFactor )

self._clear()


def refresh(self):
self.setDirty(True)
self.loadPreview( self.item )

def loadPreview(self, item, force=False):
if item == self.item and not self.dirty:
return
self._clear()
if item is None:
return

if isinstance(item, Table) and item.type in [Table.VectorType, Table.RasterType]:
# update the preview, but first let the manager chance to show the canvas
runPrev = lambda: self._loadTablePreview( item )
QTimer.singleShot(50, runPrev)
else:
return

self.item = item
self.connect(self.item, SIGNAL('aboutToChange'), self.setDirty)

def setDirty(self, val=True):
self.dirty = val

def _clear(self):
""" remove any layers from preview canvas """
if self.item is not None:
self.disconnect(self.item, SIGNAL('aboutToChange'), self.setDirty)
self.item = None
self.dirty = False

self.currentLayerId = None
self.setLayerSet( [] )

def _loadTablePreview(self, table, limit=False):
""" if has geometry column load to map canvas """
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
self.setRenderFlag(False)
newLayerId = None

if table.geomType:
# limit the query result if required
if limit and table.rowCount > 1000:
uniqueField = table.getValidQGisUniqueFields(True)
if uniqueField == None:
QMessageBox.warning(self, "Sorry", "Unable to find a valid unique field")
return

uri = table.database().uri()
uri.setDataSource("", u"(SELECT * FROM %s LIMIT 1000)" % table.quotedName(), table.geomColumn, "", uniqueField.name)
provider = table.database().dbplugin().providerName()
vl = QgsVectorLayer(uri.uri(), table.name, provider)
else:
vl = table.toMapLayer()

if not vl.isValid():
self.setLayerSet( [] )
else:
newLayerId = vl.id() if hasattr(vl, 'id') else vl.getLayerID()
self.setLayerSet( [ QgsMapCanvasLayer(vl) ] )
QgsMapLayerRegistry.instance().addMapLayers([vl], False)
self.zoomToFullExtent()

# remove old layer (if any) and set new
if self.currentLayerId:
QgsMapLayerRegistry.instance().removeMapLayer(self.currentLayerId, False)
self.currentLayerId = newLayerId

self.setRenderFlag(True)
QApplication.restoreOverrideCursor()

2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doMeanCoords.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ def accept(self):
addToTOC = QMessageBox.question(self, self.tr("Coordinate statistics"), self.tr("Created output point shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg( outPath ), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(vlayer)
QgsMapLayerRegistry.instance().addMapLayers([vlayer])
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doPointsInPolygon.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ def processFinished(self):
fileInfo = QFileInfo( self.outShape.text() )
layerName = fileInfo.completeBaseName()
layer = QgsVectorLayer(self.outShape.text(), layerName, "ogr")
QgsMapLayerRegistry.instance().addMapLayer(layer)
QgsMapLayerRegistry.instance().addMapLayers([layer])
self.populateLayers()

self.restoreGui()
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doRandPoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def accept(self):
self.tr("Created output point shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg(outPath), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
QgsMapLayerRegistry.instance().addMapLayer([self.vlayer])
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doRegPoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ def accept(self):
addToTOC = QMessageBox.question(self, self.tr("Generate Regular Points"), self.tr("Created output point shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg( outPath ), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
QgsMapLayerRegistry.instance().addMapLayer([self.vlayer])
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doSpatialJoin.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ def accept(self):
.arg(unicode(outPath)), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
QgsMapLayerRegistry.instance().addMapLayer([self.vlayer])
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )

Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/doSumLines.py
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ def accept(self):
addToTOC = QMessageBox.question(self, self.tr("Sum line lengths"), self.tr("Created output shapefile:\n%1\n\nWould you like to add the new layer to the TOC?").arg(unicode(outPath)), QMessageBox.Yes, QMessageBox.No, QMessageBox.NoButton)
if addToTOC == QMessageBox.Yes:
self.vlayer = QgsVectorLayer(outPath, unicode(outName), "ogr")
QgsMapLayerRegistry.instance().addMapLayer(self.vlayer)
QgsMapLayerRegistry.instance().addMapLayers([self.vlayer])
self.populateLayers()
self.progressBar.setValue(0)
self.buttonOk.setEnabled( True )
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/fTools/tools/ftools_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ def addShapeToCanvas( shapefile_path ):
vlayer_new = QgsVectorLayer( shapefile_path, layer_name, "ogr" )
print layer_name
if vlayer_new.isValid():
QgsMapLayerRegistry.instance().addMapLayer( vlayer_new )
QgsMapLayerRegistry.instance().addMapLayers( [vlayer_new] )
return True
else:
return False
Expand Down
6 changes: 3 additions & 3 deletions python/plugins/osm/OsmLoadDlg.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ def onOK(self):

if self.chkCustomRenderer.isChecked():
self.setCustomRenderer(polygonLayer)
QgsMapLayerRegistry.instance().addMapLayer(polygonLayer)
QgsMapLayerRegistry.instance().addMapLayers([polygonLayer])

# add line layer
lineLayer = QgsVectorLayer(self.fname+"?type=line"+observer + tag + style, basename+" lines", "osm")
Expand All @@ -206,7 +206,7 @@ def onOK(self):

if self.chkCustomRenderer.isChecked():
self.setCustomRenderer(lineLayer)
QgsMapLayerRegistry.instance().addMapLayer(lineLayer)
QgsMapLayerRegistry.instance().addMapLayers([lineLayer])

# add point layer
pointLayer = QgsVectorLayer(self.fname+"?type=point"+observer + tag + style, basename+" points", "osm")
Expand All @@ -220,7 +220,7 @@ def onOK(self):

if self.chkCustomRenderer.isChecked():
self.setCustomRenderer(pointLayer)
QgsMapLayerRegistry.instance().addMapLayer(pointLayer)
QgsMapLayerRegistry.instance().addMapLayers([pointLayer])

# remember layers
self.polygonLayer=polygonLayer
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/algs/ftools/ftools_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ def addShapeToCanvas( shapefile_path ):
vlayer_new = QgsVectorLayer( shapefile_path, layer_name, "ogr" )
print layer_name
if vlayer_new.isValid():
QgsMapLayerRegistry.instance().addMapLayer( vlayer_new )
QgsMapLayerRegistry.instance().addMapLayers( [vlayer_new] )
return True
else:
return False
Expand Down
50 changes: 25 additions & 25 deletions python/plugins/sextante/core/QGisLayers.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ def getRasterLayers():

for layer in layers:
if layer.type() == layer.RasterLayer:
if layer.usesProvider() and layer.providerKey() == 'gdal':#only gdal file-based layers
if layer.providerType() == 'gdal':#only gdal file-based layers
raster.append(layer)
return raster

@staticmethod
def getVectorLayers(shapetype=-1):
layers = QGisLayers.iface.legendInterface().layers()
vector = list()
for layer in layers:
if layer.type() == layer.VectorLayer:
if shapetype == QGisLayers.ALL_TYPES or layer.geometryType() == shapetype:
uri = unicode(layer.source())
for layer in layers:
if layer.type() == layer.VectorLayer:
if shapetype == QGisLayers.ALL_TYPES or layer.geometryType() == shapetype:
uri = unicode(layer.source())
if not uri.endswith("csv") and not uri.endswith("dbf"):

vector.append(layer)
return vector

Expand Down Expand Up @@ -112,7 +112,7 @@ def load(layer, name = None, crs = None, style = None):
else:
style = SextanteConfig.getSetting(SextanteConfig.VECTOR_POLYGON_STYLE)
qgslayer.loadNamedStyle(style)
QgsMapLayerRegistry.instance().addMapLayer(qgslayer)
QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
else:
qgslayer = QgsRasterLayer(layer, name)
if qgslayer.isValid():
Expand All @@ -121,7 +121,7 @@ def load(layer, name = None, crs = None, style = None):
if style == None:
style = SextanteConfig.getSetting(SextanteConfig.RASTER_STYLE)
qgslayer.loadNamedStyle(style)
QgsMapLayerRegistry.instance().addMapLayer(qgslayer)
QgsMapLayerRegistry.instance().addMapLayers([qgslayer])
QGisLayers.iface.legendInterface().refreshLayerSymbology(qgslayer)
else:
if prjSetting:
Expand Down Expand Up @@ -172,51 +172,51 @@ def getObjectFromUri(uri, forceLoad = True):

@staticmethod
def features(layer):
'''this returns an iterator over features in a vector layer, considering the
selection that might exist in the layer, and the SEXTANTE configuration that
'''this returns an iterator over features in a vector layer, considering the
selection that might exist in the layer, and the SEXTANTE configuration that
indicates whether to use only selected feature or all of them.
This should be used by algorithms instead of calling the QGis API directly,
to ensure a consistent behaviour across algorithms'''
return Features(layer)


class Features():
def __init__(self, layer):

def __init__(self, layer):
self.layer = layer
self.selection = False;
self.selection = False;
if SextanteConfig.getSetting(SextanteConfig.USE_SELECTED):
self.selected = layer.selectedFeatures()
if len(self.selected) > 0:
self.selection = True
self.idx = 0;
self.selection = True
self.idx = 0;

def __iter__(self):
return self

def next(self):
if self.selection:
if self.idx < len(self.selected):
if self.idx < len(self.selected):
feature = self.selected[self.idx]
self.idx += 1
return feature
else:
raise StopIteration()
raise StopIteration()
else:
f = QgsFeature()
if self.layer.dataProvider().nextFeature(f):
return f
else:
raise StopIteration()

def __len__(self):
if self.selection:
return int(self.layer.selectedFeatureCount())
else:
return int(self.layer.dataProvider().featureCount())






Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/gdal/OgrAlgorithm.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def ogrConnectionString(self, uri):
return uri;
provider = layer.dataProvider().name()
qDebug("inputLayer provider '%s'" % provider)
#qDebug("inputLayer layer '%s'" % layer.providerKey())
#qDebug("inputLayer layer '%s'" % layer.providerType())
qDebug("inputLayer.source '%s'" % layer.source())
if provider == 'spatialite':
#dbname='/geodata/osm_ch.sqlite' table="places" (Geometry) sql=
Expand Down
2 changes: 1 addition & 1 deletion python/plugins/sextante/gui/SextantePostprocessing.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def handleAlgorithmResults(alg, showResults = True):
try:
if out.value.startswith("memory:"):
layer = out.memoryLayer
QgsMapLayerRegistry.instance().addMapLayer(layer)
QgsMapLayerRegistry.instance().addMapLayers([layer])
else:
if SextanteConfig.getSetting(SextanteConfig.USE_FILENAME_AS_LAYER_NAME):
name = os.path.basename(out.value)
Expand Down