mirror of
				https://github.com/qgis/QGIS.git
				synced 2025-10-31 00:06:02 -04:00 
			
		
		
		
	
		
			
				
	
	
		
			339 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			339 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| # -*- coding: utf-8 -*-
 | |
| 
 | |
| """
 | |
| /***************************************************************************
 | |
| Name                 : DB Manager
 | |
| Description          : Database manager plugin for QGIS
 | |
| Date                 : Oct 13, 2011
 | |
| copyright            : (C) 2011 by Giuseppe Sucameli
 | |
| email                : brush.tyler@gmail.com
 | |
| 
 | |
| The content of this file is based on
 | |
| - PG_Manager by Martin Dobias (GPLv2 license)
 | |
|  ***************************************************************************/
 | |
| 
 | |
| /***************************************************************************
 | |
|  *                                                                         *
 | |
|  *   This program is free software; you can redistribute it and/or modify  *
 | |
|  *   it under the terms of the GNU General Public License as published by  *
 | |
|  *   the Free Software Foundation; either version 2 of the License, or     *
 | |
|  *   (at your option) any later version.                                   *
 | |
|  *                                                                         *
 | |
|  ***************************************************************************/
 | |
| """
 | |
| 
 | |
| from PyQt4.QtCore import Qt, SIGNAL
 | |
| from PyQt4.QtGui import QDialog, QMessageBox, QApplication
 | |
| 
 | |
| from .db_plugins.data_model import TableFieldsModel, TableConstraintsModel, TableIndexesModel
 | |
| from .db_plugins.plugin import BaseError
 | |
| from .dlg_db_error import DlgDbError
 | |
| 
 | |
| from .dlg_field_properties import DlgFieldProperties
 | |
| from .dlg_add_geometry_column import DlgAddGeometryColumn
 | |
| from .dlg_create_constraint import DlgCreateConstraint
 | |
| from .dlg_create_index import DlgCreateIndex
 | |
| 
 | |
| from .ui.ui_DlgTableProperties import Ui_DbManagerDlgTableProperties as Ui_Dialog
 | |
| 
 | |
| 
 | |
| class DlgTableProperties(QDialog, Ui_Dialog):
 | |
|     def __init__(self, table, parent=None):
 | |
|         QDialog.__init__(self, parent)
 | |
|         self.table = table
 | |
|         self.setupUi(self)
 | |
| 
 | |
|         self.db = self.table.database()
 | |
| 
 | |
|         m = TableFieldsModel(self)
 | |
|         self.viewFields.setModel(m)
 | |
| 
 | |
|         m = TableConstraintsModel(self)
 | |
|         self.viewConstraints.setModel(m)
 | |
| 
 | |
|         m = TableIndexesModel(self)
 | |
|         self.viewIndexes.setModel(m)
 | |
| 
 | |
|         self.connect(self.btnAddColumn, SIGNAL("clicked()"), self.addColumn)
 | |
|         self.connect(self.btnAddGeometryColumn, SIGNAL("clicked()"), self.addGeometryColumn)
 | |
|         self.connect(self.btnEditColumn, SIGNAL("clicked()"), self.editColumn)
 | |
|         self.connect(self.btnDeleteColumn, SIGNAL("clicked()"), self.deleteColumn)
 | |
| 
 | |
|         self.connect(self.btnAddConstraint, SIGNAL("clicked()"), self.addConstraint)
 | |
|         self.connect(self.btnDeleteConstraint, SIGNAL("clicked()"), self.deleteConstraint)
 | |
| 
 | |
|         self.connect(self.btnAddIndex, SIGNAL("clicked()"), self.createIndex)
 | |
|         self.connect(self.btnAddSpatialIndex, SIGNAL("clicked()"), self.createSpatialIndex)
 | |
|         self.connect(self.btnDeleteIndex, SIGNAL("clicked()"), self.deleteIndex)
 | |
| 
 | |
|         self.populateViews()
 | |
|         self.checkSupports()
 | |
| 
 | |
| 
 | |
|     def checkSupports(self):
 | |
|         allowEditColumns = self.db.connector.hasTableColumnEditingSupport()
 | |
|         self.btnEditColumn.setEnabled(allowEditColumns)
 | |
|         self.btnDeleteColumn.setEnabled(allowEditColumns)
 | |
| 
 | |
|         allowSpatial = self.db.connector.hasSpatialSupport()
 | |
|         self.btnAddGeometryColumn.setEnabled(allowSpatial)
 | |
