From 15eb870fb4be0063036ffd33cb21ce06473efb0e Mon Sep 17 00:00:00 2001 From: Stas Shtin Date: Fri, 9 Apr 2010 01:26:10 +0400 Subject: [PATCH] Halfway rewriting to use QT MVC --- src/ipypbx/controllers.py | 45 ++++++++++---- src/ipypbx/main.py | 107 ++++++++++++++++++++++++-------- src/ipypbx/sql.py | 19 ++++++ src/ipypbx/state.py | 2 +- src/ipypbx/ui.py | 151 ++++++++++++++++++++++++++------------------- 5 files changed, 223 insertions(+), 101 deletions(-) create mode 100644 src/ipypbx/sql.py diff --git a/src/ipypbx/controllers.py b/src/ipypbx/controllers.py index b0a3fb2..2bb3169 100644 --- a/src/ipypbx/controllers.py +++ b/src/ipypbx/controllers.py @@ -15,7 +15,8 @@ # You should have received a copy of the GNU General Public License # along with IPyPBX. If not, see . -from ipypbx import models, state +#from ipypbx import models +from PyQt4 import QtCore class BaseHandler(object): @@ -35,22 +36,40 @@ class BaseHandler(object): return NotImplemented -class ConnectionsHandler(BaseHandler): +class ConnectionController(QtCore.QObject): """ Connections handler. """ - def initState(self): - self.connections = list(state.store.query(models.Connection)) - self.currentConnection = None - - for connection in self.connections: - self.parent.ui.connectionList.addItem(connection.name) +# def initState(self): +# self.connections = [] +# #self.connections = list(state.store.query(models.Connection)) +# self.currentConnection = None + +# for connection in self.connections: +# self.parent.ui.connectionList.addItem(connection.name) + +# if self.connections: +# print self.parent.ui.connectionList.currentRow() +# self.parent.ui.connectionList.setCurrentRow(0) +# QtCore.QObject.emit( +# self.parent.ui.connectionList, QtCore.SIGNAL('currentRowChanged(int)'), 0) - def select(self, index): + def select(self, row): """ Select another connection as current. """ - self.currentConnection = state.connections[index] + self.currentConnection = self.connections[row] + + # Fill in form based on selection. + self.parent.ui.connectionName.setText(self.currentConnection.name) + self.parent.ui.connectionLocalIpAddress.setText( + self.currentConnection.local_ip_address) + self.parent.ui.connectionLocalPort.setText( + unicode(self.currentConnection.local_port)) + self.parent.ui.connectionFreeswitchIpAddress.setText( + self.currentConnection.freeswitch_ip_address) + self.parent.ui.connectionFreeswitchPort.setText( + unicode(self.currentConnection.freeswitch_port)) def clone(self): """ @@ -63,6 +82,8 @@ class ConnectionsHandler(BaseHandler): """ Add new connection. """ + print '!' + print self.parent self.currentConnection = None name_template = 'New connection [{0:02}]' @@ -77,7 +98,7 @@ class ConnectionsHandler(BaseHandler): if not connection_exists: break - self.parent.ui.connectionName.setText(name) + self.parent.ui.connectionName.setText('New connection') self.parent.ui.connectionName.setFocus() self.parent.ui.connectionName.selectAll() self.parent.ui.connectionLocalIpAddress.clear() @@ -93,7 +114,7 @@ class ConnectionsHandler(BaseHandler): # Add to connection list if we've created it. if self.currentConnection is None: - self.currentConnection = models.Connection(store=state.store) + #self.currentConnection = models.Connection(store=state.store) self.connections.append(self.currentConnection) self.parent.ui.connectionList.addItem(name) diff --git a/src/ipypbx/main.py b/src/ipypbx/main.py index 197e921..72d1de0 100644 --- a/src/ipypbx/main.py +++ b/src/ipypbx/main.py @@ -15,44 +15,99 @@ # You should have received a copy of the GNU General Public License # along with IPyPBX. If not, see . +import os import sys -from ipypbx import controllers, state, ui -from PyQt4 import QtCore, QtGui +from ipypbx import controllers, sql, ui +from PyQt4 import QtCore, QtGui, QtSql -class MainWindow(QtGui.QMainWindow): +# Working directory path. +# NOTE: ~/.ipypbx gives an error - for some reason QT doesn't like the dot? +PREFIX = os.path.expanduser('~/.ipypbx') + +# Database file name. +DB_NAME = 'ipypbx.db' + + +def setupDb(prefix=PREFIX, dbname=DB_NAME): """ - Main application window. + Setup database. """ - def __init__(self): - QtGui.QMainWindow.__init__(self) - locale = QtCore.QLocale.system().name() - translator = QtCore.QTranslator() + created = False + # Create it if necessary. + if prefix: + if not os.path.exists(prefix): + created = True + os.mkdir(prefix, 0700) + + os.chdir(prefix) - if translator.load("ipypbx_%s" % locale.toLower(), "ipypbx/locale"): - app.installTranslator(translator) + # Connect to SQLite database. + db = QtSql.QSqlDatabase.addDatabase("QSQLITE") + db.setDatabaseName(dbname) + + if db.open(): + if created: + for query in sql.creation_queries: + QtSql.QSqlQuery().exec_(query) + else: + QtGui.QMessageBox.warning( + None, "Fatal Error", "Database Error: %s" % db.lastError().text()) + sys.exit(1) - self.ui = ui.Ui_MainWindow() - self.ui.setupUi(self) + +if __name__ == '__main__': + app = QtGui.QApplication(sys.argv) + setupDb() +# import pdb; pdb.set_trace() +# runApp() + views = ui.MainWindow() + views.show() - self.connections = controllers.ConnectionsHandler(self) + connectionModel = QtSql.QSqlTableModel(views) + connectionModel.setTable('connections') + connectionModel.setHeaderData( + sql.Connection.id, QtCore.Qt.Horizontal, + QtCore.QVariant('Connection_ID')) + connectionModel.setHeaderData( + sql.Connection.name, QtCore.Qt.Horizontal, + QtCore.QVariant('Name')) + connectionModel.setHeaderData( + sql.Connection.local_ip_address, QtCore.Qt.Horizontal, + QtCore.QVariant('Local_IP_Address')) + connectionModel.setHeaderData( + sql.Connection.local_port, QtCore.Qt.Horizontal, + QtCore.QVariant('Local_Port')) + connectionModel.setHeaderData( + sql.Connection.freeswitch_ip_address, QtCore.Qt.Horizontal, + QtCore.QVariant('Freeswitch_IP_Address')) + connectionModel.setHeaderData( + sql.Connection.freeswitch_port, QtCore.Qt.Horizontal, + QtCore.QVariant('Freeswitch_Port')) + connectionModel.select() - signals_data = ( - (self.ui.connectionList, 'activated(QModelIndex)', - self.connections.select), -# (self.ui.connectionClone, 'clicked()', self.connections.clone), - (self.ui.connectionSave, 'clicked()', self.connections.save), - (self.ui.connectionAdd, 'clicked()', self.connections.add), - ) + views.connectionView.setModel(connectionModel) + views.connectionView.setColumnHidden(sql.Connection.id, True) + views.connectionView.setSelectionMode(QtGui.QTableView.SingleSelection) + views.connectionView.setSelectionBehavior(QtGui.QTableView.SelectRows) + views.connectionView.resizeColumnsToContents() + views.connectionView.resizeRowsToContents() + views.connectionView.horizontalHeader().setStretchLastSection(True) - for sender, signal, receiver in signals_data: - QtCore.QObject.connect(sender, QtCore.SIGNAL(signal), receiver) + views.connectionData.setModel(connectionModel) + connectionController = controllers.ConnectionController() + signals_data = ( + # (self.ui.connectionList, 'currentRowChanged(int)', + # self.connections.select), + # (self.ui.connectionClone, 'clicked()', self.connections.clone), + # (self.ui.connectionSave, 'clicked()', self.connections.save), +# (views.connectionAdd, 'clicked()', connectionController.add), + ) -if __name__ == '__main__': - app = QtGui.QApplication(sys.argv) - win = MainWindow() - win.show() +# for sender, signal, receiver in signals_data: +# QtCore.QObject.connect(sender, QtCore.SIGNAL(signal), receiver) app.exec_() +# sys.exit() diff --git a/src/ipypbx/sql.py b/src/ipypbx/sql.py new file mode 100644 index 0000000..ed0bf8b --- /dev/null +++ b/src/ipypbx/sql.py @@ -0,0 +1,19 @@ +creation_queries = ( + ''' + create table connections ( + id integer, + name varchar(100), + local_ip_address varchar(15), + local_port integer, + freeswitch_ip_address varchar(15), + freeswitch_port integer) + ''', +# ''' +# insert into connections (id, name, local_ip_address, local_port, freeswitch_ip_address, freeswitch_port) +# values (1, "Foo", "127.0.0.1", 8021, "127.0.0.1", 8022) +# ''' + ) + +class Connection(object): + id, name, local_ip_address, local_port, freeswitch_ip_address, \ + freeswitch_port = range(6) diff --git a/src/ipypbx/state.py b/src/ipypbx/state.py index d60fe6e..71f190a 100644 --- a/src/ipypbx/state.py +++ b/src/ipypbx/state.py @@ -28,7 +28,7 @@ if not os.path.exists(PREFIX): os.mkdir(PREFIX, 0700) # Initialize sqlite DB file. -store = Store(os.path.join(PREFIX, 'ipypbx.db')) +#store = Store(os.path.join(PREFIX, 'ipypbx.db')) # Program state data. sipProfiles = [] diff --git a/src/ipypbx/ui.py b/src/ipypbx/ui.py index e1c854f..c13d6f5 100644 --- a/src/ipypbx/ui.py +++ b/src/ipypbx/ui.py @@ -1,24 +1,42 @@ -# -*- coding: utf-8 -*- +# Copyright (c) Stas Shtin, 2010 -# Form implementation generated from reading ui file '../ui/layout.ui' -# -# Created: Thu Apr 8 20:06:26 2010 -# by: PyQt4 UI code generator 4.7.2 -# -# WARNING! All changes made in this file will be lost! +# This file is part of IPyPBX. -from PyQt4 import QtCore, QtGui +# IPyPBX 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. -class Ui_MainWindow(object): - def setupUi(self, MainWindow): - MainWindow.setObjectName("MainWindow") - MainWindow.resize(800, 400) - self.centralwidget = QtGui.QWidget(MainWindow) +# IPyPBX 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 IPyPBX. If not, see . + +from PyQt4 import QtCore, QtGui, QtSql + +class MainWindow(QtGui.QMainWindow): + """ + Main GUI window. + """ + def __init__(self, parent=None): + super(MainWindow, self).__init__(parent) + + # Tweak layout. + self.setObjectName("MainWindow") + self.resize(800, 400) + self.centralwidget = QtGui.QWidget(self) self.centralwidget.setObjectName("centralwidget") + + # Add tab widget self.tabWidget = QtGui.QTabWidget(self.centralwidget) self.tabWidget.setGeometry(QtCore.QRect(-2, -1, 811, 491)) self.tabWidget.setMinimumSize(QtCore.QSize(800, 480)) self.tabWidget.setObjectName("tabWidget") + + # Connections tab definition. self.connectionsTab = QtGui.QWidget() self.connectionsTab.setObjectName("connectionsTab") self.layoutWidget = QtGui.QWidget(self.connectionsTab) @@ -26,51 +44,52 @@ class Ui_MainWindow(object): self.layoutWidget.setObjectName("layoutWidget") self.gridLayout = QtGui.QGridLayout(self.layoutWidget) self.gridLayout.setObjectName("gridLayout") - self.formLayout_7 = QtGui.QFormLayout() - self.formLayout_7.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) - self.formLayout_7.setObjectName("formLayout_7") - self.label_5 = QtGui.QLabel(self.layoutWidget) - self.label_5.setObjectName("label_5") - self.formLayout_7.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_5) - self.connectionName = QtGui.QLineEdit(self.layoutWidget) - self.connectionName.setMaxLength(100) - self.connectionName.setObjectName("connectionName") - self.formLayout_7.setWidget(0, QtGui.QFormLayout.FieldRole, self.connectionName) - self.connectionLocalIpAddress = QtGui.QLineEdit(self.layoutWidget) - self.connectionLocalIpAddress.setInputMethodHints(QtCore.Qt.ImhNone) - self.connectionLocalIpAddress.setObjectName("connectionLocalIpAddress") - self.formLayout_7.setWidget(1, QtGui.QFormLayout.FieldRole, self.connectionLocalIpAddress) - self.label_11 = QtGui.QLabel(self.layoutWidget) - self.label_11.setObjectName("label_11") - self.formLayout_7.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_11) - self.connectionLocalPort = QtGui.QLineEdit(self.layoutWidget) - self.connectionLocalPort.setObjectName("connectionLocalPort") - self.formLayout_7.setWidget(2, QtGui.QFormLayout.FieldRole, self.connectionLocalPort) - self.label_13 = QtGui.QLabel(self.layoutWidget) - self.label_13.setObjectName("label_13") - self.formLayout_7.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_13) - self.connectionFreeswitchPort = QtGui.QLineEdit(self.layoutWidget) - self.connectionFreeswitchPort.setObjectName("connectionFreeswitchPort") - self.formLayout_7.setWidget(4, QtGui.QFormLayout.FieldRole, self.connectionFreeswitchPort) - self.label_12 = QtGui.QLabel(self.layoutWidget) - self.label_12.setObjectName("label_12") - self.formLayout_7.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_12) - self.connectionFreeswitchIpAddress = QtGui.QLineEdit(self.layoutWidget) - self.connectionFreeswitchIpAddress.setObjectName("connectionFreeswitchIpAddress") - self.formLayout_7.setWidget(3, QtGui.QFormLayout.FieldRole, self.connectionFreeswitchIpAddress) - self.label_14 = QtGui.QLabel(self.layoutWidget) - self.label_14.setObjectName("label_14") - self.formLayout_7.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_14) - self.gridLayout.addLayout(self.formLayout_7, 0, 1, 1, 1) + self.connectionData = QtGui.QDataWidgetMapper() + #self.formLayout_7 = QtGui.QFormLayout() + #self.formLayout_7.setFieldGrowthPolicy(QtGui.QFormLayout.AllNonFixedFieldsGrow) + #self.formLayout_7.setObjectName("formLayout_7") + #self.label_5 = QtGui.QLabel(self.layoutWidget) + #self.label_5.setObjectName("label_5") + #self.formLayout_7.setWidget(0, QtGui.QFormLayout.LabelRole, self.label_5) + #self.connectionName = QtGui.QLineEdit(self.layoutWidget) + #self.connectionName.setMaxLength(100) + #self.connectionName.setObjectName("connectionName") + #self.formLayout_7.setWidget(0, QtGui.QFormLayout.FieldRole, self.connectionName) + #self.connectionLocalIpAddress = QtGui.QLineEdit(self.layoutWidget) + #self.connectionLocalIpAddress.setInputMethodHints(QtCore.Qt.ImhNone) + #self.connectionLocalIpAddress.setObjectName("connectionLocalIpAddress") + #self.formLayout_7.setWidget(1, QtGui.QFormLayout.FieldRole, self.connectionLocalIpAddress) + #self.label_11 = QtGui.QLabel(self.layoutWidget) + #self.label_11.setObjectName("label_11") + #self.formLayout_7.setWidget(2, QtGui.QFormLayout.LabelRole, self.label_11) + #self.connectionLocalPort = QtGui.QLineEdit(self.layoutWidget) + #self.connectionLocalPort.setObjectName("connectionLocalPort") + #self.formLayout_7.setWidget(2, QtGui.QFormLayout.FieldRole, self.connectionLocalPort) + #self.label_13 = QtGui.QLabel(self.layoutWidget) + #self.label_13.setObjectName("label_13") + #self.formLayout_7.setWidget(4, QtGui.QFormLayout.LabelRole, self.label_13) + #self.connectionFreeswitchPort = QtGui.QLineEdit(self.layoutWidget) + #self.connectionFreeswitchPort.setObjectName("connectionFreeswitchPort") + #self.formLayout_7.setWidget(4, QtGui.QFormLayout.FieldRole, self.connectionFreeswitchPort) + #self.label_12 = QtGui.QLabel(self.layoutWidget) + #self.label_12.setObjectName("label_12") + #self.formLayout_7.setWidget(1, QtGui.QFormLayout.LabelRole, self.label_12) + #self.connectionFreeswitchIpAddress = QtGui.QLineEdit(self.layoutWidget) + #self.connectionFreeswitchIpAddress.setObjectName("connectionFreeswitchIpAddress") + #self.formLayout_7.setWidget(3, QtGui.QFormLayout.FieldRole, self.connectionFreeswitchIpAddress) + #self.label_14 = QtGui.QLabel(self.layoutWidget) + #self.label_14.setObjectName("label_14") + #self.formLayout_7.setWidget(3, QtGui.QFormLayout.LabelRole, self.label_14) + #self.gridLayout.addLayout(self.formLayout_7, 0, 1, 1, 1) self.connectionAdd = QtGui.QPushButton(self.layoutWidget) self.connectionAdd.setObjectName("connectionAdd") self.gridLayout.addWidget(self.connectionAdd, 1, 0, 1, 1) self.connectionSave = QtGui.QPushButton(self.layoutWidget) self.connectionSave.setObjectName("connectionSave") self.gridLayout.addWidget(self.connectionSave, 1, 1, 1, 1) - self.connectionList = QtGui.QListWidget(self.layoutWidget) - self.connectionList.setObjectName("connectionList") - self.gridLayout.addWidget(self.connectionList, 0, 0, 1, 1) + self.connectionView = QtGui.QTableView(self.layoutWidget) + self.connectionView.setObjectName("connectionView") + self.gridLayout.addWidget(self.connectionView, 0, 0, 1, 1) self.tabWidget.addTab(self.connectionsTab, "") self.sipProfilesTab = QtGui.QWidget() self.sipProfilesTab.setMaximumSize(QtCore.QSize(796, 16777215)) @@ -358,19 +377,27 @@ class Ui_MainWindow(object): self.formLayout_4.setWidget(3, QtGui.QFormLayout.FieldRole, self.extensionEndpoint) self.gridLayout_4.addLayout(self.formLayout_4, 0, 1, 1, 1) self.tabWidget.addTab(self.extensionsTab, "") - MainWindow.setCentralWidget(self.centralwidget) + self.setCentralWidget(self.centralwidget) - self.retranslateUi(MainWindow) + self.retranslateUi() self.tabWidget.setCurrentIndex(0) - QtCore.QMetaObject.connectSlotsByName(MainWindow) + QtCore.QMetaObject.connectSlotsByName(self) + + def retranslateUi(self): + locale = QtCore.QLocale.system().name() + translator = QtCore.QTranslator() + + if translator.load("ipypbx_%s" % locale.toLower(), "ipypbx/locale"): + QtGui.QApplication.installTranslator(translator) - def retranslateUi(self, MainWindow): - MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "IPyPBX", None, QtGui.QApplication.UnicodeUTF8)) - self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)) - self.label_11.setText(QtGui.QApplication.translate("MainWindow", "Local Port", None, QtGui.QApplication.UnicodeUTF8)) - self.label_13.setText(QtGui.QApplication.translate("MainWindow", "Freeswitch Port", None, QtGui.QApplication.UnicodeUTF8)) - self.label_12.setText(QtGui.QApplication.translate("MainWindow", "Local IP address", None, QtGui.QApplication.UnicodeUTF8)) - self.label_14.setText(QtGui.QApplication.translate("MainWindow", "Freeswitch IP Address", None, QtGui.QApplication.UnicodeUTF8)) + self.setWindowTitle( + QtGui.QApplication.translate( + "MainWindow", "IPyPBX", None, QtGui.QApplication.UnicodeUTF8)) + #self.label_5.setText(QtGui.QApplication.translate("MainWindow", "Name", None, QtGui.QApplication.UnicodeUTF8)) + #self.label_11.setText(QtGui.QApplication.translate("MainWindow", "Local Port", None, QtGui.QApplication.UnicodeUTF8)) + #self.label_13.setText(QtGui.QApplication.translate("MainWindow", "Freeswitch Port", None, QtGui.QApplication.UnicodeUTF8)) + #self.label_12.setText(QtGui.QApplication.translate("MainWindow", "Local IP address", None, QtGui.QApplication.UnicodeUTF8)) + #self.label_14.setText(QtGui.QApplication.translate("MainWindow", "Freeswitch IP Address", None, QtGui.QApplication.UnicodeUTF8)) self.connectionAdd.setText(QtGui.QApplication.translate("MainWindow", "Add", None, QtGui.QApplication.UnicodeUTF8)) self.connectionSave.setText(QtGui.QApplication.translate("MainWindow", "Save", None, QtGui.QApplication.UnicodeUTF8)) self.tabWidget.setTabText(self.tabWidget.indexOf(self.connectionsTab), QtGui.QApplication.translate("MainWindow", "Connections", None, QtGui.QApplication.UnicodeUTF8)) -- 1.7.9.5