Source code for lib_openmolar.admin.qt4.classes.database_table

#! /usr/bin/env python
# -*- coding: utf-8 -*-

###############################################################################
##                                                                           ##
##  Copyright 2010, Neil Wallace <rowinggolfer@googlemail.com>               ##
##                                                                           ##
##  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 3 of the License, or        ##
##  (at your option) any later version.                                      ##
##                                                                           ##
##  This program is distributed in the hope that it will be useful,          ##
##  but WITHOUT ANY WARRANTY; without even the implied warranty of           ##
##  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            ##
##  GNU General Public License for more details.                             ##
##                                                                           ##
##  You should have received a copy of the GNU General Public License        ##
##  along with this program.  If not, see <http://www.gnu.org/licenses/>.    ##
##                                                                           ##
###############################################################################

from xml.dom import minidom
import re
from PyQt4 import QtCore, QtGui, QtSql


from lib_openmolar.admin.qt4.classes import MyModel, MyRelationalModel
from lib_openmolar.admin.qt4.dialogs.new_db_row_dialog import NewRowDialog


[docs]class DatabaseTableViewer(QtGui.QWidget): connection = None name = _("Table Viewer")
[docs] def __init__(self, parent=None): QtGui.QWidget.__init__(self, parent) self.table_list = QtGui.QListWidget(self) tool_bar = QtGui.QToolBar() icon = QtGui.QIcon.fromTheme("document-open") action_import = QtGui.QAction(icon, "import from xml", self) action_import.setToolTip( "import data into the current table from an xml file") icon = QtGui.QIcon.fromTheme("document-save") action_export = QtGui.QAction(icon, "export to xml", self) action_export.setToolTip( "export data from the current table to an xml file") action_new_row = QtGui.QAction("New Row", self) action_new_row.setToolTip( "add a row of data to the current table") tool_bar.addAction(action_new_row) tool_bar.addSeparator() tool_bar.addAction(action_import) tool_bar.addAction(action_export) self.table_view = QtGui.QTableView(self) #h_header = self.table_view.horizontalHeader() #h_header.setStretchLastSection(True) left_frame = QtGui.QFrame(self) layout = QtGui.QVBoxLayout(left_frame) layout.setMargin(0) layout.addWidget(self.table_list) layout.addWidget(tool_bar) splitter = QtGui.QSplitter(self) splitter.addWidget(left_frame) splitter.addWidget(self.table_view) layout = QtGui.QVBoxLayout(self) layout.addWidget(splitter) splitter.setSizes([150,400]) self.table_list.itemSelectionChanged.connect(self.load_data) action_new_row.triggered.connect(self.new_row) action_import.triggered.connect(self.import_data) action_export.triggered.connect(self.export_data)
[docs] def set_connection(self, connection): self.connection = connection self.load_table_choice() self.setModel()
[docs] def setModel(self): self.model = MyModel(self, self.connection)
[docs] def load_table_choice(self): self.table_list.clear() if not self.connection: return tables = self.connection.get_available_tables() tables.sort() if tables: self.table_list.addItems(tables) self.table_list.setCurrentRow(-1) else: self.parent().parent().emit(QtCore.SIGNAL("Query Success"), _("No Tables"))
[docs] def advise(self, message): QtGui.QMessageBox.warning(self, _("error"), message)
[docs] def new_row(self, args): listwidget_item = self.table_list.currentItem() if not listwidget_item.isSelected(): self.advise("no table chosen") return dl = NewRowDialog(self.model) if dl.exec_(): record = dl.record if self.model.insertRecord(-1, record): self.advise(_("Successful insert")) else: self.advise(u"%s<hr /><pre>%s</pre>"% (_("error"), self.model.lastError().text())) self.model.revert()
[docs] def export_data(self, args): listwidget_item = self.table_list.currentItem() if not listwidget_item.isSelected(): self.advise("no table chosen") return try: filepath = QtGui.QFileDialog.getSaveFileName(None, _("save xml"),"%s.xml"% self.model.tableName(), _("text files ")+"(*.xml)") if filepath != '': if not re.match(".*\.xml$", filepath): filepath += ".xml" f = open(filepath, "w") f.write(self.model.table_xml()) f.close() except Exception, e: self.advise(_("File not saved")+" - %s"% e)
[docs] def import_data(self, args): ''' import from xml ''' listwidget_item = self.table_list.currentItem() if not listwidget_item.isSelected(): self.advise("no table chosen") return filename = QtGui.QFileDialog.getOpenFileName(self, _("load an xml file"),"%s.xml"% self.model.tableName(), _("xml files")+" (*xml)") if filename != '': try: dom = minidom.parse(str(filename)) if dom.getElementsByTagName("ix") != []: new_keys = QtGui.QMessageBox.question(self, _("option"), u"%s<hr />%s"% ( _("would you like to try and preserve existing keys for this table"), _("click 'no' to generate new serial keys")), QtGui.QMessageBox.Yes|QtGui.QMessageBox.No, QtGui.QMessageBox.No) == QtGui.QMessageBox.No self.model.load_table_xml(dom, new_keys) self.load_data() except IOError, e:#Exception, e: self.advise(_("error parsing template file")+" - %s"% e)
[docs] def load_data(self): listwidget_item = self.table_list.currentItem() if not listwidget_item.isSelected(): return table = listwidget_item.text() app = QtGui.QApplication.instance() try: self.model.reset() app.setOverrideCursor(QtCore.Qt.WaitCursor) self.model.setTable(table) self.model.select() self.table_view.setModel(self.model) except Exception as e: print e finally: app.restoreOverrideCursor() error = self.model.lastError() if error.isValid(): self.emit(QtCore.SIGNAL("Query Error"), error.text()) else: self.emit(QtCore.SIGNAL("Query Success"), u"%s '%s'"%(_("loaded table"),table))
[docs]class RelationalDatabaseTableViewer(DatabaseTableViewer): ''' a custom class consisting of a list widget and a table view connected to a RelationalDatabase Model '''
[docs] def __init__(self, parent=None): DatabaseTableViewer.__init__(self, parent)
[docs] def setModel(self): ''' a re-implemented method ''' self.model = MyRelationalModel(self, self.connection)
def _test(): from lib_openmolar.admin.connect import DemoAdminConnection def show_error(error): QtGui.QMessageBox.warning(mw, "error", error) app = QtGui.QApplication([]) ac = DemoAdminConnection() ac.connect() mw = QtGui.QMainWindow() mw.setMinimumSize(400,400) label1 = QtGui.QLabel("table viewer") widg1 = DatabaseTableViewer(mw) widg1.set_connection(ac) widg1.load_table_choice() label2 = QtGui.QLabel("relational table viewer") widg2 = RelationalDatabaseTableViewer(mw) widg2.set_connection(ac) widg2.load_table_choice() frame = QtGui.QFrame() layout = QtGui.QVBoxLayout(frame) layout.addWidget(label1) layout.addWidget(widg1) layout.addWidget(label2) layout.addWidget(widg2) mw.setCentralWidget(frame) mw.connect(widg1, QtCore.SIGNAL("Query Error"), show_error) mw.connect(widg2, QtCore.SIGNAL("Query Error"), show_error) mw.show() app.exec_() if __name__ == "__main__": import gettext gettext.install("") _test()