1 #---------------------------------------------------------------------------- 
   3 # Purpose:      Subversion Service for pydocview 
   9 # Copyright:    (c) 2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  19 import sys        
# for errors 
  20 import traceback  
# for errors 
  23     import pysvn  
# python-subversion integration 
  31 #---------------------------------------------------------------------------- 
  33 #---------------------------------------------------------------------------- 
  34 SVN_CONFIG_DIR 
= "SVNConfigDir" 
  35 SVN_REPOSITORY_URL 
= "SVNRepositoryURLs" 
  41 #---------------------------------------------------------------------------- 
  43 #---------------------------------------------------------------------------- 
  45 class SVNService(wx
.lib
.pydocview
.DocService
): 
  46     SVN_UPDATE_ALL_ID 
= wx
.NewId() 
  47     SVN_UPDATE_ID 
= wx
.NewId() 
  48     SVN_CHECKIN_ID 
= wx
.NewId() 
  49     SVN_CHECKIN_ALL_ID 
= wx
.NewId() 
  50     SVN_CHECKOUT_ID 
= wx
.NewId() 
  51     SVN_REVERT_ID 
= wx
.NewId() 
  52     SVN_ADD_ID 
= wx
.NewId() 
  53     SVN_DELETE_ID 
= wx
.NewId() 
  54     SVN_COMMAND_LIST 
= [SVN_UPDATE_ALL_ID
, SVN_CHECKIN_ALL_ID
, SVN_UPDATE_ID
, SVN_CHECKIN_ID
, SVN_CHECKOUT_ID
, SVN_REVERT_ID
, SVN_ADD_ID
, SVN_DELETE_ID
] 
  58         self
._defaultURL 
= "svn://" 
  62             config 
= wx
.ConfigBase_Get() 
  64             configDir 
= config
.Read(SVN_CONFIG_DIR
, "") 
  65             self
._client 
= pysvn
.Client(configDir
) 
  67                 self
._defaultURL 
= self
._client
.info('.').url
 
  71             self
._client
.callback_cancel 
= self
.IfCancel
 
  72             self
._client
.callback_notify 
= self
.UpdateStatus
 
  73             self
._client
.callback_get_log_message 
= self
.GetLogMessage
 
  74             self
._client
.callback_get_login 
= self
.GetLogin
 
  75             self
._client
.callback_ssl_server_trust_prompt 
= self
.GetSSLServerTrust
 
  76             self
._client
.callback_ssl_client_cert_password_prompt 
= self
.SSLClientPassword
 
  77             self
._client
.callback_ssl_client_cert_prompt 
= self
.SSLClientCert
 
  78             self
._client
.callback_ssl_server_prompt 
= self
.SSLServerPrompt
 
  80     #---------------------------------------------------------------------------- 
  81     # pysvn.Client() Callback Methods 
  82     #---------------------------------------------------------------------------- 
  85         """ return True if user wants to cancel current command """ 
  89     def UpdateStatus(self
, eventDict
): 
  90         messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
  91         messageService
.ShowWindow() 
  93         view 
= messageService
.GetView() 
  94         view
.AddLines(_("%s %s\n") % (eventDict
['action'], eventDict
['path'])) 
  97     def GetLogMessage(self
): 
  98         dlg 
= wx
.TextEntryDialog(wx
.GetApp().GetTopWindow(), 
 100                 _("SVN Log Message")) 
 103         if dlg
.ShowModal() == wx
.ID_OK
: 
 105             message 
= dlg
.GetValue() 
 108             message 
= _("Cancel Action") 
 112         return retcode
, message
 
 115     def GetLogin(self
, realm
, username
, maySave
): 
 116         dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SVN Login")) 
 118         sizer 
= wx
.FlexGridSizer(cols 
= 2, hgap 
= 5, vgap 
= 5) 
 119         sizer
