Package client :: Module Connection
[hide private]
[frames] | no frames]

Source Code for Module client.Connection

  1  """ 
  2  Overview 
  3  ======== 
  4  This module provides the dialog necessary for connecting to a Basin Remote session.  It 
  5  provides a mechanism for permanently storing profiles for a user to easily connect to 
  6  multiple sessions. 
  7  """ 
  8   
  9  from PyQt4.QtGui  import * 
 10  from PyQt4.QtCore import * 
 11   
 12  import re 
 13   
 14  import Constants 
 15   
16 -class ConnectionDialog (QDialog):
17 """ 18 """ 19
20 - def __init__ (self, bridge):
21 """ 22 """ 23 24 QDialog.__init__ (self, bridge._mainWindow) 25 self._bridge = bridge 26 mainRect = self._bridge._mainWindow.geometry () 27 width = mainRect.width () 28 height = mainRect.height () 29 x = mainRect.x () + int (width * 0.25) 30 y = mainRect.y () + int (height * 0.40) 31 width = int (width * 0.5) 32 height = int (height * 0.3) 33 self.setGeometry (x, y, width, height) 34 layout = QVBoxLayout () 35 self.setLayout (layout) 36 37 # A dictionary of profile names, to Profile objects 38 self.profiles = {} 39 40 # Set the window icon/title 41 self.setWindowTitle (QString ("Connect...")) 42 self.setWindowIcon (QIcon (Constants.ICON_DIR + "/file/connect.png")) 43 44 profileSelectLayout = QHBoxLayout () 45 profileSelectLabel = QLabel (QString ("Profile:")) 46 profileSelectLayout.addWidget (profileSelectLabel) 47 self._profileSelect = QComboBox () 48 QObject.connect (self._profileSelect, \ 49 SIGNAL ("currentIndexChanged (const QString&)"), self.profileChanged) 50 profileSelectLayout.addWidget (self._profileSelect) 51 layout.addLayout (profileSelectLayout) 52 53 self._profile = Constants.BTextField (layout, "Profile Name", "") 54 self._profile.setEnabled (False) 55 self._hostLine = Constants.BTextField (layout, "BASIN Host", "") 56 self._portLine = Constants.BTextField (layout, "BASIN Port", "") 57 self._userLine = Constants.BTextField (layout, "User Name", "") 58 59 self.loadSettings () 60 61 connectBox = QGroupBox ("Connection Actions") 62 connectBoxLayout = QHBoxLayout () 63 connectBox.setLayout (connectBoxLayout) 64 profileBox = QGroupBox ("Profile Actions") 65 profileBoxLayout = QHBoxLayout () 66 profileBox.setLayout (profileBoxLayout) 67 68 # Everything concerning the "Connect" button 69 connectButton = Constants.BQPushButton ("Connect", connectBoxLayout) 70 connectButton.setToolTip ("Connect with current profile") 71 QObject.connect (connectButton, SIGNAL("clicked ()"), self.accept) 72 73 # Everything concerning the "Cancel" button 74 cancelButton = Constants.BQPushButton ("Cancel", connectBoxLayout) 75 cancelButton.setToolTip ("Exit dialog without connecting") 76 QObject.connect (cancelButton, SIGNAL("clicked ()"), self.reject) 77 78 79 # Everything concerning the "New" button 80 newButton = Constants.BQPushButton ("New", profileBoxLayout) 81 newButton.setToolTip ("Create new profile") 82 QObject.connect (newButton, SIGNAL ("clicked ()"), self.newProfile) 83 84 # Everything concerning the "Remove" button 85 removeButton = Constants.BQPushButton ("Remove", profileBoxLayout) 86 removeButton.setToolTip ("Remove current profile") 87 QObject.connect (removeButton, SIGNAL ("clicked ()"), self.removeProfile) 88 89 # Everything concerning the "Save" button 90 saveButton = Constants.BQPushButton ("Save", profileBoxLayout) 91 saveButton.setToolTip ("Permanently change settings") 92 QObject.connect (saveButton, SIGNAL ("clicked ()"), self.saveProfile) 93 94 # Accumulate all sub-layouts into the main layout 95 layout.addWidget (connectBox) 96 layout.addWidget (profileBox) 97 98 # Actually start the dialog 99 self.exec_ ()
100
101 - def profileChanged (self, string):
102 """ 103 """ 104 105 self._profile.setEnabled (False) 106 profile = str (string) 107 self._profile.setText (profile) 108 self._hostLine.setText (self.profiles [profile].getHost ()) 109 self._portLine.setText (self.profiles [profile].getPort ()) 110 self._userLine.setText (self.profiles [profile].getUser ())
111
112 - def createProfile (self, profile):
113 """ 114 """ 115 116 # Creates new profile 117 self.profiles[str (profile)] = Profile (str (profile)) 118 self._profileSelect.addItems (QStringList (str (profile))) 119 120 # Jumps to new Profile 121 index = self._profileSelect.findText (profile) 122 self._profileSelect.setCurrentIndex (index)
123 124
125 - def newProfile (self):
126 """ 127 """ 128 129 dialog = QDialog (self) 130 dialog.setWindowTitle ("New Profile") 131 layout = QVBoxLayout (dialog) 132 profileName = Constants.BTextField (layout, "Profile Name", "") 133 buttonLayout = Constants.BQHBoxLayout (layout) 134 acceptButton = Constants.BQPushButton ("Ok", buttonLayout) 135 QObject.connect (acceptButton, SIGNAL ("clicked ()"), dialog.accept) 136 rejectButton = Constants.BQPushButton ("Cancel", buttonLayout) 137 QObject.connect (rejectButton, SIGNAL ("clicked ()"), dialog.reject) 138 dialog.exec_ () 139 140 if dialog.result () == 1: # Accepted 141 self.createProfile (profileName.text ())
142
143 - def saveProfile (self):
144 """ 145 Overview 146 ======== 147 This method should be called whenever you want to save updates to a profile. 148 You may want to do this whether the profile is new and as yet unsaved, or if 149 it is old and has just had changed applied to it. Afterwards it will save the 150 settings to file. 151 """ 152 153 self._profile.setEnabled (False) 154 profile = str (self._profile.text ()) 155 156 if profile not in self.profiles: 157 self.createProfile (profile) 158 159 self.profiles[profile].setHost (str (self._hostLine.text ())) 160 self.profiles[profile].setPort (str (self._portLine.text ())) 161 self.profiles[profile].setUser (str (self._userLine.text ())) 162 self.saveSettings ()
163
164 - def removeProfile (self):
165 """ 166 Overview 167 ======== 168 This method will remove the profile currently being viewed. While this may 169 seem permanent, this effect will not be permanent if the settings are not saved. 170 """ 171 172 # This will remove the currently viewed profile. 173 # This isn't permanent until the user clicks save or connect. 174 if self._profile.isEnabled (): 175 return 176 profile = str (self._profile.text ()) 177 del (self.profiles[profile]) 178 self._profileSelect.removeItem (self._profileSelect.currentIndex ())
179
180 - def loadSettings (self):
181 """ 182 """ 183 184 file = QFile (str (QDir.home ().path ()) + "/.basin/client/connection.conf") 185 if file.exists (): 186 file.open (QIODevice.ReadOnly | QIODevice.Text) 187 stream = QTextStream (file) 188 default = None 189 reDefault = re.compile ("\s*DEFAULT\s*:\s*[0-9]*\s*") 190 reProfile = re.compile ("\s*PROFILE\s*:\s*.*\s*") 191 reHost = re.compile ("\s*HOST\s*:\s*.*\s*:\s*.*\s*") 192 rePort = re.compile ("\s*PORT\s*:\s*.*\s*:\s*.*\s*") 193 reUser = re.compile ("\s*USER\s*:\s*.*\s*:\s*.*\s*") 194 while not stream.atEnd (): 195 line = str (stream.readLine ()) 196 197 if reProfile.match (line): 198 name = line[line.find (':') + 1:] 199 if name not in self.profiles: 200 self.profiles [name] = Profile (name) 201 elif reHost.match (line): 202 name = line[line.find (':') + 1:line.rfind (':')] 203 host = line[line.rfind (':') + 1:] 204 if name in self.profiles: 205 self.profiles[name].setHost (host) 206 elif rePort.match (line): 207 name = line[line.find (':') + 1:line.rfind (':')] 208 port = line[line.rfind (':') + 1:] 209 if name in self.profiles: 210 self.profiles[name].setPort (port) 211 elif reUser.match (line): 212 name = line[line.find (':') + 1:line.rfind (':')] 213 user = line[line.rfind (':') + 1:] 214 if name in self.profiles: 215 self.profiles[name].setUser (user) 216 elif reDefault.match (line): 217 default = int (line[line.find (':') + 1:]) 218 file.close () 219 220 # Populate the profileSelector combobox with the profiles 221 profileList = QStringList () 222 for profile in self.profiles.keys (): 223 profileList.append (profile) 224 self._profileSelect.addItems (profileList) 225 226 # If a default profile was found and is valid, go to it 227 if default and default < self._profileSelect.count (): 228 self._profileSelect.setCurrentIndex (default)
229
230 - def saveSettings (self):
231 """ 232 Overview 233 ======== 234 This method will save all of the profiles created to file. It will be saved under 235 C{$HOME/.basin/client/connection.conf} 236 """ 237 238 path = QDir.home () 239 if not path.exists (".basin"): 240 path.mkdir (".basin") 241 path.cd (".basin") 242 if not path.exists ("client"): 243 path.mkdir ("client") 244 path.cd ("client") 245 246 file = QFile (str (path.path ()) + "/connection.conf") 247 file.setPermissions (QFile.WriteOwner | QFile.ReadOwner | QFile.ReadUser | QFile.WriteUser) 248 file.open (QIODevice.WriteOnly | QIODevice.Text) 249 file.writeData ("Connection Preferences\n\n") 250 251 file.writeData ("DEFAULT:" + str (self._profileSelect.currentIndex ()) + "\n\n") 252 253 for profile in self.profiles.keys (): 254 host = self.profiles[profile].getHost () 255 port = self.profiles[profile].getPort () 256 user = self.profiles[profile].getUser () 257 file.writeData ("PROFILE:" + profile + "\n") 258 file.writeData ("HOST:" + profile + ":" + host + "\n") 259 file.writeData ("PORT:" + profile + ":" + port + "\n") 260 file.writeData ("USER:" + profile + ":" + user + "\n\n") 261 file.close ()
262
263 - def accept (self):
264 """ 265 Overview 266 ======== 267 This method is called whenever "Connect" is pressed. Incidently, it overrides the 268 QDialog's accept method, however, calls the QDialog's accept within here. It will 269 save all of the current connection settings, and then send the host, port, and user 270 to the ipython shell for connection. During the course of all this the cursor 271 will change to a busy status, and when it is done it will return. 272 """ 273 274 self._bridge.CursorBusy () 275 self.saveSettings () 276 self._bridge._host = self._hostLine.text () 277 self._bridge._port = self._portLine.text () 278 self._bridge._user = self._userLine.text () 279 self._bridge._ipyShell.Init (self._hostLine.text (), self._portLine.text (), \ 280 self._userLine.text ()) 281 QDialog.accept (self) 282 self._bridge.CursorNorm ()
283 284
285 -class Profile:
286 """ 287 Overview 288 ======== 289 This is just a small structure for keeping track of Connection Profiles. It only holds a name, host, 290 port, and user. I use it by having a dictionary of these, where the profile name is also the dictionary key. 291 """ 292
293 - def __init__ (self, name):
294 """ 295 @param name: The name of the profile. This can't be changed later. 296 @type name: string 297 """ 298 299 self._name = name 300 self._host = "" 301 self._port = "" 302 self._user = ""
303
304 - def setHost (self, host):
305 """ 306 @param host: The name of the host to be set. 307 @type host: string 308 """ 309 310 self._host = host
311
312 - def setPort (self, port):
313 """ 314 @param port: The port's number to be set. 315 @type port: string 316 """ 317 318 self._port = port
319
320 - def setUser (self, user):
321 """ 322 @param user: The name of the user to be set. 323 @type user: string 324 """ 325 326 self._user = user
327
328 - def getName (self):
329 """ 330 @return: string, the name of the profile. 331 """ 332 333 return self._name
334
335 - def getHost (self):
336 """ 337 @return: string, the name of the host. 338 """ 339 340 return self._host
341
342 - def getPort (self):
343 """ 344 @return: string, the port number. 345 """ 346 347 return self._port
348
349 - def getUser (self):
350 """ 351 @return: string, the name of the user. 352 """ 353 354 return self._user
355