]> git.saurik.com Git - wxWidgets.git/blame - wxPython/samples/ide/activegrid/tool/SVNService.py
Applied patch [ 1212020 ] MediaCtrl DirectShow drawing and sample
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / SVNService.py
CommitLineData
6f1a3f9c
RD
1#----------------------------------------------------------------------------
2# Name: SVNService.py
3# Purpose: Subversion Service for pydocview
4#
5# Author: Morgan Hua
6#
7# Created: 5/13/05
8# CVS-ID: $Id$
9# Copyright: (c) 2005 ActiveGrid, Inc.
10# License: wxWindows License
11#----------------------------------------------------------------------------
12
13import wx
14import os.path
15import ProjectEditor
16import MessageService
17
18import sys # for errors
19import traceback # for errors
20
21try:
22 import pysvn # python-subversion integration
23 SVN_INSTALLED = True
24except ImportError:
25 SVN_INSTALLED = False
26
27_ = wx.GetTranslation
28
29
30#----------------------------------------------------------------------------
31# Constants
32#----------------------------------------------------------------------------
33SVN_CONFIG_DIR = "SVNConfigDir"
34SVN_REPOSITORY_URL = "SVNRepositoryURL"
35
36SPACE = 10
37HALF_SPACE = 5
38
39
40#----------------------------------------------------------------------------
41# Classes
42#----------------------------------------------------------------------------
43
44class SVNService(wx.lib.pydocview.DocService):
45 SVN_UPDATE_ID = wx.NewId()
46 SVN_CHECKIN_ID = wx.NewId()
47 SVN_CHECKOUT_ID = wx.NewId()
48 SVN_REVERT_ID = wx.NewId()
49 SVN_ADD_ID = wx.NewId()
50 SVN_DELETE_ID = wx.NewId()
51 SVN_COMMAND_LIST = [SVN_UPDATE_ID, SVN_CHECKIN_ID, SVN_CHECKOUT_ID, SVN_REVERT_ID, SVN_ADD_ID, SVN_DELETE_ID]
52
53
54 def __init__(self):
55 self._defaultURL = "svn://"
56
57 global SVN_INSTALLED
58 if SVN_INSTALLED:
59 config = wx.ConfigBase_Get()
60 configDir = config.Read(SVN_CONFIG_DIR, "")
61
62 self._client = pysvn.Client(configDir)
63 try:
64 self._defaultURL = self._client.info('.').url
65 except:
66 pass
67 self._client.callback_cancel = self.IfCancel
68 self._client.callback_notify = self.UpdateStatus
69 self._client.callback_get_log_message = self.GetLogMessage
70 self._client.callback_get_login = self.GetLogin
71 self._client.callback_ssl_server_trust_prompt = self.GetSSLServerTrust
72 self._client.callback_ssl_client_cert_password_prompt = self.SSLClientPassword
73 self._client.callback_ssl_client_cert_prompt = self.SSLClientCert
74 self._client.callback_ssl_server_prompt = self.SSLServerPrompt
75
76 #----------------------------------------------------------------------------
77 # pysvn.Client() Callback Methods
78 #----------------------------------------------------------------------------
79
80 def IfCancel(self):
81 """ return True if user wants to cancel current command """
82 return False
83
84
85 def UpdateStatus(self, eventDict):
86 messageService = wx.GetApp().GetService(MessageService.MessageService)
87 messageService.ShowWindow()
88
89 view = messageService.GetView()
90 view.AddLines(_("%s %s\n") % (eventDict['action'], eventDict['path']))
91
92
93 def GetLogMessage(self):
94 dlg = wx.TextEntryDialog(wx.GetApp().GetTopWindow(),
95 _("Comment"),
96 _("SVN Log Message"))
97
98 if dlg.ShowModal() == wx.ID_OK:
99 retcode = True
100 message = dlg.GetValue()
101 else:
102 retcode = False
103 message = _("Cancel Action")
104
105 dlg.Destroy()
106
107 return retcode, message
108
109
110 def GetLogin(self, realm, username, maySave):
111 dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Login"))
112
113 sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
114 sizer.Add(wx.StaticText(dlg, -1, _("Username:")), 0, wx.ALIGN_CENTER_VERTICAL)
115 usernameTxt = wx.TextCtrl(dlg, -1, username, size = (200, -1))
116 sizer.Add(usernameTxt, 0, wx.ALIGN_CENTER_VERTICAL)
117 sizer.Add(wx.StaticText(dlg, -1, _("Password:")), 0, wx.ALIGN_CENTER_VERTICAL)
118 passwordTxt = wx.TextCtrl(dlg, -1, size=(200, -1), style=wx.TE_PASSWORD)
119 sizer.Add(passwordTxt, 0, wx.ALIGN_CENTER_VERTICAL)
120
121 savePasswordCheckbox = wx.CheckBox(dlg, -1, _("Remember Username and Password"))
122 if not maySave:
123 savePasswordCheckbox.Enable(False)
124
125 buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
126 okBtn = wx.Button(dlg, wx.ID_OK)
127 okBtn.SetDefault()
128 buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
129 buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
130
131 contentSizer = wx.BoxSizer(wx.VERTICAL)
132 contentSizer.Add(sizer, 0, wx.LEFT|wx.TOP|wx.RIGHT, SPACE)
133 contentSizer.Add(savePasswordCheckbox, 0, wx.TOP|wx.LEFT|wx.BOTTOM, SPACE)
134 contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
135
136 dlg.SetSizer(contentSizer)
137 dlg.Fit()
138 dlg.Layout()
139
140 if dlg.ShowModal() == wx.ID_OK:
141 retcode = True
142 username = usernameTxt.GetValue().strip()
143 password = passwordTxt.GetValue()
144 save = savePasswordCheckBox.IsChecked()
145 else:
146 retcode = False
147 username = None
148 password = None
149 save = False
150
151 dlg.Destroy()
152 return retcode, username, password, save
153
154
155 def SSLServerPrompt(self):
156 """ Not implemented, as per pysvn documentation """
157 return
158
159
160 def GetSSLServerTrust(self, trustDict):
161 dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SSL Server Certificate"))
162
163 sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
164 for k in ['hostname', 'valid_from', 'valid_to', 'issuer_dname', 'realm']:
165 if trustDict.has_key(k):
166 sizer.Add(wx.StaticText(dlg, -1, "%s:" % k), 0, wx.ALIGN_CENTER_VERTICAL)
167 sizer.Add(wx.StaticText(dlg, -1, "%s" % trustDict[k]), 0, wx.ALIGN_CENTER_VERTICAL)
168
169 box = wx.StaticBoxSizer(wx.StaticBox(dlg, -1, _("Certificate Info")), wx.VERTICAL)
170 box.Add(sizer, 0, wx.EXPAND)
171
172 certRadio = wx.RadioBox(dlg, -1, _("Certificate"), choices=[_("Accept Always"), _("Accept Once"), _("Reject")], majorDimension=1, style=wx.RA_SPECIFY_COLS)
173
174 buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
175 okBtn = wx.Button(dlg, wx.ID_OK)
176 okBtn.SetDefault()
177 buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
178 buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
179
180 contentSizer = wx.BoxSizer(wx.VERTICAL)
181 contentSizer.Add(box, 0, wx.TOP|wx.LEFT|wx.RIGHT|wx.EXPAND, SPACE)
182 contentSizer.Add(certRadio, 0, wx.TOP|wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, SPACE)
183 contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
184
185 dlg.SetSizer(contentSizer)
186 dlg.Fit()
187 dlg.Layout()
188
189 # default values for reject
190 retcode = False
191 acceptedFailures = 0
192 save = False
193
194 if dlg.ShowModal() == wx.ID_OK:
195 cert = certRadio.GetStringSelection()
196 if cert == _("Accept Always"):
197 retcode = True
198 acceptedFailures = trustDict.get('failures')
199 save = True
200 elif cert == _("Accept Once"):
201 retcode = True
202 acceptedFailures = trustDict.get('failures')
203 save = False
204
205 return retcode, acceptedFailures, save
206
207
208 def SSLClientPassword(self, realm, maySave):
209 dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SSL Client Certificate Login"))
210
211 sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
212 sizer.Add(wx.StaticText(dlg, -1, _("Realm:")), 0, wx.ALIGN_CENTER_VERTICAL)
213 sizer.Add(wx.StaticText(dlg, -1, realm), 0, wx.ALIGN_CENTER_VERTICAL)
214 sizer.Add(wx.StaticText(dlg, -1, _("Password:")), 0, wx.ALIGN_CENTER_VERTICAL)
215 passwordTxt = wx.TextCtrl(dlg, -1, size=(200, -1), style=wx.TE_PASSWORD)
216 sizer.Add(passwordTxt, 0, wx.ALIGN_CENTER_VERTICAL)
217
218 savePasswordCheckbox = wx.CheckBox(dlg, -1, _("Remember Password"))
219 if not maySave:
220 savePasswordCheckbox.Enable(False)
221
222 buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
223 okBtn = wx.Button(dlg, wx.ID_OK)
224 okBtn.SetDefault()
225 buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
226 buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
227
228 contentSizer = wx.BoxSizer(wx.VERTICAL)
229 contentSizer.Add(sizer, 0, wx.LEFT|wx.TOP|wx.RIGHT, SPACE)
230 contentSizer.Add(savePasswordCheckbox, 0, wx.TOP|wx.LEFT|wx.BOTTOM, SPACE)
231 contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
232
233 dlg.SetSizer(contentSizer)
234 dlg.Fit()
235 dlg.Layout()
236
237 if dlg.ShowModal() == wx.ID_OK:
238 retcode = True
239 password = passwordTxt.GetValue()
240 save = savePasswordCheckBox.IsChecked()
241 else:
242 retcode = False
243 password = None
244 save = False
245
246 dlg.Destroy()
247 return retcode, password, save
248
249
250 def SSLClientCert(self):
251 dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
252 message="Choose certificate", defaultDir=os.getcwd(),
253 style=wx.OPEN|wx.CHANGE_DIR
254 )
255
256 if dlg.ShowModal() == wx.ID_OK:
257 retcode = True
258 certfile = dlg.GetPath()
259 else:
260 retcode = False
261 certfile = None
262
263 dlg.Destroy()
264 return retcode, certfile
265
266
267
268 #----------------------------------------------------------------------------
269 # Service Methods
270 #----------------------------------------------------------------------------
271
272 def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
273 menu = menuBar.GetMenu(menuBar.FindMenu(_("Project")))
274
275 menu.AppendSeparator()
276
277 wx.EVT_MENU(frame, SVNService.SVN_UPDATE_ID, self.ProcessEvent)
278 wx.EVT_UPDATE_UI(frame, SVNService.SVN_UPDATE_ID, self.ProcessUpdateUIEvent)
279 menu.Append(SVNService.SVN_UPDATE_ID, _("SVN Update"), _("Update file from Subversion"))
280 wx.EVT_MENU(frame, SVNService.SVN_CHECKIN_ID, self.ProcessEvent)
281 wx.EVT_UPDATE_UI(frame, SVNService.SVN_CHECKIN_ID, self.ProcessUpdateUIEvent)
282 menu.Append(SVNService.SVN_CHECKIN_ID, _("SVN Commit..."), _("Commit file changes to Subversion"))
283 wx.EVT_MENU(frame, SVNService.SVN_CHECKOUT_ID, self.ProcessEvent)
284 wx.EVT_UPDATE_UI(frame, SVNService.SVN_CHECKOUT_ID, self.ProcessUpdateUIEvent)
285 menu.Append(SVNService.SVN_CHECKOUT_ID, _("SVN Checkout..."), _("Checkout file from Subversion"))
286 wx.EVT_MENU(frame, SVNService.SVN_REVERT_ID, self.ProcessEvent)
287 wx.EVT_UPDATE_UI(frame, SVNService.SVN_REVERT_ID, self.ProcessUpdateUIEvent)
288 menu.Append(SVNService.SVN_REVERT_ID, _("SVN Revert"), _("Revert file from Subversion"))
289
290 menu.AppendSeparator()
291
292 wx.EVT_MENU(frame, SVNService.SVN_ADD_ID, self.ProcessEvent)
293 wx.EVT_UPDATE_UI(frame, SVNService.SVN_ADD_ID, self.ProcessUpdateUIEvent)
294 menu.Append(SVNService.SVN_ADD_ID, _("SVN Add"), _("Add file to Subversion"))
295 wx.EVT_MENU(frame, SVNService.SVN_DELETE_ID, self.ProcessEvent)
296 wx.EVT_UPDATE_UI(frame, SVNService.SVN_DELETE_ID, self.ProcessUpdateUIEvent)
297 menu.Append(SVNService.SVN_DELETE_ID, _("SVN Delete"), _("Delete file from Subversion"))
298
299
300 def ProcessEvent(self, event):
301
302 id = event.GetId()
303
304 if not SVN_INSTALLED:
305 if id in SVNService.SVN_COMMAND_LIST:
306 wx.MessageBox(_("pysvn not found. Please install pysvn"), _("Python Subversion"))
307 return True
308 return False
309
310
311 if id == SVNService.SVN_UPDATE_ID:
312 filenames = self.GetCurrentDocuments()
313
314 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
315
316 messageService = wx.GetApp().GetService(MessageService.MessageService)
317 messageService.ShowWindow()
318
319 view = messageService.GetView()
320 view.ClearLines()
321 view.AddLines(_("SVN Update:\n"))
322
323 for filename in filenames:
324 view.AddLines("%s\n" % filename)
325 try:
326 status = self._client.update(filename)
327
328 if status.number > 0:
329 view.AddLines(_("Updated to revision %s\n") % status.number)
330
331 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
332 for doc in openDocs:
333 if doc.GetFilename() == filename:
334 yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
335 _("Updated file '%s' is currently open. Close it?") % os.path.basename(filename),
336 _("Close File"),
337 wx.YES_NO|wx.ICON_QUESTION)
338 if yesNoMsg.ShowModal() == wx.ID_YES:
339 doc.DeleteAllViews()
340 break
341 else:
342 view.AddLines(_("Update failed.\n"))
343
344 except pysvn.ClientError, e:
345 view.AddLines("%s\n" % str(e))
346 wx.MessageBox(str(e), _("SVN Update"), wx.OK | wx.ICON_EXCLAMATION)
347 except:
348 extype, ex, tb = sys.exc_info()
349 view.AddLines("Update failed: (%s) %s\n" % (extype, str(ex)))
350 for line in traceback.format_tb(tb):
351 view.AddLines(line)
352
353 wx.MessageBox(_("Update failed."), _("SVN Update"), wx.OK | wx.ICON_EXCLAMATION)
354
355 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
356
357 return True
358
359 elif id == SVNService.SVN_CHECKIN_ID:
360 filenames = self.GetCurrentDocuments()
361
362 # ask user if dirty files should be saved first
363 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
364 for filename in filenames:
365 for doc in openDocs:
366 if doc.GetFilename() == filename and doc.IsModified():
367 yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
368 _("'%s' has unsaved modifications. Save it before commit?") % os.path.basename(filename),
369 _("SVN Commit"),
370 wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
371 status = yesNoMsg.ShowModal()
372 if status == wx.ID_YES:
373 doc.Save()
374 elif status == wx.ID_NO:
375 pass
376 else: # elif status == wx.CANCEL:
377 return True
378 break
379
380 shortFilenames = []
381 for i, filename in enumerate(filenames):
382 shortFilename = os.path.basename(filename)
383 shortFilenames.append(shortFilename)
384
385 dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Commit"))
386
387 sizer = wx.BoxSizer(wx.VERTICAL)
388 sizer.Add(wx.StaticText(dlg, -1, _("Comment:")), 0, wx.ALIGN_CENTER_VERTICAL)
389 commentText = wx.TextCtrl(dlg, -1, size=(250,-1), style=wx.TE_MULTILINE)
390 sizer.Add(commentText, 1, wx.EXPAND|wx.TOP, HALF_SPACE)
391
392 sizer.Add(wx.StaticText(dlg, -1, _("Files:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, SPACE)
393 fileList = wx.CheckListBox(dlg, -1, choices = shortFilenames)
394 for i in range(fileList.GetCount()):
395 fileList.Check(i, True)
396 sizer.Add(fileList, 0, wx.EXPAND|wx.TOP, HALF_SPACE)
397
398 buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
399 okBtn = wx.Button(dlg, wx.ID_OK)
400 okBtn.SetDefault()
401 buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
402 buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
403
404 contentSizer = wx.BoxSizer(wx.VERTICAL)
405 contentSizer.Add(sizer, 0, wx.ALL, SPACE)
406 contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
407
408 dlg.SetSizer(contentSizer)
409 dlg.Fit()
410 dlg.Layout()
411
412 if dlg.ShowModal() == wx.ID_OK:
413 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
414
415 messageService = wx.GetApp().GetService(MessageService.MessageService)
416 messageService.ShowWindow()
417
418 view = messageService.GetView()
419 view.ClearLines()
420 view.AddLines(_("SVN Commit:\n"))
421
422 try:
423 selFilenames = []
424 for i in range(fileList.GetCount()):
425 if fileList.IsChecked(i):
426 selFilenames.append(filenames[i])
427 view.AddLines("%s\n" % filenames[i])
428
429 if len(selFilenames):
430 comment = commentText.GetValue()
431 status = self._client.checkin(selFilenames, comment)
432
433 if status is None:
434 view.AddLines(_("Nothing to commit.\n"))
435 elif status.number > 0:
436 view.AddLines(_("Committed as revision %s.\n") % status.number)
437 else:
438 view.AddLines(_("Commit failed.\n"))
439
440 except pysvn.ClientError, e:
441 view.AddLines("%s\n" % str(e))
442 wx.MessageBox(str(e), _("SVN Commit"), wx.OK | wx.ICON_EXCLAMATION)
443 except:
444 extype, ex, tb = sys.exc_info()
445 view.AddLines("Commit failed: (%s) %s\n" % (extype, str(ex)))
446 for line in traceback.format_tb(tb):
447 view.AddLines(line)
448 wx.MessageBox(_("Commit failed."), _("SVN Commit"), wx.OK | wx.ICON_EXCLAMATION)
449
450 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
451 dlg.Destroy()
452 return True
453
454 elif id == SVNService.SVN_CHECKOUT_ID:
455 config = wx.ConfigBase_Get()
456 svnUrl = config.Read(SVN_REPOSITORY_URL, self._defaultURL)
457
458 dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Checkout"))
459
460 gridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
461 gridSizer.Add(wx.StaticText(dlg, -1, _("Repository URL:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, HALF_SPACE)
462 svnURLText = wx.TextCtrl(dlg, -1, svnUrl, size = (200, -1))
463 svnURLText.SetToolTipString(svnUrl)
464 gridSizer.Add(svnURLText, 0)
465
466 gridSizer.Add(wx.StaticText(dlg, -1, _("Checkout to dir:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, HALF_SPACE)
467 localPath = wx.TextCtrl(dlg, -1, size = (200, -1))
468 localPath.SetToolTipString(_("Path in local file system where files will be located."))
469 findDirButton = wx.Button(dlg, -1, _("Browse..."))
470
471 def OnBrowseButton(event):
472 dirDlg = wx.DirDialog(wx.GetApp().GetTopWindow(), _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
473 dir = localPath.GetValue()
474 if len(dir):
475 dirDlg.SetPath(dir)
476 if dirDlg.ShowModal() == wx.ID_OK:
477 localPath.SetValue(dirDlg.GetPath())
478 localPath.SetToolTipString(localPath.GetValue())
479 localPath.SetInsertionPointEnd()
480
481 dirDlg.Destroy()
482 wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
483
484 sizer = wx.BoxSizer(wx.HORIZONTAL)
485 sizer.Add(localPath, 1, wx.EXPAND)
486 sizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
487 gridSizer.Add(sizer, 0)
488
489 buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
490 okBtn = wx.Button(dlg, wx.ID_OK)
491 okBtn.SetDefault()
492 buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
493 buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
494
495 contentSizer = wx.BoxSizer(wx.VERTICAL)
496 contentSizer.Add(gridSizer, 0, wx.ALL, SPACE)
497 contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
498
499 dlg.SetSizer(contentSizer)
500 dlg.Fit()
501 dlg.Layout()
502
503 if dlg.ShowModal() == wx.ID_OK:
504 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
505
506 messageService = wx.GetApp().GetService(MessageService.MessageService)
507 messageService.ShowWindow()
508
509 view = messageService.GetView()
510 view.ClearLines()
511 view.AddLines(_("SVN Checkout:\n"))
512
513 svnUrl = svnURLText.GetValue()
514 toLocation = localPath.GetValue()
515 try:
516 self._client.checkout(svnUrl, toLocation)
517 view.AddLines(_("Checkout completed.\n"))
518 except pysvn.ClientError, e:
519 view.AddLines(_("Checkout failed. %s\n") % str(e))
520 wx.MessageBox(_("Checkout failed. %s") % str(e), _("SVN Checkout"), wx.OK | wx.ICON_EXCLAMATION)
521 except:
522 extype, ex, tb = sys.exc_info()
523 view.AddLines("Checkout failed: (%s) %s\n" % (extype, str(ex)))
524 for line in traceback.format_tb(tb):
525 view.AddLines(line)
526 wx.MessageBox(_("Checkout failed."), _("SVN Checkout"), wx.OK | wx.ICON_EXCLAMATION)
527
528 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
529 dlg.Destroy()
530 return True
531
532 elif id == SVNService.SVN_REVERT_ID:
533 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
534
535 filenames = self.GetCurrentDocuments()
536
537 messageService = wx.GetApp().GetService(MessageService.MessageService)
538 messageService.ShowWindow()
539
540 view = messageService.GetView()
541 view.ClearLines()
542 view.AddLines(_("SVN Revert:\n"))
543 for filename in filenames:
544 view.AddLines("%s\n" % filename)
545
546 try:
547 self._client.revert(filenames)
548 view.AddLines(_("Revert completed.\n"))
549
550 openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
551 for doc in openDocs[:]: # need to make a copy of the list otherwise ordinality changes as we close the files
552 if doc.GetFilename() in filenames:
553 yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
554 _("Reverted file '%s' is currently open. Close it?") % os.path.basename(doc.GetFilename()),
555 _("Close File"),
556 wx.YES_NO|wx.ICON_QUESTION)
557 if yesNoMsg.ShowModal() == wx.ID_YES:
558 doc.DeleteAllViews()
559
560 except pysvn.ClientError, e:
561 view.AddLines("%s\n" % str(e))
562 wx.MessageBox(str(e), _("SVN Revert"), wx.OK | wx.ICON_EXCLAMATION)
563 except:
564 extype, ex, tb = sys.exc_info()
565 view.AddLines("Revert failed: (%s) %s\n" % (extype, str(ex)))
566 for line in traceback.format_tb(tb):
567 view.AddLines(line)
568 wx.MessageBox(_("Revert failed."), _("SVN Revert"), wx.OK | wx.ICON_EXCLAMATION)
569
570 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
571 return True
572
573 elif id == SVNService.SVN_ADD_ID:
574 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
575
576 filenames = self.GetCurrentDocuments()
577
578 messageService = wx.GetApp().GetService(MessageService.MessageService)
579 messageService.ShowWindow()
580
581 view = messageService.GetView()
582 view.ClearLines()
583 view.AddLines(_("SVN Add:\n"))
584 for filename in filenames:
585 view.AddLines("%s\n" % filename)
586
587 try:
588 self._client.add(filenames)
589 view.AddLines(_("Add completed.\n"))
590 except pysvn.ClientError, e:
591 view.AddLines("%s\n" % str(e))
592 wx.MessageBox(str(e), _("SVN Add"), wx.OK | wx.ICON_EXCLAMATION)
593 except:
594 extype, ex, tb = sys.exc_info()
595 view.AddLines("Add failed: (%s) %s\n" % (extype, str(ex)))
596 for line in traceback.format_tb(tb):
597 view.AddLines(line)
598 wx.MessageBox(_("Add failed."), _("SVN Add"), wx.OK | wx.ICON_EXCLAMATION)
599
600 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
601 return True
602
603 elif id == SVNService.SVN_DELETE_ID:
604 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
605
606 filenames = self.GetCurrentDocuments()
607
608 messageService = wx.GetApp().GetService(MessageService.MessageService)
609 messageService.ShowWindow()
610
611 view = messageService.GetView()
612 view.ClearLines()
613 view.AddLines(_("SVN Delete:\n"))
614 for filename in filenames:
615 view.AddLines("%s\n" % filename)
616
617 try:
618 self._client.remove(filenames)
619 view.AddLines(_("Delete completed.\n"))
620 except pysvn.ClientError, e:
621 view.AddLines("%s\n" % str(e))
622 wx.MessageBox(str(e), _("SVN Delete"), wx.OK | wx.ICON_EXCLAMATION)
623 except:
624 extype, ex, tb = sys.exc_info()
625 view.AddLines("Delete failed: (%s) %s\n" % (extype, str(ex)))
626 for line in traceback.format_tb(tb):
627 view.AddLines(line)
628 wx.MessageBox(_("Delete failed."), _("SVN Delete"), wx.OK | wx.ICON_EXCLAMATION)
629
630 wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
631 return True
632
633 return False
634
635
636 def ProcessUpdateUIEvent(self, event):
637 id = event.GetId()
638
639 if id in [SVNService.SVN_UPDATE_ID,
640 SVNService.SVN_CHECKIN_ID,
641 SVNService.SVN_REVERT_ID,
642 SVNService.SVN_ADD_ID,
643 SVNService.SVN_DELETE_ID]:
644 if self.GetCurrentDocuments():
645 event.Enable(True)
646 else:
647 event.Enable(False)
648 return True
649
650 elif id == SVNService.SVN_CHECKOUT_ID:
651 event.Enable(True)
652 return True
653
654 return False
655
656
657 def GetCurrentDocuments(self):
658
659 projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
660 if projectService:
661 projView = projectService.GetView()
662
663 if projView.HasFocus():
664 filenames = projView.GetSelectedFiles()
665 if len(filenames):
666 return filenames
667 else:
668 return None
669
670 doc = wx.GetApp().GetTopWindow().GetDocumentManager().GetCurrentDocument()
671 if doc:
672 filenames = [doc.GetFilename()]
673 else:
674 filenames = None
675
676 return filenames
677
678
679class SVNOptionsPanel(wx.Panel):
680
681
682 def __init__(self, parent, id):
683 wx.Panel.__init__(self, parent, id)
684
685 config = wx.ConfigBase_Get()
686 svnService = wx.GetApp().GetService(SVNService)
687 svnUrl = config.Read(SVN_REPOSITORY_URL, svnService._defaultURL)
688 configDir = config.Read(SVN_CONFIG_DIR, "")
689
690 borderSizer = wx.BoxSizer(wx.VERTICAL)
691 sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
692
693 sizer.Add(wx.StaticText(self, -1, _("SVN Config Dir:")), 0, wx.ALIGN_CENTER_VERTICAL)
694
695 self._svnConfigDir = wx.TextCtrl(self, -1, configDir, size = (200, -1))
696 if configDir == "":
697 self._svnConfigDir.SetToolTipString(_("Path Subversion configuration directory."))
698 else:
699 self._svnConfigDir.SetToolTipString(configDir)
700
701 findDirButton = wx.Button(self, -1, _("Browse..."))
702
703 def OnBrowseButton(event):
704 dirDlg = wx.DirDialog(self, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
705 dir = self._svnConfigDir.GetValue()
706 if len(dir):
707 dirDlg.SetPath(dir)
708 if dirDlg.ShowModal() == wx.ID_OK:
709 self._svnConfigDir.SetValue(dirDlg.GetPath())
710 self._svnConfigDir.SetToolTipString(self._svnConfigDir.GetValue())
711 self._svnConfigDir.SetInsertionPointEnd()
712
713 dirDlg.Destroy()
714 wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
715
716 hsizer = wx.BoxSizer(wx.HORIZONTAL)
717 hsizer.Add(self._svnConfigDir, 1, wx.EXPAND)
718 hsizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
719 sizer.Add(hsizer, 0)
720
721 sizer.Add(wx.StaticText(self, -1, _("SVN URL:")), 0, wx.ALIGN_CENTER_VERTICAL)
722 self._svnURLText = wx.TextCtrl(self, -1, svnUrl, size = (200, -1))
723 self._svnURLText.SetToolTipString(svnUrl)
724 sizer.Add(self._svnURLText, 0)
725
726 borderSizer.Add(sizer, 0, wx.ALL, SPACE)
727 self.SetSizer(borderSizer)
728 self.Layout()
729 parent.AddPage(self, _("SVN"))
730
731
732 def OnOK(self, optionsDialog):
733 config = wx.ConfigBase_Get()
734 config.Write(SVN_CONFIG_DIR, self._svnConfigDir.GetValue())
735 config.Write(SVN_REPOSITORY_URL, self._svnURLText.GetValue())
736