Add/edit all tables. Data gets save to DB at last\!
[ipypbx] / src / ipypbx / controllers.py
index a196a27..6f7f173 100644 (file)
@@ -28,7 +28,8 @@ class BaseController(QtCore.QObject):
     fields = ()
     view_list_fields = ()
     view_display_fields = ()
-    view_display_fields_hidden = ()
+    view_display_fields_hidden = 'ID', 'Connection ID'
+    is_bound_to_connection = True
     
     def __init__(self, model=None, view_list=None, view_display=None, parent=None, views=None):
         super(BaseController, self).__init__(parent=parent)
@@ -49,11 +50,15 @@ class BaseController(QtCore.QObject):
         else:
             self.model = QtSql.QSqlTableModel(parent)
             self.model.setTable('ipypbxweb_%s' % self.basename.lower())
+            self.model.setEditStrategy(self.model.OnRowChange)
 
             # Create model header from fields list.
             for i, field in enumerate(self.fields):
                 self.model.setHeaderData(
-                    i, QtCore.Qt.Horizontal, QtCore.QVariant(field))
+                    i, QtCore.Qt.Horizontal,
+                    QtCore.QVariant(QtGui.QApplication.translate(
+                        "MainWindow", field, None,
+                        QtGui.QApplication.UnicodeUTF8)))
 
             # Fetch model data.
             self.model.select()
@@ -77,6 +82,8 @@ class BaseController(QtCore.QObject):
             self.view_list.resizeColumnsToContents()
             self.view_list.resizeRowsToContents()
             self.view_list.horizontalHeader().setStretchLastSection(True)
+
+        # Select first row.
         self.view_list.selectRow(0)
 
         # Are we given an existing view display?
@@ -87,9 +94,8 @@ class BaseController(QtCore.QObject):
             self.view_display = QtGui.QDataWidgetMapper(parent)
             self.view_display.setModel(self.model)
 
-            # If view_display_fields is not send, display all fields except
-            # the first one that is usually the ID.
             display_fields = self.getDisplayFields()
+            
             for i, field in enumerate(self.fields):
                 if field in display_fields:
                     field_widget = self.getFieldWidget(field)
@@ -108,30 +114,6 @@ class BaseController(QtCore.QObject):
                 QtCore.QObject.connect(
                     sender, QtCore.SIGNAL(signal), receiver, QtCore.SLOT(slot))
                                        
-
-    def getDisplayFields(self):
-        """
-        Return the list of fields to display.
-
-        If it's not set explicitly, use all defined fields except the first
-        which usually is the primary key.
-        """
-        # Do we have the fields to display explicitly set?
-        if self.view_display_fields:
-            fields = self.view_display_fields
-        else:
-            # Do we have hidden fields set?
-            if self.view_display_fields_hidden:
-                hidden = self.view_display_fields_hidden
-            # If not, hide the first one.
-            else:
-                hidden = self.fields[0]
-
-            # Filter away all hidden fields.
-            fields = [field for field in self.fields if not field in hidden]
-            
-        return fields
-
     def getFieldWidget(self, field):
         """
         Return widget for given field name.
@@ -141,19 +123,29 @@ class BaseController(QtCore.QObject):
             self.basename + ''.join(word.capitalize()
                                     for word in field.split(' ')))
 
+    def getDisplayFields(self):
+        """
+        Return list of display fields.
+        
+        If view_display_fields is not send, display all fields except
+        the first one that is usually the ID.
+        """
+        return [
+            field for field in self.fields
+            if not field in self.view_display_fields_hidden]        
+
     def getSignalsData(self):
         """
         Default signals built from controller's base name.
         """
         # Default signals handle row selection, Add and Save buttons.
-        return (
+        return [
             (getattr(self.views, self.basename + 'Add'), 'clicked()', self.add),
             (self.view_list.selectionModel(),
              'currentRowChanged(QModelIndex,QModelIndex)',
              self.view_display, 'setCurrentModelIndex(QModelIndex)'),
             (getattr(self.views, self.basename + 'Save'), 'clicked()',
-             self.save),
-            )
+             self.save)]
 
     def add(self):
         """
@@ -170,19 +162,14 @@ class BaseController(QtCore.QObject):
         # Focust to the first displayed field.
         self.getFieldWidget(self.getDisplayFields()[0]).setFocus()
 
-        # Clear all displayed fields.
-        for field in self.getDisplayFields():
-            self.getFieldWidget(field).clear()
-        
+        # TODO: set default values?
+
     def save(self):
         """
         Save to database.
         """
-        # For now we just submit everything - QT seems to be able to handle it
-        # on its own.
         self.view_display.submit()
         self.getFieldWidget('Add').setEnabled(True)
