1 # Copyright (c) Stas Shtin, 2010
3 # This file is part of IPyPBX.
5 # IPyPBX is free software: you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation, either version 3 of the License, or
8 # (at your option) any later version.
10 # IPyPBX is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
15 # You should have received a copy of the GNU General Public License
16 # along with IPyPBX. If not, see <http://www.gnu.org/licenses/>.
18 #from ipypbx import models
19 from PyQt4 import QtCore, QtGui, QtSql
22 class BaseController(QtCore.QObject):
24 Base class for other controllers.
26 Doesn't do anything useful on its own.
28 # TODO: possibly use a separate class for options and a meta-class.
31 view_display_fields = ()
32 view_display_fields_hidden = ()
34 def __init__(self, model=None, view_list=None, view_display=None, parent=None, views=None):
35 super(BaseController, self).__init__(parent=parent)
40 classname = self.__class__.__name__
42 classname[:-10] if classname.endswith('Controller')
44 self.basename = self.basename[0].lower() + self.basename[1:]
46 # Are we given an existing model?
49 # Otherwise initialize a new model.
51 self.model = QtSql.QSqlTableModel(parent)
52 self.model.setTable('ipypbxweb_%s' % self.basename.lower())
54 # Create model header from fields list.
55 for i, field in enumerate(self.fields):
56 self.model.setHeaderData(
57 i, QtCore.Qt.Horizontal, QtCore.QVariant(field))
62 # Are we given an existing view list?
64 self.view_list = view_list
65 # Otherwise get view list from the parent.
67 self.view_list = getattr(views, self.basename + 'ViewList')
68 self.view_list.setModel(self.model)
70 # Hide fields not meant for display.
71 for i, field in enumerate(self.fields):
72 if field not in self.view_list_fields:
73 self.view_list.hideColumn(i)
75 # Stretch headers to fill all available width.
76 self.view_list.setSelectionMode(QtGui.QTableView.SingleSelection)
77 self.view_list.setSelectionBehavior(QtGui.QTableView.SelectRows)
78 self.view_list.resizeColumnsToContents()
79 self.view_list.resizeRowsToContents()
80 self.view_list.horizontalHeader().setStretchLastSection(True)
81 self.view_list.selectRow(0)
83 # Are we given an existing view display?
85 self.view_display = view_display
86 # Otherwise get view display from the parent.
88 self.view_display = QtGui.QDataWidgetMapper(parent)
89 self.view_display.setModel(self.model)
91 # If view_display_fields is not send, display all fields except
92 # the first one that is usually the ID.
93 display_fields = self.getDisplayFields()
94 for i, field in enumerate(self.fields):
95 if field in display_fields:
96 field_widget = self.getFieldWidget(field)
97 self.view_display.addMapping(field_widget, i)
99 # Select first row in the view list.
100 self.view_display.toFirst()
102 # Register signals for this controller.
103 for data in self.getSignalsData():
105 sender, signal, receiver = data
106 QtCore.QObject.connect(sender, QtCore.SIGNAL(signal), receiver)
108 sender, signal, receiver, slot = data
109 QtCore.QObject.connect(
110 sender, QtCore.SIGNAL(signal), receiver, QtCore.SLOT(slot))
113 def getDisplayFields(self):
115 Return the list of fields to display.
117 If it's not set explicitly, use all defined fields except the first
118 which usually is the primary key.
120 # Do we have the fields to display explicitly set?
121 if self.view_display_fields:
122 fields = self.view_display_fields
124 # Do we have hidden fields set?
125 if self.view_display_fields_hidden:
126 hidden = self.view_display_fields_hidden
127 # If not, hide the first one.
129 hidden = self.fields[0]
131 # Filter away all hidden fields.
132 fields = [field for field in self.fields if not field in hidden]
136 def getFieldWidget(self, field):
138 Return widget for given field name.
142 self.basename + ''.join(word.capitalize()
143 for word in field.split(' ')))
145 def getSignalsData(self):
147 Default signals built from controller's base name.
149 # Default signals handle row selection, Add and Save buttons.
151 (getattr(self.views, self.basename + 'Add'), 'clicked()', self.add),
152 (self.view_list.selectionModel(),
153 'currentRowChanged(QModelIndex,QModelIndex)',
154 self.view_display, 'setCurrentModelIndex(QModelIndex)'),
155 (getattr(self.views, self.basename + 'Save'), 'clicked()',
163 # Add a new row to list view.
164 num_rows = self.model.rowCount()
165 self.model.insertRows(num_rows, 1)
166 self.view_list.selectRow(num_rows)
168 # Disable adding more than one row.
169 self.getFieldWidget('Add').setEnabled(False)
171 # Focust to the first displayed field.
172 self.getFieldWidget(self.getDisplayFields()[0]).setFocus()
174 # Clear all displayed fields.
175 for field in self.getDisplayFields():
176 self.getFieldWidget(field).clear()
182 # For now we just submit everything - QT seems to be able to handle it
184 self.view_display.submit()
185 self.getFieldWidget('Add').setEnabled(True)
189 class ConnectionController(BaseController):
191 Connections controller.
194 'ID', 'Name', 'Local IP Address', 'Local Port',
195 'Freeswitch IP Address', 'Freeswitch Port')
196 view_list_fields = 'Name', 'Freeswitch IP Address', 'Freeswitch Port'
200 TODO: Clone an existing connection.
202 This creates a new connection with bound data copied from another one.
205 class SipProfileController(BaseController):
207 SIP Profile controller.
210 'ID', 'Connection ID', 'Name', 'External RTP IP', 'External SIP IP',
211 'RTP IP', 'SIP IP', 'SIP Port', 'Accept Blind Registration',
212 'Authenticate Calls', 'Is Active')
213 view_list_fields = 'Name', 'SIP IP', 'SIP Port'
214 view_display_fields_hidden = 'ID', 'Connection ID'
217 class DomainController(BaseController):
221 fields = 'ID', 'SIP Profile ID', 'Host Name', 'Is Active'
222 view_list_fields = 'SIP Profile ID', 'Host Name', 'Is Active'
225 class GatewayController(BaseController):
230 'ID', 'SIP Profile ID', 'Name', 'Username', 'Password', 'Realm',
231 'From Domain', 'Expire In Seconds', 'Retry In Seconds',
232 'Caller ID In From Field', 'Is Active')
233 view_list_fields = 'SIP Profile ID', 'Name'
236 class EndpointController(BaseController):
240 fields = 'ID', 'User ID', 'Password', 'Domain ID', 'Is Active'
243 class ExtensionController(BaseController):
245 Extension controller.
248 'ID', 'Destination Match', 'XML Dialplan', 'Domain ID', 'Endpoint ID',
249 'Authenticate Calls', 'Is Active')
250 view_list_fields = 'Destination Match', 'Domain ID', 'Endpoint ID'