|         self.btnAddSpatialIndex.setEnabled(allowSpatial)
 | |
| 
 | |
| 
 | |
|     def populateViews(self):
 | |
|         self.populateFields()
 | |
|         self.populateConstraints()
 | |
|         self.populateIndexes()
 | |
| 
 | |
| 
 | |
|     def populateFields(self):
 | |
|         """ load field information from database """
 | |
| 
 | |
|         m = self.viewFields.model()
 | |
|         m.clear()
 | |
| 
 | |
|         for fld in self.table.fields():
 | |
|             m.append(fld)
 | |
| 
 | |
|         for col in range(4):
 | |
|             self.viewFields.resizeColumnToContents(col)
 | |
| 
 | |
|     def currentColumn(self):
 | |
|         """ returns row index of selected column """
 | |
|         sel = self.viewFields.selectionModel()
 | |
|         indexes = sel.selectedRows()
 | |
|         if len(indexes) == 0:
 | |
|             QMessageBox.information(self, self.tr("DB Manager"), self.tr("nothing selected"))
 | |
|             return -1
 | |
|         return indexes[0].row()
 | |
| 
 | |
|     def addColumn(self):
 | |
|         """ open dialog to set column info and add column to table """
 | |
|         dlg = DlgFieldProperties(self, None, self.table)
 | |
|         if not dlg.exec_():
 | |
|             return
 | |
|         fld = dlg.getField()
 | |
| 
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
|         try:
 | |
|             # add column to table
 | |
|             self.table.addField(fld)
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 | |
| 
 | |
|     def addGeometryColumn(self):
 | |
|         """ open dialog to add geometry column """
 | |
|         dlg = DlgAddGeometryColumn(self, self.table)
 | |
|         if not dlg.exec_():
 | |
|             return
 | |
|         self.populateViews()
 | |
| 
 | |
|     def editColumn(self):
 | |
|         """ open dialog to change column info and alter table appropriately """
 | |
|         index = self.currentColumn()
 | |
|         if index == -1:
 | |
|             return
 | |
| 
 | |
|         m = self.viewFields.model()
 | |
|         # get column in table
 | |
|         # (there can be missing number if someone deleted a column)
 | |
|         fld = m.getObject(index)
 | |
| 
 | |
|         dlg = DlgFieldProperties(self, fld, self.table)
 | |
|         if not dlg.exec_():
 | |
|             return
 | |
|         new_fld = dlg.getField(True)
 | |
| 
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
|         try:
 | |
|             fld.update(new_fld.name, new_fld.type2String(), new_fld.notNull, new_fld.default2String())
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 | |
| 
 | |
|     def deleteColumn(self):
 | |
|         """ delete currently selected column """
 | |
|         index = self.currentColumn()
 | |
|         if index == -1:
 | |
|             return
 | |
| 
 | |
|         m = self.viewFields.model()
 | |
|         fld = m.getObject(index)
 | |
| 
 | |
|         res = QMessageBox.question(self, self.tr("Are you sure"), self.tr("really delete column '%s'?") % fld.name,
 | |
|                                    QMessageBox.Yes | QMessageBox.No)
 | |
|         if res != QMessageBox.Yes:
 | |
|             return
 | |
| 
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
|         try:
 | |
|             fld.delete()
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 | |
| 
 | |
| 
 | |
|     def populateConstraints(self):
 | |
|         constraints = self.table.constraints()
 | |
|         if constraints is None:
 | |
|             self.hideConstraints()  # not supported
 | |
|             return
 | |
| 
 | |
|         m = self.viewConstraints.model()
 | |
|         m.clear()
 | |
| 
 | |
|         for constr in constraints:
 | |
|             m.append(constr)
 | |
| 
 | |
|         for col in range(3):
 | |
|             self.viewConstraints.resizeColumnToContents(col)
 | |
| 
 | |
|     def hideConstraints(self):
 | |
|         index = self.tabs.indexOf(self.tabConstraints)
 | |
|         if index >= 0:
 | |
|             self.tabs.setTabEnabled(index, False)
 | |
| 
 | |
|     def addConstraint(self):
 | |
|         """ add primary key or unique constraint """
 | |
| 
 | |
|         dlg = DlgCreateConstraint(self, self.table)
 | |
|         if not dlg.exec_():
 | |
|             return
 | |
|         self.populateViews()
 | |
| 
 | |
|     def deleteConstraint(self):
 | |