.Add(wx
.StaticText(dlg
, -1, _("Username:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 120         usernameTxt 
= wx
.TextCtrl(dlg
, -1, username
, size 
= (200, -1)) 
 121         sizer
.Add(usernameTxt
, 0, wx
.ALIGN_CENTER_VERTICAL
) 
 122         sizer
.Add(wx
.StaticText(dlg
, -1, _("Password:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 123         passwordTxt 
= wx
.TextCtrl(dlg
, -1, size
=(200, -1), style
=wx
.TE_PASSWORD
) 
 124         sizer
.Add(passwordTxt
, 0, wx
.ALIGN_CENTER_VERTICAL
) 
 126         savePasswordCheckbox 
= wx
.CheckBox(dlg
, -1, _("Remember Username and Password")) 
 128             savePasswordCheckbox
.Enable(False) 
 130         buttonSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 131         okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 133         buttonSizer
.Add(okBtn
, 0, wx
.RIGHT
, HALF_SPACE
) 
 134         buttonSizer
.Add(wx
.Button(dlg
, wx
.ID_CANCEL
), 0) 
 136         contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 137         contentSizer
.Add(sizer
, 0, wx
.LEFT|wx
.TOP|wx
.RIGHT
, SPACE
) 
 138         contentSizer
.Add(savePasswordCheckbox
, 0, wx
.TOP|wx
.LEFT|wx
.BOTTOM
, SPACE
) 
 139         contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 141         dlg
.SetSizer(contentSizer
) 
 146         if dlg
.ShowModal() == wx
.ID_OK
: 
 148             username 
= usernameTxt
.GetValue().strip() 
 149             password 
= passwordTxt
.GetValue() 
 150             save 
= savePasswordCheckbox
.IsChecked() 
 158         return retcode
, username
, password
, save
 
 161     def SSLServerPrompt(self
): 
 162         """ Not implemented, as per pysvn documentation """ 
 166     def GetSSLServerTrust(self
, trustDict
): 
 167         dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SSL Server Certificate")) 
 169         sizer 
= wx
.FlexGridSizer(cols 
= 2, hgap 
= 5, vgap 
= 5) 
 170         for k 
in ['hostname', 'valid_from', 'valid_to', 'issuer_dname', 'realm']: 
 171             if trustDict
.has_key(k
): 
 172                 sizer
.Add(wx
.StaticText(dlg
, -1, "%s:" % k
), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 173                 sizer
.Add(wx
.StaticText(dlg
, -1, "%s"  % trustDict
[k
]), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 175         box 
= wx
.StaticBoxSizer(wx
.StaticBox(dlg
, -1, _("Certificate Info")), wx
.VERTICAL
) 
 176         box
.Add(sizer
, 0, wx
.EXPAND
) 
 178         certRadio 
= wx
.RadioBox(dlg
, -1, _("Certificate"), choices
=[_("Accept Always"), _("Accept Once"), _("Reject")], majorDimension
=1, style
=wx
.RA_SPECIFY_COLS
) 
 180         buttonSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 181         okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 183         buttonSizer
.Add(okBtn
, 0, wx
.RIGHT
, HALF_SPACE
) 
 184         buttonSizer
.Add(wx
.Button(dlg
, wx
.ID_CANCEL
), 0) 
 186         contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 187         contentSizer
.Add(box
, 0, wx
.TOP|wx
.LEFT|wx
.RIGHT|wx
.EXPAND
, SPACE
) 
 188         contentSizer
.Add(certRadio
, 0, wx
.TOP|wx
.LEFT|wx
.RIGHT|wx
.BOTTOM|wx
.EXPAND
, SPACE
) 
 189         contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 191         dlg
.SetSizer(contentSizer
) 
 195         # default values for reject 
 201         if dlg
.ShowModal() == wx
.ID_OK
: 
 202             cert 
= certRadio
.GetStringSelection() 
 203             if cert 
== _("Accept Always"): 
 205                 acceptedFailures 
= trustDict
.get('failures') 
 207             elif cert 
== _("Accept Once"): 
 209                 acceptedFailures 
= trustDict
.get('failures') 
 213         return retcode
, acceptedFailures
, save
 
 216     def SSLClientPassword(self
, realm
, maySave
): 
 217         dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SSL Client Certificate Login")) 
 219         sizer 
= wx
.FlexGridSizer(cols 
= 2, hgap 
= 5, vgap 
= 5) 
 220         sizer
.Add(wx
.StaticText(dlg
, -1, _("Realm:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 221         sizer
.Add(wx
.StaticText(dlg
, -1, realm
), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 222         sizer
.Add(wx
.StaticText(dlg
, -1, _("Password:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 223         passwordTxt 
= wx
.TextCtrl(dlg
, -1, size
=(200, -1), style
=wx
.TE_PASSWORD
) 
 224         sizer
.Add(passwordTxt
, 0, wx
.ALIGN_CENTER_VERTICAL
) 
 226         savePasswordCheckbox 
= wx
.CheckBox(dlg
, -1, _("Remember Password")) 
 228             savePasswordCheckbox
.Enable(False) 
 230         buttonSizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 231         okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 233         buttonSizer
.Add(okBtn
, 0, wx
.RIGHT
, HALF_SPACE
) 
 234         buttonSizer
.Add(wx
.Button(dlg
, wx
.ID_CANCEL
), 0) 
 236         contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 237         contentSizer
.Add(sizer
, 0, wx
.LEFT|wx
.TOP|wx
.RIGHT
, SPACE
) 
 238         contentSizer
.Add(savePasswordCheckbox
, 0, wx
.TOP|wx
.LEFT|wx
.BOTTOM
, SPACE
) 
 239         contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 241         dlg
.SetSizer(contentSizer
) 
 246         if dlg
.ShowModal() == wx
.ID_OK
: 
 248             password 
= passwordTxt
.GetValue() 
 249             save 
= savePasswordCheckbox
.IsChecked() 
 256         return retcode
, password
, save
 
 259     def SSLClientCert(self
): 
 260         dlg 
= wx
.FileDialog(wx
.GetApp().GetTopWindow(), 
 261             message
="Choose certificate", 
 262             style
=wx
.OPEN|wx
.FILE_MUST_EXIST|wx
.CHANGE_DIR
 
 265         # dlg.CenterOnParent()  # wxBug: caused crash with wx.FileDialog 
 266         if dlg
.ShowModal() == wx
.ID_OK
: 
 268             certfile 
= dlg
.GetPath() 
 274         return retcode
, certfile
 
 278     #---------------------------------------------------------------------------- 
 280     #---------------------------------------------------------------------------- 
 282     def InstallControls(self
, frame
, menuBar 
= None, toolBar 
= None, statusBar 
= None, document 
= None): 
 283         menu 
= menuBar
.GetMenu(menuBar
.FindMenu(_("Project"))) 
 285         menu
.AppendSeparator() 
 287         wx
.EVT_MENU(frame
, SVNService
.SVN_UPDATE_ALL_ID
, self
.ProcessEvent
) 
 288         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_UPDATE_ALL_ID
, self
.ProcessUpdateUIEvent
) 
 289         menu
.Append(SVNService
.SVN_UPDATE_ALL_ID
, _("SVN Update All in Project"), _("Update all files in a project from Subversion")) 
 290         wx
.EVT_MENU(frame
, SVNService
.SVN_CHECKIN_ALL_ID
, self
.ProcessEvent
) 
 291         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_CHECKIN_ALL_ID
, self
.ProcessUpdateUIEvent
) 
 292         menu
.Append(SVNService
.SVN_CHECKIN_ALL_ID
, _("SVN Commit All in Project..."), _("Commit all files changes in a project to Subversion")) 
 293         wx
.EVT_MENU(frame
, SVNService
.SVN_UPDATE_ID
, self
.ProcessEvent
) 
 294         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_UPDATE_ID
, self
.ProcessUpdateUIEvent
) 
 295         menu
.Append(SVNService
.SVN_UPDATE_ID
, _("SVN Update"), _("Update file from Subversion")) 
 296         wx
.EVT_MENU(frame
, SVNService
.SVN_CHECKIN_ID
, self
.ProcessEvent
) 
 297         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_CHECKIN_ID
, self
.ProcessUpdateUIEvent
) 
 298         menu
.Append(SVNService
.SVN_CHECKIN_ID
, _("SVN Commit..."), _("Commit file changes to Subversion")) 
 299         wx
.EVT_MENU(frame
, SVNService
.SVN_CHECKOUT_ID
, self
.ProcessEvent
) 
 300         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_CHECKOUT_ID
, self
.ProcessUpdateUIEvent
) 
 301         menu
.Append(SVNService
.SVN_CHECKOUT_ID
, _("SVN Checkout..."), _("Checkout file from Subversion")) 
 302         wx
.EVT_MENU(frame
, SVNService
.SVN_REVERT_ID
, self
.ProcessEvent
) 
 303         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_REVERT_ID
, self
.ProcessUpdateUIEvent
) 
 304         menu
.Append(SVNService
.SVN_REVERT_ID
, _("SVN Revert"), _("Revert file from Subversion")) 
 306         menu
.AppendSeparator() 
 308         wx
.EVT_MENU(frame
, SVNService
.SVN_ADD_ID
, self
.ProcessEvent
) 
 309         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_ADD_ID
, self
.ProcessUpdateUIEvent
) 
 310         menu
.Append(SVNService
.SVN_ADD_ID
, _("SVN Add"), _("Add file to Subversion")) 
 311         wx
.EVT_MENU(frame
, SVNService
.SVN_DELETE_ID
, self
.ProcessEvent
) 
 312         wx
.EVT_UPDATE_UI(frame
, SVNService
.SVN_DELETE_ID
, self
.ProcessUpdateUIEvent
) 
 313         menu
.Append(SVNService
.SVN_DELETE_ID
, _("SVN Delete"), _("Delete file from Subversion")) 
 316     def ProcessEvent(self
, event
): 
 320         if not SVN_INSTALLED
: 
 321             if id in SVNService
.SVN_COMMAND_LIST
: 
 322                 wx
.MessageBox(_("pysvn not found.  Please install pysvn"), _("Python Subversion")) 
 328             if id == SVNService
.SVN_UPDATE_ID
: 
 329                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 331                 filenames 
= self
.GetCurrentDocuments() 
 333                     filenames 
= filenames
[:] 
 334                     filenames
.sort(self
.BasenameCaseInsensitiveCompare
) 
 336                     folderPath 
= self
.GetCurrentFolder() 
 338                         filenames 
= [folderPath
] 
 340                 messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 341                 messageService
.ShowWindow() 
 343                 view 
= messageService
.GetView() 
 345                 view
.AddLines(_("SVN Update:\n")) 
 347                 for filename 
in filenames
: 
 348                     view
.AddLines("%s\n" % filename
) 
 350                         status 
= self
._client
.update(filename
) 
 352                         if status
.number 
> 0: 
 353                             view
.AddLines(_("Updated to revision %s\n") % status
.number
) 
 355                             openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 357                                 if doc
.GetFilename() == filename
: 
 358                                     yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 359                                                              _("Updated file '%s' is currently open.  Close it?") % os
.path
.basename(filename
), 
 361                                                              wx
.YES_NO|wx
.ICON_QUESTION
) 
 362                                     yesNoMsg
.CenterOnParent() 
 363                                     status 
= yesNoMsg
.ShowModal() 
 365                                     if status 
== wx
.ID_YES
: 
 369                             view
.AddLines(_("Update failed.\n")) 
 371                     except pysvn
.ClientError
, e
: 
 372                         view
.AddLines("%s\n" % str(e
)) 
 373                         wx
.MessageBox(str(e
), _("SVN Update"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 375                         extype
, ex
, tb 
= sys
.exc_info() 
 376                         view
.AddLines("Update failed: (%s) %s\n" % (extype
, str(ex
))) 
 377                         for line 
in traceback
.format_tb(tb
): 
 380                         wx
.MessageBox(_("Update failed."), _("SVN Update"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 382                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 386             elif id == SVNService
.SVN_UPDATE_ALL_ID
: 
 387                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 389                 messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 390                 messageService
.ShowWindow() 
 392                 view 
= messageService
.GetView() 
 394                 view
.AddLines(_("SVN Update:\n")) 
 396                 project 
= self
.GetCurrentProject() 
 398                     openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 400                         if doc
.GetFilename() == project
: 
 401                             filenames 
= doc
.GetFiles()[:]  # make a copy and sort it. 
 402                             filenames
.sort(self
.BasenameCaseInsensitiveCompare
) 
 404                             for filename 
in filenames
: 
 405                                 view
.AddLines("%s\n" % filename
) 
 407                                     status 
= self
._client
.update(filename
) 
 409                                     if status
.number 
> 0: 
 410                                         view
.AddLines(_("Updated to revision %s\n") % status
.number
) 
 412                                         openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 414                                             if doc
.GetFilename() == filename
: 
 415                                                 yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 416                                                                          _("Updated file '%s' is currently open.  Close it?") % os
.path
.basename(filename
), 
 418                                                                          wx
.YES_NO|wx
.CANCEL|wx
.ICON_QUESTION
) 
 419                                                 yesNoMsg
.CenterOnParent() 
 420                                                 status 
= yesNoMsg
.ShowModal() 
 422                                                 if status 
== wx
.ID_YES
: 
 424                                                 elif status 
== wx
.ID_NO
: 
 426                                                 else: # elif status == wx.CANCEL: 
 427                                                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 431                                         view
.AddLines(_("Update failed.\n")) 
 433                                 except pysvn
.ClientError
, e
: 
 434                                     view
.AddLines("%s\n" % str(e
)) 
 435                                     wx
.MessageBox(str(e
), _("SVN Update"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 437                                     extype
, ex
, tb 
= sys
.exc_info() 
 438                                     view
.AddLines("Update failed: (%s) %s\n" % (extype
, str(ex
))) 
 439                                     for line 
in traceback
.format_tb(tb
): 
 442                                     wx
.MessageBox(_("Update failed."), _("SVN Update"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 444                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 447             elif id == SVNService
.SVN_CHECKIN_ALL_ID
: 
 449                 project 
= self
.GetCurrentProject() 
 451                     openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 453                         if doc
.GetFilename() == project
: 
 454                             for filename 
in doc
.GetFiles(): 
 455                                 if filename 
not in filenames
: 
 456                                     filenames
.append(filename
) 
 457                 filenames
.sort(self
.BasenameCaseInsensitiveCompare
) 
 459                 # ask user if dirty files should be saved first 
 460                 openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 461                 for filename 
in filenames
: 
 463                         if doc
.GetFilename() == filename 
and doc
.IsModified(): 
 464                             yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 465                                                      _("'%s' has unsaved modifications.  Save it before commit?") % os
.path
.basename(filename
), 
 467                                                      wx
.YES_NO|wx
.CANCEL|wx
.ICON_QUESTION
) 
 468                             yesNoMsg
.CenterOnParent() 
 469                             status 
= yesNoMsg
.ShowModal() 
 471                             if status 
== wx
.ID_YES
: 
 473                             elif status 
== wx
.ID_NO
: 
 475                             else: # elif status == wx.CANCEL: 
 480                 for i
, filename 
in enumerate(filenames
): 
 481                     shortFilename 
= os
.path
.basename(filename
) 
 482                     shortFilenames
.append(shortFilename
) 
 484                 dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SVN Commit")) 
 486                 sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 487                 sizer
.Add(wx
.StaticText(dlg
, -1, _("Comment:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 488                 commentText 
= wx
.TextCtrl(dlg
, -1, size
=(250,-1), style
=wx
.TE_MULTILINE
) 
 489                 sizer
.Add(commentText
, 1, wx
.EXPAND|wx
.TOP
, HALF_SPACE
) 
 491                 sizer
.Add(wx
.StaticText(dlg
, -1, _("Files:")), 0, wx
.ALIGN_CENTER_VERTICAL|wx
.TOP
, SPACE
) 
 492                 fileList 
= wx
.CheckListBox(dlg
, -1, choices 
= shortFilenames
) 
 493                 for i 
in range(fileList
.GetCount()): 
 494                     fileList
.Check(i
, True) 
 495                 sizer
.Add(fileList
, 0, wx
.EXPAND|wx
.TOP
, HALF_SPACE
) 
 497                 buttonSizer 
= wx
.StdDialogButtonSizer() 
 498                 okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 500                 buttonSizer
.AddButton(okBtn
) 
 501                 buttonSizer
.AddButton(wx
.Button(dlg
, wx
.ID_CANCEL
)) 
 502                 buttonSizer
.Realize() 
 504                 contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 505                 contentSizer
.Add(sizer
, 0, wx
.ALL
, SPACE
) 
 506                 contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 508                 dlg
.SetSizer(contentSizer
) 
 513                 if dlg
.ShowModal() == wx
.ID_OK
: 
 514                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 516                     messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 517                     messageService
.ShowWindow() 
 519                     view 
= messageService
.GetView() 
 521                     view
.AddLines(_("SVN Commit:\n")) 
 525                         for i 
in range(fileList
.GetCount()): 
 526                             if fileList
.IsChecked(i
): 
 527                                 selFilenames
.append(filenames
[i
]) 
 528                                 view
.AddLines("%s\n" % filenames
[i
]) 
 530                         if len(selFilenames
): 
 531                             comment 
= commentText
.GetValue() 
 532                             status 
= self
._client
.checkin(selFilenames
, comment
) 
 535                                 view
.AddLines(_("Nothing to commit.\n")) 
 536                             elif status
.number 
> 0: 
 537                                 view
.AddLines(_("Committed as revision %s.\n") % status
.number
) 
 539                                 view
.AddLines(_("Commit failed.\n")) 
 541                     except pysvn
.ClientError
, e
: 
 542                         view
.AddLines("%s\n" % str(e
)) 
 543                         wx
.MessageBox(str(e
), _("SVN Commit"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 545                         extype
, ex
, tb 
= sys
.exc_info() 
 546                         view
.AddLines("Commit failed: (%s) %s\n" % (extype
, str(ex
))) 
 547                         for line 
in traceback
.format_tb(tb
): 
 549                         wx
.MessageBox(_("Commit failed."), _("SVN Commit"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 551                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 556             elif id == SVNService
.SVN_CHECKIN_ID
: 
 557                 filenames 
= self
.GetCurrentDocuments()[:] 
 558                 filenames
.sort(self
.BasenameCaseInsensitiveCompare
)             
 560                 # ask user if dirty files should be saved first 
 561                 openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 562                 for filename 
in filenames
: 
 564                         if doc
.GetFilename() == filename 
and doc
.IsModified(): 
 565                             yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 566                                                      _("'%s' has unsaved modifications.  Save it before commit?") % os
.path
.basename(filename
), 
 568                                                      wx
.YES_NO|wx
.CANCEL|wx
.ICON_QUESTION
) 
 569                             yesNoMsg
.CenterOnParent() 
 570                             status 
= yesNoMsg
.ShowModal() 
 572                             if status 
== wx
.ID_YES
: 
 574                             elif status 
== wx
.ID_NO
: 
 576                             else: # elif status == wx.CANCEL: 
 581                 for i
, filename 
in enumerate(filenames
): 
 582                     shortFilename 
= os
.path
.basename(filename
) 
 583                     shortFilenames
.append(shortFilename
) 
 585                 dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SVN Commit")) 
 587                 sizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 588                 sizer
.Add(wx
.StaticText(dlg
, -1, _("Comment:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 589                 commentText 
= wx
.TextCtrl(dlg
, -1, size
=(250,-1), style
=wx
.TE_MULTILINE
) 
 590                 sizer
.Add(commentText
, 1, wx
.EXPAND|wx
.TOP
, HALF_SPACE
) 
 592                 sizer
.Add(wx
.StaticText(dlg
, -1, _("Files:")), 0, wx
.ALIGN_CENTER_VERTICAL|wx
.TOP
, SPACE
) 
 593                 fileList 
= wx
.CheckListBox(dlg
, -1, choices 
= shortFilenames
) 
 594                 for i 
in range(fileList
.GetCount()): 
 595                     fileList
.Check(i
, True) 
 596                 sizer
.Add(fileList
, 0, wx
.EXPAND|wx
.TOP
, HALF_SPACE
) 
 598                 buttonSizer 
= wx
.StdDialogButtonSizer() 
 599                 okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 601                 buttonSizer
.AddButton(okBtn
) 
 602                 buttonSizer
.AddButton(wx
.Button(dlg
, wx
.ID_CANCEL
)) 
 603                 buttonSizer
.Realize() 
 605                 contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 606                 contentSizer
.Add(sizer
, 0, wx
.ALL
, SPACE
) 
 607                 contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 609                 dlg
.SetSizer(contentSizer
) 
 614                 if dlg
.ShowModal() == wx
.ID_OK
: 
 615                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 617                     messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 618                     messageService
.ShowWindow() 
 620                     view 
= messageService
.GetView() 
 622                     view
.AddLines(_("SVN Commit:\n")) 
 626                         for i 
in range(fileList
.GetCount()): 
 627                             if fileList
.IsChecked(i
): 
 628                                 selFilenames
.append(filenames
[i
]) 
 629                                 view
.AddLines("%s\n" % filenames
[i
]) 
 631                         if len(selFilenames
): 
 632                             comment 
= commentText
.GetValue() 
 633                             status 
= self
._client
.checkin(selFilenames
, comment
) 
 636                                 view
.AddLines(_("Nothing to commit.\n")) 
 637                             elif status
.number 
> 0: 
 638                                 view
.AddLines(_("Committed as revision %s.\n") % status
.number
) 
 640                                 view
.AddLines(_("Commit failed.\n")) 
 642                     except pysvn
.ClientError
, e
: 
 643                         view
.AddLines("%s\n" % str(e
)) 
 644                         wx
.MessageBox(str(e
), _("SVN Commit"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 646                         extype
, ex
, tb 
= sys
.exc_info() 
 647                         view
.AddLines("Commit failed: (%s) %s\n" % (extype
, str(ex
))) 
 648                         for line 
in traceback
.format_tb(tb
): 
 650                         wx
.MessageBox(_("Commit failed."), _("SVN Commit"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 652                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 656             elif id == SVNService
.SVN_CHECKOUT_ID
: 
 657                 config 
= wx
.ConfigBase_Get() 
 658                 svnUrl 
= config
.Read(SVN_REPOSITORY_URL
, self
._defaultURL
) 
 660                 dlg 
= wx
.Dialog(wx
.GetApp().GetTopWindow(), -1, _("SVN Checkout")) 
 662                 gridSizer 
= wx
.FlexGridSizer(cols 
= 2, hgap 
= 5, vgap 
= 5) 
 663                 gridSizer
.Add(wx
.StaticText(dlg
, -1, _("Repository URL:")), 0, wx
.ALIGN_CENTER_VERTICAL|wx
.RIGHT|wx
.TOP
, HALF_SPACE
) 
 664                 svnUrlList 
= ReadSvnUrlList() 
 665                 svnURLCombobox 
= wx
.ComboBox(dlg
, -1, size
=(200, -1), choices
=svnUrlList
, style
=wx
.CB_DROPDOWN
) 
 667                     svnURLCombobox
.SetToolTipString(svnUrlList
[0]) 
 668                     svnURLCombobox
.SetStringSelection(svnUrlList
[0]) 
 670                     svnURLCombobox
.SetToolTipString(_("Set Repository URL")) 
 671                 gridSizer
.Add(svnURLCombobox
, 0) 
 673                 gridSizer
.Add(wx
.StaticText(dlg
, -1, _("Checkout to dir:")), 0, wx
.ALIGN_CENTER_VERTICAL|wx
.RIGHT|wx
.TOP
, HALF_SPACE
) 
 674                 localPath 
= wx
.TextCtrl(dlg
, -1, size 
= (200, -1)) 
 675                 localPath
.SetToolTipString(_("Path in local file system where files will be located.")) 
 676                 findDirButton 
= wx
.Button(dlg
, -1, _("Browse...")) 
 678                 def OnBrowseButton(event
): 
 679                     dirDlg 
= wx
.DirDialog(wx
.GetApp().GetTopWindow(), _("Choose a directory:"), style
=wx
.DD_DEFAULT_STYLE
) 
 680                     dir = localPath
.GetValue() 
 683                     dirDlg
.CenterOnParent() 
 684                     if dirDlg
.ShowModal() == wx
.ID_OK
: 
 685                         localPath
.SetValue(dirDlg
.GetPath()) 
 686                         localPath
.SetToolTipString(localPath
.GetValue()) 
 687                         localPath
.SetInsertionPointEnd() 
 689                 wx
.EVT_BUTTON(findDirButton
, -1, OnBrowseButton
) 
 691                 sizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 692                 sizer
.Add(localPath
, 1, wx
.EXPAND
) 
 693                 sizer
.Add(findDirButton
, 0, wx
.LEFT
, HALF_SPACE
) 
 694                 gridSizer
.Add(sizer
, 0) 
 696                 buttonSizer 
= wx
.StdDialogButtonSizer() 
 697                 okBtn 
= wx
.Button(dlg
, wx
.ID_OK
) 
 699                 buttonSizer
.AddButton(okBtn
) 
 700                 buttonSizer
.AddButton(wx
.Button(dlg
, wx
.ID_CANCEL
)) 
 701                 buttonSizer
.Realize() 
 703                 contentSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 704                 contentSizer
.Add(gridSizer
, 0, wx
.ALL
, SPACE
) 
 705                 contentSizer
.Add(buttonSizer
, 0, wx
.ALL|wx
.ALIGN_RIGHT
, SPACE
) 
 707                 dlg
.SetSizer(contentSizer
) 
 712                 if dlg
.ShowModal() == wx
.ID_OK
: 
 713                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 715                     WriteSvnUrlList(svnURLCombobox
) 
 717                     messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 718                     messageService
.ShowWindow() 
 720                     view 
= messageService
.GetView() 
 722                     view
.AddLines(_("SVN Checkout:\n")) 
 724                     svnUrl 
= svnURLCombobox
.GetValue() 
 725                     toLocation 
= localPath
.GetValue() 
 727                         self
._client
.checkout(svnUrl
, toLocation
) 
 728                         view
.AddLines(_("Checkout completed.\n")) 
 729                     except pysvn
.ClientError
, e
: 
 730                         view
.AddLines(_("Checkout failed.  %s\n") % str(e
)) 
 731                         wx
.MessageBox(_("Checkout failed.  %s") % str(e
), _("SVN Checkout"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 733                         extype
, ex
, tb 
= sys
.exc_info() 
 734                         view
.AddLines("Checkout failed: (%s) %s\n" % (extype
, str(ex
))) 
 735                         for line 
in traceback
.format_tb(tb
): 
 737                         wx
.MessageBox(_("Checkout failed."), _("SVN Checkout"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 739                     wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 743             elif id == SVNService
.SVN_REVERT_ID
: 
 744                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 746                 filenames 
= self
.GetCurrentDocuments() 
 748                 messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 749                 messageService
.ShowWindow() 
 751                 view 
= messageService
.GetView() 
 753                 view
.AddLines(_("SVN Revert:\n")) 
 754                 for filename 
in filenames
: 
 755                     view
.AddLines("%s\n" % filename
) 
 758                     self
._client
.revert(filenames
) 
 759                     view
.AddLines(_("Revert completed.\n")) 
 761                     openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 762                     for doc 
in openDocs
[:]:   # need to make a copy of the list otherwise ordinality changes as we close the files 
 763                         if doc
.GetFilename() in filenames
: 
 764                             yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 765                                                      _("Reverted file '%s' is currently open.  Close it?") % os
.path
.basename(doc
.GetFilename()), 
 767                                                      wx
.YES_NO|wx
.ICON_QUESTION
) 
 768                             yesNoMsg
.CenterOnParent() 
 769                             status 
= yesNoMsg
.ShowModal() 
 771                             if status 
== wx
.ID_YES
: 
 774                 except pysvn
.ClientError
, e
: 
 775                     view
.AddLines("%s\n" % str(e
)) 
 776                     wx
.MessageBox(str(e
), _("SVN Revert"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 778                     extype
, ex
, tb 
= sys
.exc_info() 
 779                     view
.AddLines("Revert failed: (%s) %s\n" % (extype
, str(ex
))) 
 780                     for line 
in traceback
.format_tb(tb
): 
 782                     wx
.MessageBox(_("Revert failed."), _("SVN Revert"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 784                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 787             elif id == SVNService
.SVN_ADD_ID
: 
 788                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 790                 filenames 
= self
.GetCurrentDocuments() 
 792                 messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 793                 messageService
.ShowWindow() 
 795                 view 
= messageService
.GetView() 
 797                 view
.AddLines(_("SVN Add:\n")) 
 798                 for filename 
in filenames
: 
 799                     view
.AddLines("%s\n" % filename
) 
 802                     self
._client
.add(filenames
) 
 803                     view
.AddLines(_("Add completed.\n")) 
 804                 except pysvn
.ClientError
, e
: 
 805                     view
.AddLines("%s\n" % str(e
)) 
 806                     wx
.MessageBox(str(e
), _("SVN Add"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 808                     extype
, ex
, tb 
= sys
.exc_info() 
 809                     view
.AddLines("Add failed: (%s) %s\n" % (extype
, str(ex
))) 
 810                     for line 
in traceback
.format_tb(tb
): 
 812                     wx
.MessageBox(_("Add failed."), _("SVN Add"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 814                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 817             elif id == SVNService
.SVN_DELETE_ID
: 
 818                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_WAIT
)) 
 820                 filenames 
= self
.GetCurrentDocuments() 
 822                 messageService 
= wx
.GetApp().GetService(MessageService
.MessageService
) 
 823                 messageService
.ShowWindow() 
 825                 view 
= messageService
.GetView() 
 827                 view
.AddLines(_("SVN Delete:\n")) 
 828                 for filename 
in filenames
: 
 829                     view
.AddLines("%s\n" % filename
) 
 832                     self
._client
.remove(filenames
) 
 833                     view
.AddLines(_("Delete completed.\n")) 
 834                 except pysvn
.ClientError
, e
: 
 835                     view
.AddLines("%s\n" % str(e
)) 
 836                     wx
.MessageBox(str(e
), _("SVN Delete"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 838                     extype
, ex
, tb 
= sys
.exc_info() 
 839                     view
.AddLines("Delete failed: (%s) %s\n" % (extype
, str(ex
))) 
 840                     for line 
in traceback
.format_tb(tb
): 
 842                     wx
.MessageBox(_("Delete failed."), _("SVN Delete"), wx
.OK | wx
.ICON_EXCLAMATION
) 
 844                 wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 849             wx
.GetApp().GetTopWindow().SetCursor(wx
.StockCursor(wx
.CURSOR_DEFAULT
)) 
 852     def ProcessUpdateUIEvent(self
, event
): 
 855         if id in [SVNService
.SVN_CHECKIN_ID
, 
 856                   SVNService
.SVN_REVERT_ID
, 
 857                   SVNService
.SVN_ADD_ID
, 
 858                   SVNService
.SVN_DELETE_ID
]: 
 859             if self
.GetCurrentDocuments(): 
 865         elif id == SVNService
.SVN_UPDATE_ID
: 
 866             if self
.GetCurrentDocuments() or self
.GetCurrentFolder(): 
 872         elif id == SVNService
.SVN_CHECKOUT_ID
: 
 876         elif (id == SVNService
.SVN_UPDATE_ALL_ID
 
 877         or id == SVNService
.SVN_CHECKIN_ALL_ID
): 
 878             if self
.GetCurrentProject(): 
 887     def GetCurrentProject(self
): 
 888         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 890             projView 
= projectService
.GetView() 
 891             return projView
.GetSelectedProject() 
 895     def GetCurrentDocuments(self
): 
 896         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 898             projView 
= projectService
.GetView() 
 900             if projView
.FilesHasFocus(): 
 901                 filenames 
= projView
.GetSelectedFiles() 
 907         doc 
= wx
.GetApp().GetTopWindow().GetDocumentManager().GetCurrentDocument() 
 909             filenames 
= [doc
.GetFilename()] 
 916     def GetCurrentFolder(self
): 
 917         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 919             projView 
= projectService
.GetView() 
 921             if projView
.FilesHasFocus(): 
 922                 folderPath 
= projView
.GetSelectedPhysicalFolder() 
 929     def BasenameCaseInsensitiveCompare(self
, s1
, s2
): 
 930         s1L 
= os
.path
.basename(s1
).lower() 
 931         s2L 
= os
.path
.basename(s2
).lower() 
 940 class SVNOptionsPanel(wx
.Panel
): 
 943     def __init__(self
, parent
, id): 
 944         wx
.Panel
.__init
__(self
, parent
, id) 
 946         config 
= wx
.ConfigBase_Get() 
 947         configDir 
= config
.Read(SVN_CONFIG_DIR
, "") 
 949         borderSizer 
= wx
.BoxSizer(wx
.VERTICAL
) 
 950         sizer 
= wx
.FlexGridSizer(cols 
= 2, hgap 
= 5, vgap 
= 5) 
 951         sizer
.AddGrowableCol(1, 1) 
 953         sizer
.Add(wx
.StaticText(self
, -1, _("SVN Config Dir:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 955         self
._svnConfigDir 
= wx
.TextCtrl(self
, -1, configDir
, size 
= (200, -1)) 
 957             self
._svnConfigDir
.SetToolTipString(_("Path Subversion configuration directory.")) 
 959             self
._svnConfigDir
.SetToolTipString(configDir
) 
 961         findDirButton 
= wx
.Button(self
, -1, _("Browse...")) 
 963         def OnBrowseButton(event
): 
 964             dirDlg 
= wx
.DirDialog(self
, _("Choose a directory:"), style
=wx
.DD_DEFAULT_STYLE
) 
 965             dir = self
._svnConfigDir
.GetValue() 
 968             dirDlg
.CenterOnParent() 
 969             if dirDlg
.ShowModal() == wx
.ID_OK
: 
 970                 self
._svnConfigDir
.SetValue(dirDlg
.GetPath()) 
 971                 self
._svnConfigDir
.SetToolTipString(self
._svnConfigDir
.GetValue()) 
 972                 self
._svnConfigDir
.SetInsertionPointEnd() 
 974         wx
.EVT_BUTTON(findDirButton
, -1, OnBrowseButton
) 
 976         hsizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
 977         hsizer
.Add(self
._svnConfigDir
, 1, wx
.EXPAND
) 
 978         hsizer
.Add(findDirButton
, 0, wx
.LEFT
, HALF_SPACE
) 
 979         sizer
.Add(hsizer
, 0, wx
.EXPAND
) 
 982         svnUrlList 
= ReadSvnUrlList() 
 983         sizer
.Add(wx
.StaticText(self
, -1, _("SVN URL:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 984         self
._svnURLCombobox 
= wx
.ComboBox(self
, -1, size
=(200, -1), choices
=svnUrlList
, style
=wx
.CB_DROPDOWN
) 
 986             self
._svnURLCombobox
.SetToolTipString(svnUrlList
[0]) 
 987             self
._svnURLCombobox
.SetStringSelection(svnUrlList
[0]) 
 989             self
._svnURLCombobox
.SetToolTipString(_("Set Repository URL")) 
 990         sizer
.Add(self
._svnURLCombobox
, 0, wx
.EXPAND
) 
 993         sizer
.Add(wx
.StaticText(self
, -1, _("SVN_SSH:")), 0, wx
.ALIGN_CENTER_VERTICAL
) 
 994         svnSSH 
= os
.getenv("SVN_SSH") 
 995         if not svnSSH 
or svnSSH 
== "": 
 996             self
._svnSSH 
= wx
.TextCtrl(self
, -1, size 
= (200, -1)) 
 998             self
._svnSSH 
= wx
.TextCtrl(self
, -1, svnSSH
, size 
= (200, -1)) 
 999         self
._svnSSH
.SetToolTipString(_("Override SVN_SSH environment variable temporarily.")) 
1001         findSSHButton 
= wx
.Button(self
, -1, _("Browse...")) 
1003         def OnBrowseFileButton(event
): 
1004             dirDlg 
= wx
.FileDialog(self
, _("Choose a file:"), style
=wx
.OPEN|wx
.CHANGE_DIR
) 
1005             # dirDlg.CenterOnParent()  # wxBug: caused crash with wx.FileDialog 
1006             if dirDlg
.ShowModal() == wx
.ID_OK
: 
1007                 self
._svnSSH
.SetValue(dirDlg
.GetPath()) 
1008                 self
._svnSSH
.SetToolTipString(self
._svnSSH
.GetValue()) 
1009                 self
._svnSSH
.SetInsertionPointEnd() 
1011         wx
.EVT_BUTTON(findSSHButton
, -1, OnBrowseFileButton
) 
1013         hsizer 
= wx
.BoxSizer(wx
.HORIZONTAL
) 
1014         hsizer
.Add(self
._svnSSH
, 1, wx
.EXPAND
) 
1015         hsizer
.Add(findSSHButton
, 0, wx
.LEFT
, HALF_SPACE
) 
1016         sizer
.Add(hsizer
, 0, wx
.EXPAND
) 
1019         borderSizer
.Add(sizer
, 0, wx
.ALL|wx
.EXPAND
, SPACE
) 
1020         self
.SetSizer(borderSizer
) 
1022         parent
.AddPage(self
, _("SVN")) 
1029     def OnOK(self
, optionsDialog
): 
1030         config 
= wx
.ConfigBase_Get() 
1032         config
.Write(SVN_CONFIG_DIR
, self
._svnConfigDir
.GetValue()) 
1034         WriteSvnUrlList(self
._svnURLCombobox
) 
1036         os
.environ
["SVN_SSH"] = self
._svnSSH
.GetValue() 
1039 def ReadSvnUrlList(): 
1040     """ Read in list of SNV repository URLs.  First in list is the last one path used. """ 
1041     config 
= wx
.ConfigBase_Get() 
1042     urlStringList 
= config
.Read(SVN_REPOSITORY_URL
) 
1043     if len(urlStringList
): 
1044         urlList 
= eval(urlStringList
) 
1047     if len(urlList
) == 0: 
1048         svnService 
= wx
.GetApp().GetService(SVNService
) 
1049         if svnService 
and hasattr(svnService
, "_defaultURL"): 
1050             urlList
.append(svnService
._defaultURL
) 
1054 def WriteSvnUrlList(comboBox
): 
1055     """ Save out list of SVN repository URLs from combobox.  Put on top the current selection.  Only save out first 10 from the list """ 
1058     url 
= comboBox
.GetValue() 
1062     for i 
in range(min(comboBox
.GetCount(), 10)): 
1063         url 
= comboBox
.GetString(i
) 
1064         if url 
not in urlList
: 
1067     config 
= wx
.ConfigBase_Get() 
1068     config
.Write(SVN_REPOSITORY_URL
, urlList
.__repr
__())