changeset 16:6a62de088c00

implement editing existing connections
author Dirk Olmes <dirk@xanthippe.ping.de>
date Wed, 24 Sep 2014 03:51:33 +0200
parents d8958cb11043
children 58bfa3d9f5a9
files RemoteViewer/Connection.py RemoteViewer/ConnectionDialog.py RemoteViewer/RemoteViewer.py RemoteViewer/RemoteViewer.ui RemoteViewer/Settings.py
diffstat 5 files changed, 123 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/RemoteViewer/Connection.py	Tue Sep 23 01:44:24 2014 +0200
+++ b/RemoteViewer/Connection.py	Wed Sep 24 03:51:33 2014 +0200
@@ -1,7 +1,15 @@
-
+from uuid import uuid4
 from .Viewer import VncViewer, FreeRdp
 
-KEYS = ['geometry', 'host', 'title', 'type', 'user']
+KEYS = ['geometry', 'id', 'host', 'title', 'type', 'user']
+
+def filter_string(func):
+    '''decorator function to filter turn empty strings into None'''
+    def __perform(object, string):
+        if len(string) == 0:
+            string = None
+        return func(object, string)
+    return __perform
 
 class Connection(object):
     @staticmethod
@@ -15,14 +23,16 @@
 
     def __init__(self):
         self.geometry = None
+        self.id = str(uuid4())
         self.host = None
         self.title = None
         self.type = 'vnc'
         self.user = None
 
     def __str__(self):
-        return 'connection "{}" of type {} to {} with user {} and geometry {}'.format(self.title, self.type,  self.host, self.user, self.geometry)
+        return 'connection@{} "{}" of type {} to {} with user {} and geometry {}'.format(self.title, id(self), self.type,  self.host, self.user, self.geometry)
 
+    @filter_string
     def setTitle(self, title):
         '''This is a slot that is connected to a signal in the GUI'''
         self.title = title
@@ -31,14 +41,17 @@
         '''This is a slot that is connected to a signal in the GUI'''
         self.type = type
 
+    @filter_string
     def setHost(self, hostname):
         '''This is a slot that is connected to a signal in the GUI'''
         self.host = hostname
 
+    @filter_string
     def setUser(self, user):
         '''This is a slot that is connected to a signal in the GUI'''
-        self.user= user
+        self.user = user
 
+    @filter_string
     def setGeometry(self, geometry):
         '''This is a slot that is connected to a signal in the GUI'''
         self.geometry = geometry
@@ -50,14 +63,21 @@
             return self.host
 
     def validate(self):
-        # TODO: implement proper validation
-        pass
+        validationErrors = []
+        if self.host is None:
+            validationErrors.append('host may not be empty')
+        if len(validationErrors) > 0:
+            return validationErrors
+        else:
+            return None
 
     def toJson(self):
         json = {}
         for key in KEYS:
             if hasattr(self,  key):
-                json[key] = getattr(self,  key)
+                value = getattr(self,  key)
+                if value is not None:
+                    json[key] = value
         return json
 
     def open(self, parent):
--- a/RemoteViewer/ConnectionDialog.py	Tue Sep 23 01:44:24 2014 +0200
+++ b/RemoteViewer/ConnectionDialog.py	Wed Sep 24 03:51:33 2014 +0200
@@ -3,23 +3,35 @@
 from .Ui_ConnectionDialog import Ui_ConnectionDialog
 
 class ConnectionDialog(QDialog):
-    def __init__(self,  windowTitle=''):
+    def __init__(self,  windowTitle='', connection=Connection()):
         super(QDialog, self).__init__()
-        self.__initDefaultValues()
+        self.connection = connection
         self.__initUi(windowTitle)
-        self.__connectConnection()
-
-    def __initDefaultValues(self):
-        self.connection = Connection()
 
     def __initUi(self, windowTitle):
         self.ui = Ui_ConnectionDialog()
         self.ui.setupUi(self)
         self.setWindowTitle(windowTitle)
+        self.__initTypeDropDown()
+        self.__loadConnection()
+        self.__connectWidgetSlots()
+
+    def __initTypeDropDown(self):
         self.ui.type.addItem('rdp')
         self.ui.type.addItem('vnc')
 
-    def __connectConnection(self):
+    def __loadConnection(self):
+        self.ui.title.setText(self.connection.title)
+        if self.connection.type == 'rdp':
+            index = 0
+        else:
+            index = 1
+        self.ui.type.setCurrentIndex(index)
+        self.ui.hostname.setText(self.connection.host)
+        self.ui.username.setText(self.connection.user)
+        self.ui.geometry.setText(self.connection.geometry)
+
+    def __connectWidgetSlots(self):
         self.ui.title.textChanged.connect(self.connection.setTitle)
         self.ui.type.activated[str].connect(self.connection.setType)
         self.ui.hostname.textChanged.connect(self.connection.setHost)