|         """ delete a constraint """
 | |
| 
 | |
|         index = self.currentConstraint()
 | |
|         if index == -1:
 | |
|             return
 | |
| 
 | |
|         m = self.viewConstraints.model()
 | |
|         constr = m.getObject(index)
 | |
| 
 | |
|         res = QMessageBox.question(self, self.tr("Are you sure"),
 | |
|                                    self.tr("really delete constraint '%s'?") % constr.name,
 | |
|                                    QMessageBox.Yes | QMessageBox.No)
 | |
|         if res != QMessageBox.Yes:
 | |
|             return
 | |
| 
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
|         try:
 | |
|             constr.delete()
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 | |
| 
 | |
|     def currentConstraint(self):
 | |
|         """ returns row index of selected index """
 | |
|         sel = self.viewConstraints.selectionModel()
 | |
|         indexes = sel.selectedRows()
 | |
|         if len(indexes) == 0:
 | |
|             QMessageBox.information(self, self.tr("DB Manager"), self.tr("nothing selected"))
 | |
|             return -1
 | |
|         return indexes[0].row()
 | |
| 
 | |
| 
 | |
|     def populateIndexes(self):
 | |
|         indexes = self.table.indexes()
 | |
|         if indexes is None:
 | |
|             self.hideIndexes()
 | |
|             return
 | |
| 
 | |
|         m = self.viewIndexes.model()
 | |
|         m.clear()
 | |
| 
 | |
|         for idx in indexes:
 | |
|             m.append(idx)
 | |
| 
 | |
|         for col in range(2):
 | |
|             self.viewIndexes.resizeColumnToContents(col)
 | |
| 
 | |
|     def hideIndexes(self):
 | |
|         index = self.tabs.indexOf(self.tabIndexes)
 | |
|         if index >= 0:
 | |
|             self.tabs.setTabEnabled(index, False)
 | |
| 
 | |
|     def createIndex(self):
 | |
|         """ create an index """
 | |
|         dlg = DlgCreateIndex(self, self.table)
 | |
|         if not dlg.exec_():
 | |
|             return
 | |
|         self.populateViews()
 | |
| 
 | |
|     def createSpatialIndex(self):
 | |
|         """ create spatial index for the geometry column """
 | |
|         if self.table.type != self.table.VectorType:
 | |
|             QMessageBox.information(self, self.tr("DB Manager"), self.tr("The selected table has no geometry"))
 | |
|             return
 | |
| 
 | |
|         res = QMessageBox.question(self, self.tr("Create?"),
 | |
|                                    self.tr("Create spatial index for field %s?") % self.table.geomColumn,
 | |
|                                    QMessageBox.Yes | QMessageBox.No)
 | |
|         if res != QMessageBox.Yes:
 | |
|             return
 | |
| 
 | |
|         # TODO: first check whether the index doesn't exist already
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
| 
 | |
|         try:
 | |
|             self.table.createSpatialIndex()
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 | |
| 
 | |
|     def currentIndex(self):
 | |
|         """ returns row index of selected index """
 | |
|         sel = self.viewIndexes.selectionModel()
 | |
|         indexes = sel.selectedRows()
 | |
|         if len(indexes) == 0:
 | |
|             QMessageBox.information(self, self.tr("DB Manager"), self.tr("Nothing selected"))
 | |
|             return -1
 | |
|         return indexes[0].row()
 | |
| 
 | |
|     def deleteIndex(self):
 | |
|         """ delete currently selected index """
 | |
|         index = self.currentIndex()
 | |
|         if index == -1:
 | |
|             return
 | |
| 
 | |
|         m = self.viewIndexes.model()
 | |
|         idx = m.getObject(index)
 | |
| 
 | |
|         res = QMessageBox.question(self, self.tr("Are you sure"), self.tr("really delete index '%s'?") % idx.name,
 | |
|                                    QMessageBox.Yes | QMessageBox.No)
 | |
|         if res != QMessageBox.Yes:
 | |
|             return
 | |
| 
 | |
|         QApplication.setOverrideCursor(Qt.WaitCursor)
 | |
|         self.emit(SIGNAL("aboutToChangeTable()"))
 | |
|         try:
 | |
|             idx.delete()
 | |
|             self.populateViews()
 | |
|         except BaseError, e:
 | |
|             DlgDbError.showError(e, self)
 | |
|             return
 | |
|         finally:
 | |
|             QApplication.restoreOverrideCursor()
 |