-        
 
 
 class ConnectionController(BaseController):
@@ -190,61 +177,130 @@ class ConnectionController(BaseController):
     Connections controller.
     """
     fields = (
-        'ID', 'Name', 'Local IP Address', 'Local Port',
-        'Freeswitch IP Address', 'Freeswitch Port')
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Name'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Local IP Address'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Local Port'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Freeswitch IP Address'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Freeswitch Port'))
     view_list_fields = 'Name', 'Freeswitch IP Address', 'Freeswitch Port'
-    
-    def clone(self):
+
+
+class ConnectionChangeListenerController(BaseController):
+    """
+    Mixin class for reacting on connection change.
+    """
+    def getSignalsData(self):
+        """
+        Listen to connection change signal.
+        """
+        connection_controller = self.parent().controllers[0]
+
+        signals = [
+            (connection_controller.view_list.selectionModel(),
+             'currentRowChanged(QModelIndex,QModelIndex)',
+             self.connectionChange),
+            (self.model, 'primeInsert(int,QSqlRecord&)',
+             self.setConnectionId)] 
+        signals.extend(super(
+            ConnectionChangeListenerController, self).getSignalsData())
+        return signals
+        
+    def connectionChange(self, index):
         """
-        TODO: Clone an existing connection.
+        Connection change handler.
 
-        This creates a new connection with bound data copied from another one.
+        Filters table by a new connection ID and stores last connection ID
+        locally.
         """
+        if index.row() != -1:
+            connection_id, ok = index.model().data(
+                index.sibling(index.row(), 0)).toInt()
+            self.connection_id = connection_id
+            self.model.setFilter('connection_id = %i' % connection_id)
 
-class SipProfileController(BaseController):
+    def setConnectionId(self, row, record):
+        record.setValue('connection_id', self.connection_id)
+
+        
+class SipProfileController(ConnectionChangeListenerController):
     """
     SIP Profile controller.
     """
     fields = (
-        'ID', 'Connection ID', 'Name', 'External RTP IP', 'External SIP IP',
-        'RTP IP', 'SIP IP', 'SIP Port', 'Accept Blind Registration',
-        'Authenticate Calls', 'Is Active')
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Connection ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Name'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'External RTP IP'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'External SIP IP'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'RTP IP'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'SIP IP'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'SIP Port'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Accept Blind Registration'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Authenticate Calls'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Is Active'))
     view_list_fields = 'Name', 'SIP IP', 'SIP Port'
-    view_display_fields_hidden = 'ID', 'Connection ID'
-
+    
 
-class DomainController(BaseController):
+class DomainController(ConnectionChangeListenerController):
     """
     Domain controller.
     """
-    fields = 'ID', 'SIP Profile ID', 'Host Name', 'Is Active'
-    view_list_fields = 'SIP Profile ID', 'Host Name', 'Is Active'
+    fields = (
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Connection ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'SIP Profile ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Host Name'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Is Active'))
+    view_list_fields = 'SIP Profile', 'Host Name'
 
 
-class GatewayController(BaseController):
+class GatewayController(ConnectionChangeListenerController):
     """
     Gateway controller.
     """
     fields = (
-        'ID', 'SIP Profile ID', 'Name', 'Username', 'Password', 'Realm',
-        'From Domain', 'Expire In Seconds', 'Retry In Seconds',
-        'Caller ID In From Field', 'Is Active')
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Connection ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'SIP Profile ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Name'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Username'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Password'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Realm'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'From Domain'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Expire In Seconds'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Retry In Seconds'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Caller ID In From Field'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Is Active'))
     view_list_fields = 'SIP Profile ID', 'Name'
 
 
-class EndpointController(BaseController):
+class EndpointController(ConnectionChangeListenerController):
     """
     Endpoint controller.
     """
-    fields = 'ID', 'User ID', 'Password', 'Domain ID', 'Is Active'
-
+    fields = (
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Connection ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'User ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Password'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Domain ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Is Active'))
+    view_list_fields = 'User ID', 'Domain ID'
+    
 
-class ExtensionController(BaseController):
+class ExtensionController(ConnectionChangeListenerController):
     """
     Extension controller.
     """
     fields = (
-        'ID', 'Destination Match', 'XML Dialplan', 'Domain ID', 'Endpoint ID',
-        'Authenticate Calls', 'Is Active')
-    view_list_fields = 'Destination Match', 'Domain ID', 'Endpoint ID'
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Connection ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Destination Match'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'XML Dialplan'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Domain ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Endpoint ID'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Authenticate Calls'),
+        QtCore.QT_TRANSLATE_NOOP('MainWindow', 'Is Active'))
+    view_list_fields = 'Destination Match',