标签:
# -*- coding: utf-8 -*-
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys
import os.path
try:
import qgis.gui
import qgis.core
except ImportError, e:
print "no qgis"
from DlgCreateTable import DlgCreateTable
from DlgLoadData import DlgLoadData
from DlgDumpData import DlgDumpData
from DlgAbout import DlgAbout
from DlgSqlWindow import DlgSqlWindow
from DlgTableProperties import DlgTableProperties
from DatabaseModel import TableItem, DBItem, DatabaseModel
from DbTableModel import DbTableModel
from DlgDbError import DlgDbError
from WizardImport import WizardImport
from DlgGeomProcessing import DlgGeomProcessing
from MetadataBrowser import MetadataBrowser
from DlgVersioning import DlgVersioning
import resources
import spatialite_utils
class ManagerWindow(QMainWindow):
ViewDbInfo, ViewDB, ViewTable = range(3)
ViewNothing = -1
debug_index = 0
def __init__(self, use_qgis=False, parent=None):
QMainWindow.__init__(self, parent)
self.useQgis = use_qgis
self.currentLayerId = None
self.db = None
self.setupUi()
self.enableGui(False)
settings = QSettings()
self.restoreGeometry(settings.value("/SpatiaLite_Manager/geometry").toByteArray())
self.restoreState(settings.value("/SpatiaLite_Manager/windowState").toByteArray())
self.dbModel = DatabaseModel(self)
self.dbModel.setReadOnlyMode(True)
self.tree.setModel(self.dbModel)
self.currentItem = (None, None)
self.currentView = ManagerWindow.ViewNothing
self.currentHasGeometry = False
self.tableModel = None
# setup signal-slot connections
self.connect(self.tree.selectionModel(), SIGNAL("currentChanged(const QModelIndex&, const QModelIndex&)"), self.itemChanged)
self.connect(self.tree, SIGNAL("doubleClicked(const QModelIndex&)"), self.notImplemented) #self.editTable)
self.connect(self.tree.model(), SIGNAL("dataChanged(const QModelIndex &, const QModelIndex &)"), self.refreshTable)
# text metadata
self.connect(self.txtMetadata, SIGNAL("anchorClicked(const QUrl&)"), self.metadataLinkClicked)
self.connect(self.tableFilterCheck, SIGNAL("toggled(bool)"), self.tableFilterChanged)
self.connect(self.tabs, SIGNAL("currentChanged(int)"), self.tabChanged)
# connect to database selected last time
# but first let the manager chance to show the window
QTimer.singleShot(50, self.dbConnectInit)
self.dirtyMetadata=False
self.dirtyTable=False
self.dirtyMap=False
def notImplemented(self):
QMessageBox.warning(self, "Not Implemented", "This feature is not implemented yet.")
def closeEvent(self, e):
""" save window state """
settings = QSettings()
settings.setValue("/SpatiaLite_Manager/windowState", QVariant(self.saveState()))
settings.setValue("/SpatiaLite_Manager/geometry", QVariant(self.saveGeometry()))
QMainWindow.closeEvent(self, e)
def listDatabases(self):
actionsDb = {}
settings = QSettings()
settings.beginGroup("/SpatiaLite/connections")
keys = settings.childGroups()
for key in keys:
actionsDb[unicode(key)] = QAction(key, self)
settings.endGroup()
return actionsDb
def dbConnectSlot(self):
sel = unicode(self.sender().text())
#print "connect", sel.encode(‘utf-8‘)
self.dbConnect(sel)
def dbConnectInit(self):
if len(self.actionsDb) == 0:
QMessageBox.information(self, "No connections", "You apparently haven‘t defined any database connections yet.\nYou can do so in Quantum GIS by opening Add SpatiaLite layer dialog.\n\nWithout database connections you won‘t be able to use this plugin.")
return
settings = QSettings()
selected = QString(settings.value("/SpatiaLite/connections/selected").toString())
self.dbConnect( unicode(selected) )
def dbConnect(self, selected):
settings = QSettings()
# if there‘s open database already, get rid of it
if self.db:
self.dbDisconnect()
# get connection details from QSettings
settings.beginGroup( u"/SpatiaLite/connections/" + selected )
if not settings.contains("sqlitepath"): # non-existent entry?
QMessageBox.critical(self, "Error", "Unable to connect: there is no defined database connection \"%s\"." % selected)
return
dbpath = unicode(settings.value("sqlitepath").toString())
settings.endGroup()
self.statusBar.showMessage("Connecting to database (%s) ..." % selected)
QApplication.processEvents() # give the user chance to see the message :)
# connect to DB
try:
self.db = spatialite_utils.GeoDB(dbname=dbpath)
except spatialite_utils.DbError, e:
self.statusBar.clearMessage()
QMessageBox.critical(self, "error", "Couldn‘t connect to database:\n"+e.msg)
return
self.txtMetadata.setDatabase(self.db)
# set as default in QSettings
settings.setValue("/SpatiaLite/connections/selected", QVariant(selected))
# set action as checked
if self.actionsDb.has_key(selected):
self.actionsDb[selected].setChecked(True)
self.actionDbDisconnect.setEnabled(True)
self.statusBar.showMessage("Querying database structure ...")
self.enableGui(True)
self.refreshTable()
self.updateWindowTitle()
self.tree.resizeColumnToContents(0)
self.dbInfo()
self.statusBar.clearMessage()
def dbDisconnect(self):
# uncheck previously selected DB
for a in self.actionsDb.itervalues():
if a.isChecked():
a.setChecked(False)
self.db = None
self.txtMetadata.setDatabase(None)
self.refreshTable()
self.actionDbDisconnect.setEnabled(False)
self.enableGui(False)
self.currentView = ManagerWindow.ViewNothing
self.updateView()
self.updateWindowTitle()
def updateWindowTitle(self):
if not hasattr(self, ‘defaultTitle‘):
self.defaultTitle = self.windowTitle()
if self.db:
self.setWindowTitle(self.defaultTitle + " - %s" % (self.db.dbname) )
else:
self.setWindowTitle(self.defaultTitle)
def tabChanged(self, tabIndex):
""" another tab has been selected: update its contents """
self.tabs.setTabEnabled(1, self.currentView == ManagerWindow.ViewTable)
if self.useQgis:
self.tabs.setTabEnabled(2, self.currentView == ManagerWindow.ViewTable and self.currentHasGeometry)
if tabIndex == 0 and self.dirtyMetadata:
# update the metadata
if self.currentView == ManagerWindow.ViewTable:
self.txtMetadata.showTableInfo(self.currentDatabaseItem())
elif self.currentView == ManagerWindow.ViewDB:
self.txtMetadata.showDbInfo(self.currentDatabaseItem())
elif self.currentView == ManagerWindow.ViewDbInfo:
self.txtMetadata.showDbInfo()
else:
self.txtMetadata.setHtml(‘‘)
self.dirtyMetadata = False
elif tabIndex == 1 and self.dirtyTable:
# update the table
if self.currentView == ManagerWindow.ViewTable:
self.loadDbTable(self.currentDatabaseItem())
else:
self.unloadDbTable()
elif tabIndex == 2 and self.dirtyMap:
# update the map canvas
if self.currentView == ManagerWindow.ViewTable and self.currentHasGeometry and self.useQgis:
self.loadMapPreview(self.currentDatabaseItem())
else:
self.clearMapPreview()
def tableFilterChanged(self):
self.loadDbTable(self.currentDatabaseItem(), True)
def dbInfo(self):
""" retrieve information about current server / database """
self.tree.selectionModel().clear()
self.currentItem = (None, None)
self.currentView = ManagerWindow.ViewDbInfo
self.updateView()
def showOnlyReadableTables(self):
model = self.tree.model()
model.showOnlyReadableTables(self.actionOnlyReadable.isChecked())
self.refreshTable()
def refreshTable(self):
model = self.tree.model()
model.loadFromDb(self.db)
model.reset()
# only expand when there are not too many tables
if model.tree.tableCount < 20:
self.tree.expandAll()
self.currentItem = (None, None)
self.currentView = ManagerWindow.ViewNothing
def itemChanged(self, index, indexOld):
""" update information - current database item has been changed """
item = index.internalPointer()
if isinstance(item, DBItem):
if self.currentItem == (item.name, None):
return
self.currentItem = (item.name, None)
self.currentView = ManagerWindow.ViewDB
#self.loadSchemaMetadata(item)
#self.unloadDbTable()
elif isinstance(item, TableItem):
if self.currentItem == (item.db().name, item.name):
return
self.currentItem = (item.db().name, item.name)
self.currentView = ManagerWindow.ViewTable
self.currentHasGeometry = (item.geom_type is not None)
#self.loadTableMetadata(item)
else:
self.currentItem = (None, None)
self.currentView = ManagerWindow.ViewNothing
self.updateView()
def updateView(self):
""" set all views dirty and trigger refresh of the current one """
self.dirtyMetadata = True
self.dirtyTable = True
self.dirtyMap = True
self.tabChanged( self.tabs.currentIndex() )
def updateMetadata(self):
self.dirtyMetadata = True
self.tabChanged( self.tabs.currentIndex() )
def updateTable(self):
self.dirtyTable = True
self.tabChanged( self.tabs.currentIndex() )
def metadataLinkClicked(self, url):
print unicode(url.path()).encode(‘utf-8‘)
action = unicode(url.path())
if action == ‘triggers/enable‘ or action == ‘triggers/disable‘:
enable = (action == ‘triggers/enable‘)
item = self.currentDatabaseItem()
msg = "Do you want to %s all triggers?" % ("enable" if enable else "disable")
if QMessageBox.question(self, "Table triggers", msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes:
try:
self.unloadDbTable() # table has to be unloaded, otherwise blocks the trigger enable/disable
self.db.table_enable_triggers(item.name, item.db().name, enable)
self.loadDbTable(item)
self.updateMetadata()
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
elif action[0:8] == ‘trigger/‘:
item = self.currentDatabaseItem()
parts = action.split(‘/‘)
trigger_name = parts[1]
trigger_action = parts[2]
if trigger_action == ‘enable‘ or trigger_action == ‘disable‘:
enable = (trigger_action == ‘enable‘)
msg = "Do you want to %s trigger %s?" % ("enable" if enable else "disable", trigger_name)
if QMessageBox.question(self, "Table trigger", msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes:
try:
self.unloadDbTable() # table has to be unloaded, otherwise blocks the trigger enable/disable
self.db.table_enable_trigger(item.name, item.db().name, trigger_name, enable)
self.loadDbTable(item)
self.updateMetadata()
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
elif trigger_action == ‘delete‘:
msg = "Do you want to delete trigger %s?" % trigger_name
if QMessageBox.question(self, "Table trigger", msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes:
try:
self.unloadDbTable() # table has to be unloaded, otherwise blocks the trigger
self.db.table_delete_trigger(item.name, item.db().name, trigger_name)
self.loadDbTable(item)
self.updateMetadata()
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
elif action[0:5] == ‘rule/‘:
item = self.currentDatabaseItem()
parts = action.split(‘/‘)
rule_name = parts[1]
rule_action = parts[2]
if rule_action == ‘delete‘:
msg = "Do you want to delete rule %s?" % rule_name
if QMessageBox.question(self, "Table rule", msg, QMessageBox.Yes|QMessageBox.No) == QMessageBox.Yes:
try:
self.unloadDbTable() # table has to be unloaded
self.db.table_delete_rule(item.name, item.db().name, rule_name)
self.loadDbTable(item)
self.updateMetadata()
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
elif action == ‘rows‘:
try:
item = self.currentDatabaseItem()
item.row_count_real = self.db.get_table_rows(item.name, item.db().name)
self.updateMetadata()
except spatialite_utils.DbError, e:
QMessageBox.information(self, "sorry", "Unable to calculate number of rows")
def unloadDbTable(self):
self.table.setModel(None)
self.tableModel = None
self.dirtyTable = False
def loadDbTable(self, item, reloadData = False):
# the same table?
if self.table.model() and self.table.model().table == item.name and self.table.model().schema == item.db().name:
if not reloadData:
return
# if the real row count is not calculated yet, find out now!
if item.row_count_real == -1:
try:
item.row_count_real = self.db.get_table_rows(item.name)
self.updateMetadata()
except spatialite_utils.DbError, e:
self.unloadDbTable() # unable to load the table!
return
# if the checkbox is checked get only the first 1000 results
rows = item.row_count_real
if self.tableFilterCheck.isChecked():
rows = min(item.row_count_real, 1000)
newModel = DbTableModel(self.db, item.db().name, item.name, rows)
self.table.setModel(newModel)
del self.tableModel # ensure that old model gets deleted
self.tableModel = newModel
self.dirtyTable = False
def loadMapPreview(self, item):
""" if has geometry column load to map canvas """
if item and item.geom_type:
uri = qgis.core.QgsDataSourceURI()
uri.setDatabase(self.db.dbname)
uri.setDataSource(item.db().name, item.name, item.geom_column)
vl = qgis.core.QgsVectorLayer(uri.uri(), item.name, "spatialite")
if not vl.isValid():
newLayerId = None
self.preview.setLayerSet( [] )
else:
newLayerId = vl.getLayerID()
qgis.core.QgsMapLayerRegistry.instance().addMapLayer(vl, False)
self.preview.setLayerSet( [ qgis.gui.QgsMapCanvasLayer(vl, True, False) ] )
self.preview.zoomToFullExtent()
else:
newLayerId = None
self.preview.setLayerSet( [] )
# remove old layer (if any) and set new
if self.currentLayerId:
qgis.core.QgsMapLayerRegistry.instance().removeMapLayer(self.currentLayerId, False)
self.currentLayerId = newLayerId
self.dirtyMap = False
def clearMapPreview(self):
""" remove any layers from preview canvas """
self.preview.setLayerSet( [] )
self.dirtyMap = False
def createTable(self):
dlg = DlgCreateTable(self, self.db)
self.connect(dlg, SIGNAL("databaseChanged()"), self.refreshTable)
dlg.exec_()
def editTable(self):
ptr = self.currentDatabaseItem()
if not ptr:
return
if not isinstance(ptr, TableItem) or ptr.is_view:
QMessageBox.information(self, "sorry", "select a TABLE for editation")
return
dlg = DlgTableProperties(self.db, ptr.db().name, ptr.name)
self.connect(dlg, SIGNAL("aboutToChangeTable()"), self.aboutToChangeTable)
dlg.exec_()
# update info
self.updateMetadata()
self.updateTable()
def aboutToChangeTable(self):
""" table is going to be changed, we must close currently opened cursor """
self.unloadDbTable()
def currentDatabaseItem(self):
""" returns reference to item currently selected or displays an error """
sel = self.tree.selectionModel()
index = sel.currentIndex()
if not index.isValid():
QMessageBox.information(self, "sorry", "nothing selected")
return None
return index.internalPointer()
def emptyTable(self):
""" deletes all items from current table """
ptr = self.currentDatabaseItem()
if not ptr:
return
if not isinstance(ptr, TableItem) or ptr.is_view:
QMessageBox.information(self, "sorry", "select a TABLE to empty it")
return
res = QMessageBox.question(self, "hey!", "really delete all items from table %s ?" % ptr.name, QMessageBox.Yes | QMessageBox.No)
if res != QMessageBox.Yes:
return
try:
self.db.empty_table(ptr.name, ptr.db().name)
self.updateMetadata()
self.updateTable()
QMessageBox.information(self, "good", "table has been emptied.")
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
def deleteTable(self):
""" deletes current table from database """
ptr = self.currentDatabaseItem()
if not ptr:
return
if not isinstance(ptr, TableItem):
QMessageBox.information(self, "sorry", "select a TABLE or VIEW for deletion")
return
res = QMessageBox.question(self, "hey!", "really delete table/view %s ?" % ptr.name, QMessageBox.Yes | QMessageBox.No)
if res != QMessageBox.Yes:
return
# necessary to close cursor, otherwise deletion fails
self.unloadDbTable()
self.dbInfo()
try:
if ptr.is_view:
self.db.delete_view(ptr.name)
else:
if ptr.geom_column:
self.db.delete_geometry_table(ptr.name)
else:
self.db.delete_table(ptr.name)
self.refreshTable()
QMessageBox.information(self, "good", "table/view deleted.")
except spatialite_utils.DbError, e:
DlgDbError.showError(e, self)
def loadData(self):
dlg = DlgLoadData(self, self.db)
self.connect(dlg, SIGNAL("dbChanged()"), self.refreshTable)
dlg.exec_()
def dumpData(self):
dlg = DlgDumpData(self, self.db)
dlg.exec_()
def importData(self):
wizard = WizardImport(self, self.db)
if not wizard.exec_():
return
self.refreshTable()
def geomProcessing(self):
dlg = DlgGeomProcessing(self, self.db)
if not dlg.exec_():
return
self.refreshTable()
def exportData(self):
QMessageBox.information(self, "sorry", "wizard not implemented yet.")
def vacuumAnalyze(self):
""" run VACUUM ANALYZE on this table """
self.db.vacuum()
self.refreshTable() # table‘s metadata has been changed, fetch everything again
# update info
self.updateMetadata()
self.dbInfo()
def tableVersioning(self):
dlg = DlgVersioning(self, self.db)
if not dlg.exec_():
return
self.refreshTable()
def about(self):
""" show about box """
dlg = DlgAbout(self)
dlg.exec_()
def help(self):
""" open help in a browser """
docFile = os.path.join(os.path.dirname(__file__), "doc","index.html")
QDesktopServices.openUrl( QUrl("file:" + docFile) )
def sqlWindow(self):
""" show sql window """
dlg = DlgSqlWindow(self, self.db)
dlg.exec_()
def enableGui(self, connected):
""" enable / disable various actions depending whether we‘re connected or not """
for a in self.dbActions:
a.setEnabled(connected)
def setupUi(self):
self.setWindowTitle("SpatiaLite Manager")
self.setWindowIcon(QIcon(":/icons/spatialite_icon.png"))
self.resize(QSize(700,500).expandedTo(self.minimumSizeHint()))
self.txtMetadata = MetadataBrowser()
self.txtMetadata.setOpenLinks(False)
self.table = QTableView()
self.table.setSelectionBehavior(QAbstractItemView.SelectRows)
self.tableFilterCheck = QCheckBox("Shows only the first 1000 results")
self.tableFilterCheck.setChecked(True)
vTableLayout = QVBoxLayout()
vTableLayout.addWidget(self.table)
vTableLayout.addWidget(self.tableFilterCheck)
tableViewer = QWidget(self)
tableViewer.setLayout(vTableLayout)
if self.useQgis:
self.preview = qgis.gui.QgsMapCanvas(self)
self.preview.setCanvasColor(QColor(255,255,255))
# reuse settings from QGIS
settings = QSettings()
self.preview.enableAntiAliasing( settings.value( "/qgis/enable_anti_aliasing", QVariant(False) ).toBool() )
self.preview.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.preview.setWheelAction( qgis.gui.QgsMapCanvas.WheelAction(action), zoomFactor )
self.tabs = QTabWidget()
self.tabs.addTab(self.txtMetadata, "Info")
self.tabs.addTab(tableViewer, "Table")
if self.useQgis:
self.tabs.addTab(self.preview, "Preview")
self.setCentralWidget(self.tabs)
self.tree = QTreeView()
#self.tree.setRootIsDecorated(False)
self.tree.setEditTriggers( QAbstractItemView.SelectedClicked | QAbstractItemView.EditKeyPressed )
self.dock = QDockWidget("Database view", self)
self.dock.setObjectName("DbView")
self.dock.setFeatures(QDockWidget.DockWidgetMovable)
self.dock.setWidget(self.tree)
self.statusBar = QStatusBar(self)
self.setStatusBar(self.statusBar)
self.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
self.createMenu()
def createMenu(self):
self.menuDb = QMenu("&Database", self)
self.menuSchema = QMenu("&Schema", self)
self.menuTable = QMenu("&Table", self)
self.menuData = QMenu("D&ata", self)
self.menuHelp = QMenu("&Help", self)
## MENU Database
self.actionsDb = self.listDatabases()
for k,a in self.actionsDb.iteritems():
self.menuDb.addAction(a)
a.setCheckable(True)
self.connect(a, SIGNAL("triggered(bool)"), self.dbConnectSlot)
self.menuDb.addSeparator()
actionRefresh = self.menuDb.addAction(QIcon(":/icons/toolbar/action_refresh.png"), "&Refresh", self.refreshTable, QKeySequence("F5"))
actionDbInfo = self.menuDb.addAction("Show &info", self.dbInfo)
actionSqlWindow = self.menuDb.addAction(QIcon(":/icons/toolbar/action_sql_window.png"), "&SQL window", self.sqlWindow, QKeySequence("F2"))
actionVacuumAnalyze = self.menuDb.addAction("Run VACUUM", self.vacuumAnalyze)
self.menuDb.addSeparator()
self.actionDbDisconnect = self.menuDb.addAction("&Disconnect", self.dbDisconnect)
self.actionDbDisconnect.setEnabled(False)
## MENU Schema
#actionCreateSchema = self.menuSchema.addAction("&Create schema", self.createSchema)
#actionDeleteSchema = self.menuSchema.addAction("&Delete (empty) schema", self.deleteSchema)
## MENU Table
#actionCreateTable = self.menuTable.addAction(QIcon(":/icons/toolbar/action_new_table.png"), "Create &table", self.createTable)
#self.menuTable.addSeparator()
#actionEditTable = self.menuTable.addAction(QIcon(":/icons/toolbar/action_edit_table.png"),"&Edit table", self.editTable)
#actionVacuumAnalyze = self.menuTable.addAction("Run VACUUM &ANALYZE", self.vacuumAnalyze)
#self.menuMoveToSchema = self.menuTable.addMenu("Move to &schema")
#self.connect(self.menuMoveToSchema, SIGNAL("aboutToShow()"), self.prepareMenuMoveToSchema)
#self.menuTable.addSeparator()
#actionEmptyTable = self.menuTable.addAction("E&mpty table", self.emptyTable)
actionDeleteTable = self.menuTable.addAction(QIcon(":/icons/toolbar/action_del_table.png"),"&Delete table/view", self.deleteTable)
#self.menuTable.addSeparator()
## MENU Data
#actionLoadData = self.menuData.addAction("&Load data from shapefile", self.loadData)
#actionDumpData = self.menuData.addAction("&Dump data to shapefile", self.dumpData)
actionImportData = self.menuData.addAction(QIcon(":/icons/toolbar/action_import.png"), "&Import data", self.importData)
#actionExportData = self.menuData.addAction(QIcon(":/icons/toolbar/action_export.png"), "&Export data", self.exportData)
#self.menuData.addSeparator()
#actionGeomProcessing = self.menuData.addAction("&Geometry processing...", self.geomProcessing)
#actionVersioning = self.menuData.addAction("Table &versioning...", self.tableVersioning)
## MENU About
self.menuHelp.addAction(QIcon(":/icons/about.png"), "&About", self.about)
self.menuHelp.addAction("&Help", self.help, QKeySequence("F1"))
## menu bar
self.menuBar = QMenuBar(self)
self.menuBar.addMenu(self.menuDb)
#self.menuBar.addMenu(self.menuSchema)
self.menuBar.addMenu(self.menuTable)
self.menuBar.addMenu(self.menuData)
self.menuBar.addMenu(self.menuHelp)
self.setMenuBar(self.menuBar)
# toolbar
self.toolBar = QToolBar(self)
self.toolBar.setObjectName("SpatiaLite_Manager_ToolBar")
self.toolBar.setToolButtonStyle(Qt.ToolButtonTextUnderIcon)
self.toolBar.addAction(actionRefresh)
self.toolBar.addAction(actionSqlWindow)
self.toolBar.addSeparator()
#self.toolBar.addAction(actionCreateTable)
#self.toolBar.addAction(actionEditTable)
self.toolBar.addAction(actionDeleteTable)
self.toolBar.addSeparator()
self.toolBar.addAction(actionImportData)
#self.toolBar.addAction(actionExportData)
self.addToolBar(self.toolBar)
# database actions - enabled only when we‘re not connected
# (menu "move to schema" actually isn‘t an action... we‘re abusing python‘s duck typing :-)
self.dbActions = [ actionDbInfo, actionRefresh, actionSqlWindow, #actionCreateSchema, actionDeleteSchema,
actionDeleteTable, actionVacuumAnalyze, #actionCreateTable, actionEditTable, actionEmptyTable,
actionImportData, #actionLoadData, actionDumpData, actionExportData, actionGeomProcessing, actionVersioning,
#self.menuMoveToSchema
]
标签:
原文地址:http://www.cnblogs.com/mhxy13867806343/p/3860917.html