@@ -27,4 +39,9 @@
         self.ui.geometry.textChanged.connect(self.connection.setGeometry)
 
     def accept(self):
-        super(ConnectionDialog, self).accept()
+        validationErrors = self.connection.validate()
+        if validationErrors is None:
+            super(ConnectionDialog, self).accept()
+        else:
+            # TODO: display the error message
+            print('connection has validation errors:',  validationErrors)
--- a/RemoteViewer/RemoteViewer.py	Tue Sep 23 01:44:24 2014 +0200
+++ b/RemoteViewer/RemoteViewer.py	Wed Sep 24 03:51:33 2014 +0200
@@ -10,6 +10,7 @@
     def __init__(self):
         super(RemoteViewer,  self).__init__()
         self.settings = Settings()
+        self.activeConnection = None
         self.__initUi()
 
     def __initUi(self):
@@ -22,6 +23,10 @@
         model = GenericListModel(self,  connections,  'displayString')
         self.ui.hostList.setModel(model)
 
+    def connectionSelected(self, index):
+        self.activeConnection = index.internalPointer()
+        self.ui.actionEdit.setEnabled(True)
+
     @ExceptionSafeSlot()
     def newConnection(self):
         dialog = ConnectionDialog('New Connection')
@@ -30,6 +35,13 @@
             connection = dialog.connection
             self.settings.addConnection(connection)
 
+    @ExceptionSafeSlot()
+    def editConnection(self):
+        title = 'Edit {}'.format(self.activeConnection.displayString())
+        dialog = ConnectionDialog(title, self.activeConnection)
+        dialog.exec_()
+        self.settings.update(self.activeConnection)
+
     @ExceptionSafeSlot('QModelIndex')
     def openConnection(self, index):
         connection = index.internalPointer()
--- a/RemoteViewer/RemoteViewer.ui	Tue Sep 23 01:44:24 2014 +0200
+++ b/RemoteViewer/RemoteViewer.ui	Wed Sep 24 03:51:33 2014 +0200
@@ -34,6 +34,7 @@
      <string>Connection</string>
     </property>
     <addaction name="actionNew"/>
+    <addaction name="actionEdit"/>
     <addaction name="separator"/>
     <addaction name="actionQuit"/>
    </widget>
@@ -56,6 +57,17 @@
     <string>Ctrl+N</string>
    </property>
   </action>
+  <action name="actionEdit">
+   <property name="enabled">
+    <bool>false</bool>
+   </property>
+   <property name="text">
+    <string>Edit</string>
+   </property>
+   <property name="shortcut">
+    <string>Ctrl+E</string>
+   </property>
+  </action>
  </widget>
  <resources/>
  <connections>
@@ -107,9 +119,43 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>actionEdit</sender>
+   <signal>triggered()</signal>
+   <receiver>RemoteViewer</receiver>
+   <slot>editConnection()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>-1</x>
+     <y>-1</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>219</x>
+     <y>204</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>hostList</sender>
+   <signal>clicked(QModelIndex)</signal>
+   <receiver>RemoteViewer</receiver>
+   <slot>connectionSelected(QModelIndex)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>143</x>
+     <y>263</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>120</x>
+     <y>383</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
  <slots>
   <slot>newConnection()</slot>
   <slot>openConnection(QModelIndex)</slot>
+  <slot>editConnection()</slot>
+  <slot>connectionSelected(QModelIndex)</slot>
  </slots>
 </ui>
--- a/RemoteViewer/Settings.py	Tue Sep 23 01:44:24 2014 +0200
+++ b/RemoteViewer/Settings.py	Wed Sep 24 03:51:33 2014 +0200
@@ -3,6 +3,7 @@
 from .Connection import Connection
 
 CONNECTIONS_KEY = 'connections'
+ID_KEY = 'id'
 
 class Settings(AbstractSettings):
     def __init__(self):
@@ -26,3 +27,15 @@
     def addConnection(self,  connection):
         json = connection.toJson()
         self.config[CONNECTIONS_KEY].append(json)
+        self.persist()
+
+    def update(self, connection):
+        id = connection.id
+        self.__remove(id)
+        self.addConnection(connection)
+
+    def __remove(self, id):
+        allConnections = self.config[CONNECTIONS_KEY]
+        for conn in allConnections:
+            if conn[ID_KEY] == id:
+                allConnections.remove(conn)