More updates to the docview library modules and sample apps from the
ActiveGrid folks. Their sample IDE is now able to integrate with Subversion. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34158 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -28,6 +28,7 @@ licenseData = [
|
||||
("wxWidgets", "wxWindows Library License 3", "http://www.wxwidgets.org/manuals/2.5.4/wx_wxlicense.html"),
|
||||
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
|
||||
("process.py", "See file", "http://starship.python.net/~tmick/"),
|
||||
("pysvn", "Apache License", "http://pysvn.tigris.org/"),
|
||||
]
|
||||
|
||||
if not ACTIVEGRID_BASE_IDE: # add licenses for database connections only if not the base IDE
|
||||
|
@@ -66,13 +66,18 @@ class CanvasView(wx.lib.docview.View):
|
||||
if activate and self._canvas:
|
||||
# In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
|
||||
if self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
|
||||
self._canvas.SetFocus()
|
||||
self.SetFocus()
|
||||
else:
|
||||
wx.CallAfter(self._canvas.SetFocus)
|
||||
wx.CallAfter(self.SetFocus)
|
||||
|
||||
|
||||
def SetFocus(self):
|
||||
if self._canvas:
|
||||
self._canvas.SetFocus()
|
||||
|
||||
|
||||
def OnFocus(self, event):
|
||||
self._canvas.SetFocus()
|
||||
self.SetFocus()
|
||||
self.FocusColorPropertyShape(True)
|
||||
event.Skip()
|
||||
|
||||
@@ -82,6 +87,17 @@ class CanvasView(wx.lib.docview.View):
|
||||
event.Skip()
|
||||
|
||||
|
||||
def HasFocus(self):
|
||||
winWithFocus = wx.Window.FindFocus()
|
||||
if not winWithFocus:
|
||||
return False
|
||||
while winWithFocus:
|
||||
if winWithFocus == self._canvas:
|
||||
return True
|
||||
winWithFocus = winWithFocus.GetParent()
|
||||
return False
|
||||
|
||||
|
||||
def OnClose(self, deleteWindow = True):
|
||||
statusC = wx.GetApp().CloseChildDocuments(self.GetDocument())
|
||||
statusP = wx.lib.docview.View.OnClose(self, deleteWindow = deleteWindow)
|
||||
@@ -528,7 +544,10 @@ class CanvasView(wx.lib.docview.View):
|
||||
|
||||
# draw new selection
|
||||
if self._propShape and self._propShape in self._diagram.GetShapeList():
|
||||
self._propShape.SetBrush(SELECT_BRUSH)
|
||||
if self.HasFocus():
|
||||
self._propShape.SetBrush(SELECT_BRUSH)
|
||||
else:
|
||||
self._propShape.SetBrush(INACTIVE_SELECT_BRUSH)
|
||||
if (self._propShape._textColourName in ["BLACK", "WHITE"]): # Would use GetTextColour() but it is broken
|
||||
self._propShape.SetTextColour("WHITE", 0)
|
||||
self._propShape.Draw(dc)
|
||||
|
@@ -190,6 +190,7 @@ class Adb(bdb.Bdb):
|
||||
|
||||
def stop_here(self, frame):
|
||||
if( self._userBreak ):
|
||||
self._userBreak = False
|
||||
return True
|
||||
|
||||
|
||||
@@ -446,11 +447,22 @@ class DebuggerHarness(object):
|
||||
item_node.setAttribute('value', wholeStack)
|
||||
item_node.setAttribute('name', str(name))
|
||||
top_element.appendChild(item_node)
|
||||
|
||||
cantIntro = [types.FunctionType,
|
||||
types.LambdaType,
|
||||
types.UnicodeType,
|
||||
types.StringType,
|
||||
types.NoneType,
|
||||
types.IntType,
|
||||
types.LongType,
|
||||
types.FloatType,
|
||||
types.BooleanType]
|
||||
|
||||
def addAny(self, top_element, name, item, doc, ply):
|
||||
tp = type(item)
|
||||
if ply < 1:
|
||||
self.addNode(top_element,name, self.saferepr(item), doc)
|
||||
|
||||
if tp in DebuggerHarness.cantIntro or ply < 1:
|
||||
self.addNode(top_element,name, item, doc)
|
||||
elif tp is types.TupleType or tp is types.ListType:
|
||||
self.addTupleOrList(top_element, name, item, doc, ply - 1)
|
||||
elif tp is types.DictType or tp is types.DictProxyType:
|
||||
@@ -459,23 +471,141 @@ class DebuggerHarness(object):
|
||||
self.addModule(top_element, name, item, doc, ply -1)
|
||||
elif inspect.isclass(item) or tp is types.InstanceType:
|
||||
self.addClass(top_element, name, item, doc, ply -1)
|
||||
#elif hasattr(item, '__dict__'):
|
||||
# self.addDictAttr(top_element, name, item, doc, ply -1)
|
||||
elif hasattr(item, '__dict__'):
|
||||
self.addDict(top_element, name, item.__dict__, doc, ply -1)
|
||||
self.addDictAttr(top_element, name, item, doc, ply -1)
|
||||
else:
|
||||
self.addNode(top_element,name, self.saferepr(item), doc)
|
||||
self.addNode(top_element,name, item, doc)
|
||||
|
||||
|
||||
def canIntrospect(self, item):
|
||||
tp = type(item)
|
||||
if tp in DebuggerHarness.cantIntro:
|
||||
return False
|
||||
elif tp is types.TupleType or tp is types.ListType:
|
||||
return len(item) > 0
|
||||
elif tp is types.DictType or tp is types.DictProxyType:
|
||||
return len(item) > 0
|
||||
elif inspect.ismodule(item):
|
||||
return True
|
||||
elif inspect.isclass(item) or tp is types.InstanceType:
|
||||
if hasattr(item, '__dict__'):
|
||||
return True
|
||||
elif hasattr(item, '__name__'):
|
||||
return True
|
||||
elif hasattr(item, '__module__'):
|
||||
return True
|
||||
elif hasattr(item, '__doc__'):
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
elif hasattr(item, '__dict__'):
|
||||
return len(item.__dict__) > 0
|
||||
else:
|
||||
return False
|
||||
|
||||
def addNode(self, parent_node, name, item, document):
|
||||
item_node = document.createElement("dict_nv_element")
|
||||
item_node.setAttribute('value', self.saferepr(item))
|
||||
item_node.setAttribute('name', str(name))
|
||||
introVal = str(self.canIntrospect(item))
|
||||
item_node.setAttribute('intro', str(introVal))
|
||||
parent_node.appendChild(item_node)
|
||||
|
||||
|
||||
def addTupleOrList(self, top_node, name, tupple, doc, ply):
|
||||
tupleNode = doc.createElement('tuple')
|
||||
tupleNode.setAttribute('name', str(name))
|
||||
tupleNode.setAttribute('value', str(type(tupple)))
|
||||
tupleNode.setAttribute('value', self.saferepr(tupple))
|
||||
top_node.appendChild(tupleNode)
|
||||
count = 0
|
||||
for item in tupple:
|
||||
self.addAny(tupleNode, name +'[' + str(count) + ']',item, doc, ply -1)
|
||||
count += 1
|
||||
|
||||
def addDictAttr(self, root_node, name, thing, document, ply):
|
||||
dict_node = document.createElement('thing')
|
||||
dict_node.setAttribute('name', name)
|
||||
dict_node.setAttribute('value', self.saferepr(thing))
|
||||
root_node.appendChild(dict_node)
|
||||
self.addDict(dict_node, '', thing.__dict__, document, ply) # Not decreminting ply
|
||||
|
||||
def addDict(self, root_node, name, dict, document, ply):
|
||||
if name != '':
|
||||
dict_node = document.createElement('dict')
|
||||
dict_node.setAttribute('name', name)
|
||||
dict_node.setAttribute('value', self.saferepr(dict))
|
||||
root_node.appendChild(dict_node)
|
||||
else:
|
||||
dict_node = root_node
|
||||
for key in dict.keys():
|
||||
strkey = str(key)
|
||||
try:
|
||||
value = dict[key]
|
||||
self.addAny(dict_node, strkey, value, document, ply-1)
|
||||
except:
|
||||
if _VERBOSE:
|
||||
tp,val,tb=sys.exc_info()
|
||||
print "Error recovering key: ", str(key), " from node ", str(name), " Val = ", str(val)
|
||||
traceback.print_exception(tp, val, tb)
|
||||
|
||||
def addClass(self, root_node, name, class_item, document, ply):
|
||||
item_node = document.createElement('class')
|
||||
item_node.setAttribute('name', str(name))
|
||||
item_node.setAttribute('value', self.saferepr(class_item))
|
||||
root_node.appendChild(item_node)
|
||||
try:
|
||||
if hasattr(class_item, '__dict__'):
|
||||
self.addDict(item_node, '', class_item.__dict__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
try:
|
||||
if hasattr(class_item, '__name__'):
|
||||
self.addAny(item_node,'__name__',class_item.__name__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
try:
|
||||
if hasattr(class_item, '__module__'):
|
||||
self.addAny(item_node, '__module__', class_item.__module__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
try:
|
||||
if hasattr(class_item, '__doc__'):
|
||||
self.addAny(item_node, '__doc__', class_item.__doc__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
try:
|
||||
if hasattr(class_item, '__bases__'):
|
||||
self.addAny(item_node, '__bases__', class_item.__bases__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
|
||||
def addModule(self, root_node, name, module_item, document, ply):
|
||||
item_node = document.createElement('module')
|
||||
item_node.setAttribute('name', str(name))
|
||||
item_node.setAttribute('value', self.saferepr(module_item))
|
||||
root_node.appendChild(item_node)
|
||||
try:
|
||||
if hasattr(module_item, '__file__'):
|
||||
self.addAny(item_node, '__file__', module_item.__file__, document, ply -1)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if hasattr(module_item, '__doc__'):
|
||||
self.addAny(item_node,'__doc__', module_item.__doc__, document, ply -1)
|
||||
except:
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def getFrameXML(self, base_frame):
|
||||
doc = getDOMImplementation().createDocument(None, "stack", None)
|
||||
@@ -506,7 +636,7 @@ class DebuggerHarness(object):
|
||||
#print "Frame: %s %s %s" %(message, frame.f_lineno, filename)
|
||||
self.message_frame_dict[message] = frame
|
||||
self.addDict(frameNode, "locals", frame.f_locals, document, 2)
|
||||
self.addNode(frameNode, "globals", "", document)
|
||||
self.addNode(frameNode, "globals", frame.f_globals, document)
|
||||
|
||||
def getRepr(self, varName, globals, locals):
|
||||
try:
|
||||
@@ -514,101 +644,15 @@ class DebuggerHarness(object):
|
||||
except:
|
||||
return 'Error: Could not recover value.'
|
||||
|
||||
def addNode(self, parent_node, name, value, document):
|
||||
item_node = document.createElement("dict_nv_element")
|
||||
item_node.setAttribute('value', self.saferepr(value))
|
||||
item_node.setAttribute('name', str(name))
|
||||
parent_node.appendChild(item_node)
|
||||
|
||||
def addDictAttr(self, root_node, name, thing, document, ply):
|
||||
dict_node = document.createElement('thing')
|
||||
root_node.setAttribute('name', name)
|
||||
root_node.setAttribute('value', str(type(dict)) + " add attr")
|
||||
self.addDict(root_node, name, thing.__dict__, document, ply) # Not decreminting ply
|
||||
|
||||
|
||||
def saferepr(self, thing):
|
||||
try:
|
||||
return repr(thing)
|
||||
except:
|
||||
tp, val, tb = sys.exc_info()
|
||||
traceback.print_exception(tp, val, tb)
|
||||
return repr(val)
|
||||
|
||||
def addDict(self, root_node, name, dict, document, ply):
|
||||
dict_node = document.createElement('dict')
|
||||
dict_node.setAttribute('name', name)
|
||||
dict_node.setAttribute('value', str(type(dict)) + " add dict")
|
||||
root_node.appendChild(dict_node)
|
||||
for key in dict.keys():
|
||||
strkey = str(key)
|
||||
try:
|
||||
self.addAny(dict_node, strkey, dict[key], document, ply-1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
print "Error recovering key: ", str(key), " from node ", str(name), " Val = ", str(val)
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(dict_node, strkey, "Exception getting " + str(name) + "[" + strkey + "]: " + str(val), document, ply -1)
|
||||
|
||||
def addClass(self, root_node, name, class_item, document, ply):
|
||||
item_node = document.createElement('class')
|
||||
item_node.setAttribute('name', str(name))
|
||||
root_node.appendChild(item_node)
|
||||
try:
|
||||
if hasattr(class_item, '__dict__'):
|
||||
self.addAny(item_node, '__dict__', class_item.__dict__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(item_node, '__dict__', "Exception getting __dict__: " + str(val), document, ply -1)
|
||||
try:
|
||||
if hasattr(class_item, '__name__'):
|
||||
self.addAny(item_node,'__name__',class_item.__name__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(item_node,'__name__',"Exception getting class.__name__: " + val, document, ply -1)
|
||||
try:
|
||||
if hasattr(class_item, '__module__'):
|
||||
self.addAny(item_node, '__module__', class_item.__module__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(item_node, '__module__', "Exception getting class.__module__: " + val, document, ply -1)
|
||||
try:
|
||||
if hasattr(class_item, '__doc__'):
|
||||
self.addAny(item_node, '__doc__', class_item.__doc__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(item_node, '__doc__', "Exception getting class.__doc__: " + val, document, ply -1)
|
||||
try:
|
||||
if hasattr(class_item, '__bases__'):
|
||||
self.addAny(item_node, '__bases__', class_item.__bases__, document, ply -1)
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
if _VERBOSE:
|
||||
traceback.print_exception(tp, val, tb)
|
||||
self.addAny(item_node, '__bases__', "Exception getting class.__bases__: " + val, document, ply -1)
|
||||
|
||||
def addModule(self, root_node, name, module_item, document, ply):
|
||||
item_node = document.createElement('module')
|
||||
item_node.setAttribute('name', str(name))
|
||||
root_node.appendChild(item_node)
|
||||
try:
|
||||
if hasattr(module_item, '__file__'):
|
||||
self.addAny(item_node, '__file__', module_item.__file__, document, ply -1)
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
if hasattr(module_item, '__doc__'):
|
||||
self.addAny(item_node,'__doc__', module_item.__doc__, document, ply -1)
|
||||
except:
|
||||
pass
|
||||
|
||||
# The debugger calls this method when it reaches a breakpoint.
|
||||
def interaction(self, message, frame, info):
|
||||
if _VERBOSE:
|
||||
@@ -683,6 +727,7 @@ if __name__ == '__main__':
|
||||
try:
|
||||
harness = DebuggerHarness()
|
||||
harness.run()
|
||||
harness.do_exit(kill=True)
|
||||
except SystemExit:
|
||||
print "Exiting..."
|
||||
except:
|
||||
|
@@ -103,6 +103,8 @@ class OutputReaderThread(threading.Thread):
|
||||
self._keepGoing = False
|
||||
start = time.time()
|
||||
output = ""
|
||||
except TypeError:
|
||||
pass
|
||||
except:
|
||||
tp, val, tb = sys.exc_info()
|
||||
print "Exception in OutputReaderThread.run():", tp, val
|
||||
@@ -163,6 +165,7 @@ class Executor:
|
||||
self._stdOutReader = None
|
||||
self._stdErrReader = None
|
||||
self._process = None
|
||||
DebuggerService.executors.append(self)
|
||||
|
||||
def OutCall(self, text):
|
||||
evt = UpdateTextEvent(value = text)
|
||||
@@ -197,6 +200,7 @@ class Executor:
|
||||
self._stdOutReader.AskToStop()
|
||||
if(self._stdErrReader != None):
|
||||
self._stdErrReader.AskToStop()
|
||||
DebuggerService.executors.remove(self)
|
||||
|
||||
class RunCommandUI(wx.Panel):
|
||||
|
||||
@@ -371,10 +375,10 @@ class DebugCommandUI(wx.Panel):
|
||||
|
||||
def ShutdownAllDebuggers():
|
||||
for debugger in DebugCommandUI.debuggers:
|
||||
debugger.StopExecution()
|
||||
debugger.StopExecution(None)
|
||||
|
||||
ShutdownAllDebuggers = staticmethod(ShutdownAllDebuggers)
|
||||
|
||||
|
||||
def GetAvailablePort():
|
||||
for index in range( 0, len(DebugCommandUI.debuggerPortList)):
|
||||
port = DebugCommandUI.debuggerPortList[index]
|
||||
@@ -428,7 +432,6 @@ class DebugCommandUI(wx.Panel):
|
||||
|
||||
self._parentNoteBook = parent
|
||||
self._command = command
|
||||
self._textCtrl = None
|
||||
self._service = service
|
||||
self._executor = None
|
||||
self.STEP_ID = wx.NewId()
|
||||
@@ -490,18 +493,10 @@ class DebugCommandUI(wx.Panel):
|
||||
tb.AddSimpleTool(self.CLEAR_ID, clear_bmp, _("Clear output pane"))
|
||||
wx.EVT_TOOL(self, self.CLEAR_ID, self.OnClearOutput)
|
||||
|
||||
tb.Realize()
|
||||
self.framesTab = None
|
||||
self.DisableWhileDebuggerRunning()
|
||||
self._notebook = wx.Notebook(self, -1, wx.DefaultPosition, wx.DefaultSize, wx.LB_DEFAULT, "Debugger")
|
||||
sizer.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId(), None)
|
||||
self.framesTab = self.MakeFramesTab(self._notebook, wx.NewId(), None)
|
||||
self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId(), None)
|
||||
self._notebook.AddPage(self.consoleTab, "Output")
|
||||
self._notebook.AddPage(self.framesTab, "Frames")
|
||||
self._notebook.AddPage(self.breakPointsTab, "Break Points")
|
||||
|
||||
self.framesTab = self.MakeFramesUI(self, wx.NewId(), None)
|
||||
sizer.Add(self.framesTab, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self._statusBar = wx.StatusBar( self, -1)
|
||||
self._statusBar.SetFieldsCount(1)
|
||||
sizer.Add(self._statusBar, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
|
||||
@@ -509,6 +504,7 @@ class DebugCommandUI(wx.Panel):
|
||||
self.SetStatusText("Starting debug...")
|
||||
|
||||
self.SetSizer(sizer)
|
||||
tb.Realize()
|
||||
sizer.Fit(self)
|
||||
config = wx.ConfigBase_Get()
|
||||
self._debuggerHost = self._guiHost = config.Read("DebuggerHostName", DEFAULT_HOST)
|
||||
@@ -550,14 +546,12 @@ class DebugCommandUI(wx.Panel):
|
||||
def BreakPointChange(self):
|
||||
if not self._stopped:
|
||||
self._callback.pushBreakpoints()
|
||||
self.breakPointsTab.PopulateBPList()
|
||||
self.framesTab.PopulateBPList()
|
||||
|
||||
def __del__(self):
|
||||
if self in DebugCommandUI.debuggers:
|
||||
DebugCommandUI.debuggers.remove(self)
|
||||
|
||||
def SwitchToOutputTab(self):
|
||||
self._notebook.SetSelection(0)
|
||||
|
||||
def DisableWhileDebuggerRunning(self):
|
||||
self._tb.EnableTool(self.STEP_ID, False)
|
||||
@@ -573,7 +567,6 @@ class DebugCommandUI(wx.Panel):
|
||||
openDoc.GetFirstView().GetCtrl().ClearCurrentLineMarkers()
|
||||
if self.framesTab:
|
||||
self.framesTab.ClearWhileRunning()
|
||||
#wx.GetApp().ProcessPendingEvents() #Yield(True)
|
||||
|
||||
def EnableWhileDebuggerStopped(self):
|
||||
self._tb.EnableTool(self.STEP_ID, True)
|
||||
@@ -583,8 +576,6 @@ class DebugCommandUI(wx.Panel):
|
||||
if _WATCHES_ON:
|
||||
self._tb.EnableTool(self.ADD_WATCH_ID, True)
|
||||
self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
|
||||
#if _WINDOWS:
|
||||
# wx.GetApp().GetTopWindow().RequestUserAttention()
|
||||
|
||||
def ExecutorFinished(self):
|
||||
if _VERBOSE: print "In ExectorFinished"
|
||||
@@ -687,62 +678,27 @@ class DebugCommandUI(wx.Panel):
|
||||
DebugCommandUI.debuggers.remove(self)
|
||||
index = self._parentNoteBook.GetSelection()
|
||||
self._parentNoteBook.GetPage(index).Show(False)
|
||||
self._parentNoteBook.RemovePage(index)
|
||||
|
||||
def GetConsoleTextControl(self):
|
||||
return self._textCtrl
|
||||
|
||||
def OnClearOutput(self, event):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.ClearAll()
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
self._parentNoteBook.RemovePage(index)
|
||||
|
||||
def OnAddWatch(self, event):
|
||||
if self.framesTab:
|
||||
self.framesTab.OnWatch(event)
|
||||
|
||||
def MakeConsoleTab(self, parent, id, debugger):
|
||||
panel = wx.Panel(parent, id)
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self._textCtrl = STCTextEditor.TextCtrl(panel, wx.NewId())
|
||||
sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self._textCtrl.SetViewLineNumbers(False)
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
if wx.Platform == '__WXMSW__':
|
||||
font = "Courier New"
|
||||
else:
|
||||
font = "Courier"
|
||||
self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
|
||||
self._textCtrl.SetFontColor(wx.BLACK)
|
||||
self._textCtrl.StyleClearAll()
|
||||
panel.SetSizer(sizer)
|
||||
sizer.Fit(panel)
|
||||
|
||||
return panel
|
||||
|
||||
def MakeFramesTab(self, parent, id, debugger):
|
||||
|
||||
def MakeFramesUI(self, parent, id, debugger):
|
||||
panel = FramesUI(parent, id, self)
|
||||
return panel
|
||||
|
||||
def MakeBreakPointsTab(self, parent, id, debugger):
|
||||
panel = BreakpointsUI(parent, id, self)
|
||||
return panel
|
||||
|
||||
def AppendText(self, event):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.AddText(event.value)
|
||||
self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
self.framesTab.AppendText(event.value)
|
||||
|
||||
def AppendErrorText(self, event):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.SetFontColor(wx.RED)
|
||||
self._textCtrl.StyleClearAll()
|
||||
self._textCtrl.AddText(event.value)
|
||||
self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
|
||||
self._textCtrl.SetFontColor(wx.BLACK)
|
||||
self._textCtrl.StyleClearAll()
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
self.framesTab.AppendErrorText(event.value)
|
||||
|
||||
def OnClearOutput(self, event):
|
||||
self.framesTab.ClearOutput()
|
||||
|
||||
def SwitchToOutputTab(self):
|
||||
self.framesTab.SwitchToOutputTab()
|
||||
|
||||
class BreakpointsUI(wx.Panel):
|
||||
def __init__(self, parent, id, ui):
|
||||
@@ -753,7 +709,6 @@ class BreakpointsUI(wx.Panel):
|
||||
self.Bind(wx.EVT_MENU, self.ClearBreakPoint, id=self.clearBPID)
|
||||
self.syncLineID = wx.NewId()
|
||||
self.Bind(wx.EVT_MENU, self.SyncBPLine, id=self.syncLineID)
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
p1 = self
|
||||
self._bpListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(1000,1000), style=wx.LC_REPORT)
|
||||
@@ -767,6 +722,11 @@ class BreakpointsUI(wx.Panel):
|
||||
self._bpListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
|
||||
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._bpListCtrl)
|
||||
self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._bpListCtrl)
|
||||
|
||||
def OnLeftDoubleClick(event):
|
||||
self.SyncBPLine(event)
|
||||
|
||||
wx.EVT_LEFT_DCLICK(self._bpListCtrl, OnLeftDoubleClick)
|
||||
|
||||
self.PopulateBPList()
|
||||
|
||||
@@ -903,25 +863,24 @@ class FramesUI(wx.SplitterWindow):
|
||||
def __init__(self, parent, id, ui):
|
||||
wx.SplitterWindow.__init__(self, parent, id, style = wx.SP_3D)
|
||||
self._ui = ui
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
self._p1 = p1 = wx.ScrolledWindow(self, -1)
|
||||
p1.Bind(wx.EVT_SIZE, self.OnSize)
|
||||
|
||||
self._framesListCtrl = wx.ListCtrl(p1, -1, pos=wx.DefaultPosition, size=(250,150), style=wx.LC_REPORT)
|
||||
sizer.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self._framesListCtrl.InsertColumn(0, "Frame")
|
||||
self._framesListCtrl.SetColumnWidth(0, 250)
|
||||
self._framesListCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
|
||||
self.Bind(wx.EVT_LIST_ITEM_SELECTED, self.ListItemSelected, self._framesListCtrl)
|
||||
self.Bind(wx.EVT_LIST_ITEM_DESELECTED, self.ListItemDeselected, self._framesListCtrl)
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
framesLabel = wx.StaticText(self, -1, "Stack Frame:")
|
||||
sizer.Add(framesLabel, 0, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.LEFT, border=2)
|
||||
|
||||
self._framesChoiceCtrl = wx.Choice(p1, -1, choices=[" "])
|
||||
sizer.Add(self._framesChoiceCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self._framesChoiceCtrl.Bind(wx.EVT_LIST_ITEM_RIGHT_CLICK, self.OnListRightClick)
|
||||
self.Bind(wx.EVT_CHOICE, self.ListItemSelected, self._framesChoiceCtrl)
|
||||
|
||||
sizer2 = wx.BoxSizer(wx.VERTICAL)
|
||||
self._p2 = p2 = wx.ScrolledWindow(self, -1)
|
||||
p2.Bind(wx.EVT_SIZE, self.OnSize)
|
||||
|
||||
self._treeCtrl = wx.gizmos.TreeListCtrl(p2, -1, size=(530,250), style=wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT)
|
||||
p1.SetSizer(sizer2)
|
||||
|
||||
self._treeCtrl = wx.gizmos.TreeListCtrl(p1, -1, style=wx.TR_DEFAULT_STYLE| wx.TR_FULL_ROW_HIGHLIGHT)
|
||||
self._treeCtrl.Bind(wx.EVT_TREE_ITEM_RIGHT_CLICK, self.OnRightClick)
|
||||
sizer2.Add(self._framesListCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
sizer2.Add(sizer, 0, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
sizer2.Add(self._treeCtrl,1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
tree = self._treeCtrl
|
||||
tree.AddColumn("Thing")
|
||||
tree.AddColumn("Value")
|
||||
@@ -930,11 +889,80 @@ class FramesUI(wx.SplitterWindow):
|
||||
tree.SetColumnWidth(1, 355)
|
||||
self._root = tree.AddRoot("Frame")
|
||||
tree.SetItemText(self._root, "", 1)
|
||||
tree.Bind(wx.EVT_TREE_ITEM_EXPANDING, self.IntrospectCallback)
|
||||
|
||||
self._p2 = p2 = wx.Window(self, -1)
|
||||
sizer3 = wx.BoxSizer(wx.HORIZONTAL)
|
||||
p2.SetSizer(sizer3)
|
||||
p2.Bind(wx.EVT_SIZE, self.OnSize)
|
||||
self._notebook = wx.Notebook(p2, -1, size=(20,20))
|
||||
self._notebook.Hide()
|
||||
sizer3.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||
self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId())
|
||||
#self.inspectConsoleTab = self.MakeInspectConsoleTab(self._notebook, wx.NewId())
|
||||
self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId())
|
||||
self._notebook.AddPage(self.consoleTab, "Output")
|
||||
#self._notebook.AddPage(self.inspectConsoleTab, "Interact")
|
||||
self._notebook.AddPage(self.breakPointsTab, "Break Points")
|
||||
|
||||
self.SetMinimumPaneSize(20)
|
||||
self.SplitVertically(p1, p2, 250)
|
||||
self.SplitVertically(p1, p2, 550)
|
||||
self.currentItem = None
|
||||
self.Layout()
|
||||
self._notebook.Show(True)
|
||||
|
||||
def PopulateBPList(self):
|
||||
self.breakPointsTab.PopulateBPList()
|
||||
|
||||
def OnSize(self, event):
|
||||
self._notebook.SetSize(self._p2.GetSize())
|
||||
|
||||
def MakeConsoleTab(self, parent, id):
|
||||
panel = wx.Panel(parent, id)
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self._textCtrl = STCTextEditor.TextCtrl(panel, wx.NewId())
|
||||
sizer.Add(self._textCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 2)
|
||||
self._textCtrl.SetViewLineNumbers(False)
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
if wx.Platform == '__WXMSW__':
|
||||
font = "Courier New"
|
||||
else:
|
||||
font = "Courier"
|
||||
self._textCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
|
||||
self._textCtrl.SetFontColor(wx.BLACK)
|
||||
self._textCtrl.StyleClearAll()
|
||||
panel.SetSizer(sizer)
|
||||
#sizer.Fit(panel)
|
||||
|
||||
return panel
|
||||
|
||||
def MakeInspectConsoleTab(self, parent, id):
|
||||
def OnEnterPressed(event):
|
||||
print "Enter text was %s" % event.GetString()
|
||||
def OnText(event):
|
||||
print "Command was %s" % event.GetString()
|
||||
|
||||
panel = wx.Panel(parent, id)
|
||||
try:
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
self._ictextCtrl = wx.TextCtrl(panel, wx.NewId(), style=wx.TE_MULTILINE|wx.TE_RICH|wx.HSCROLL)
|
||||
sizer.Add(self._ictextCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 2)
|
||||
self._ictextCtrl.Bind(wx.EVT_TEXT_ENTER, OnEnterPressed)
|
||||
self._ictextCtrl.Bind(wx.EVT_TEXT, OnText)
|
||||
if wx.Platform == '__WXMSW__':
|
||||
font = "Courier New"
|
||||
else:
|
||||
font = "Courier"
|
||||
self._ictextCtrl.SetDefaultStyle(wx.TextAttr(font=wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font)))
|
||||
panel.SetSizer(sizer)
|
||||
except:
|
||||
tp, val, tb = sys.exc_info()
|
||||
traceback.print_exception(tp, val, tb)
|
||||
|
||||
return panel
|
||||
|
||||
def MakeBreakPointsTab(self, parent, id):
|
||||
panel = BreakpointsUI(parent, id, self._ui)
|
||||
return panel
|
||||
|
||||
def OnRightClick(self, event):
|
||||
#Refactor this...
|
||||
@@ -944,13 +972,6 @@ class FramesUI(wx.SplitterWindow):
|
||||
if not _WATCHES_ON and watchOnly:
|
||||
return
|
||||
menu = wx.Menu()
|
||||
if not watchOnly:
|
||||
if not hasattr(self, "introspectID"):
|
||||
self.introspectID = wx.NewId()
|
||||
self.Bind(wx.EVT_MENU, self.OnIntrospect, id=self.introspectID)
|
||||
item = wx.MenuItem(menu, self.introspectID, "Attempt Introspection")
|
||||
menu.AppendItem(item)
|
||||
menu.AppendSeparator()
|
||||
if _WATCHES_ON:
|
||||
if not hasattr(self, "watchID"):
|
||||
self.watchID = wx.NewId()
|
||||
@@ -1016,13 +1037,13 @@ class FramesUI(wx.SplitterWindow):
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
try:
|
||||
list = self._framesListCtrl
|
||||
list = self._framesChoiceCtrl
|
||||
frameNode = self._stack[int(self.currentItem)]
|
||||
message = frameNode.getAttribute("message")
|
||||
binType = self._ui._callback._debuggerServer.attempt_introspection(message, self._parentChain)
|
||||
xmldoc = bz2.decompress(binType.data)
|
||||
|
||||
domDoc = parseString(xmldoc)
|
||||
#wx.MessageBox(xmldoc, "result of introspection")
|
||||
nodeList = domDoc.getElementsByTagName('replacement')
|
||||
replacementNode = nodeList.item(0)
|
||||
if len(replacementNode.childNodes):
|
||||
@@ -1030,6 +1051,7 @@ class FramesUI(wx.SplitterWindow):
|
||||
tree = self._treeCtrl
|
||||
parent = tree.GetItemParent(self._introspectItem)
|
||||
treeNode = self.AppendSubTreeFromNode(thingToWalk, thingToWalk.getAttribute('name'), parent, insertBefore=self._introspectItem)
|
||||
self._treeCtrl.Expand(treeNode)
|
||||
tree.Delete(self._introspectItem)
|
||||
except:
|
||||
tp,val,tb = sys.exc_info()
|
||||
@@ -1037,16 +1059,15 @@ class FramesUI(wx.SplitterWindow):
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
|
||||
def OnSize(self, event):
|
||||
self._treeCtrl.SetSize(self._p2.GetSize())
|
||||
w,h = self._p1.GetClientSizeTuple()
|
||||
self._framesListCtrl.SetDimensions(0, 0, w, h)
|
||||
|
||||
def ClearWhileRunning(self):
|
||||
list = self._framesListCtrl
|
||||
list.DeleteAllItems()
|
||||
tree = self._treeCtrl
|
||||
tree.Hide()
|
||||
list = self._framesChoiceCtrl
|
||||
list.Clear()
|
||||
list.Enable(False)
|
||||
tree = self._treeCtrl
|
||||
root = self._root
|
||||
tree.DeleteChildren(root)
|
||||
|
||||
#tree.Hide()
|
||||
|
||||
def OnListRightClick(self, event):
|
||||
if not hasattr(self, "syncFrameID"):
|
||||
@@ -1059,7 +1080,7 @@ class FramesUI(wx.SplitterWindow):
|
||||
menu.Destroy()
|
||||
|
||||
def OnSyncFrame(self, event):
|
||||
list = self._framesListCtrl
|
||||
list = self._framesChoiceCtrl
|
||||
frameNode = self._stack[int(self.currentItem)]
|
||||
file = frameNode.getAttribute("file")
|
||||
line = frameNode.getAttribute("line")
|
||||
@@ -1069,18 +1090,24 @@ class FramesUI(wx.SplitterWindow):
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
try:
|
||||
domDoc = parseString(framesXML)
|
||||
list = self._framesListCtrl
|
||||
list.DeleteAllItems()
|
||||
list = self._framesChoiceCtrl
|
||||
list.Clear()
|
||||
self._stack = []
|
||||
nodeList = domDoc.getElementsByTagName('frame')
|
||||
frame_count = -1
|
||||
for index in range(0, nodeList.length):
|
||||
frameNode = nodeList.item(index)
|
||||
message = frameNode.getAttribute("message")
|
||||
list.InsertStringItem(index, message)
|
||||
list.Append(message)
|
||||
self._stack.append(frameNode)
|
||||
frame_count += 1
|
||||
list.Select(frame_count)
|
||||
index = len(self._stack) - 1
|
||||
list.SetSelection(index)
|
||||
node = self._stack[index]
|
||||
self.currentItem = index
|
||||
self.PopulateTreeFromFrameNode(node)
|
||||
self.OnSyncFrame(None)
|
||||
|
||||
self._p1.FitInside()
|
||||
frameNode = nodeList.item(index)
|
||||
file = frameNode.getAttribute("file")
|
||||
@@ -1092,19 +1119,23 @@ class FramesUI(wx.SplitterWindow):
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
|
||||
def ListItemDeselected(self, event):
|
||||
pass
|
||||
|
||||
def ListItemSelected(self, event):
|
||||
self.currentItem = event.m_itemIndex
|
||||
frameNode = self._stack[int(self.currentItem)]
|
||||
self.PopulateTreeFromFrameNode(frameNode)
|
||||
# Temporarily doing this to test out automatically swicting to source line.
|
||||
self.OnSyncFrame(None)
|
||||
|
||||
message = event.GetString()
|
||||
index = 0
|
||||
for node in self._stack:
|
||||
if node.getAttribute("message") == message:
|
||||
self.currentItem = index
|
||||
self.PopulateTreeFromFrameNode(node)
|
||||
self.OnSyncFrame(None)
|
||||
return
|
||||
index = index + 1
|
||||
|
||||
def PopulateTreeFromFrameNode(self, frameNode):
|
||||
list = self._framesChoiceCtrl
|
||||
list.Enable(True)
|
||||
tree = self._treeCtrl
|
||||
tree.Show(True)
|
||||
#tree.Show(True)
|
||||
root = self._root
|
||||
tree.DeleteChildren(root)
|
||||
children = frameNode.childNodes
|
||||
@@ -1117,6 +1148,19 @@ class FramesUI(wx.SplitterWindow):
|
||||
tree.Expand(root)
|
||||
tree.Expand(firstChild)
|
||||
self._p2.FitInside()
|
||||
|
||||
def IntrospectCallback(self, event):
|
||||
tree = self._treeCtrl
|
||||
item = event.GetItem()
|
||||
if _VERBOSE:
|
||||
print "In introspectCallback item is %s, pydata is %s" % (event.GetItem(), tree.GetPyData(item))
|
||||
if tree.GetPyData(item) != "Introspect":
|
||||
event.Skip()
|
||||
return
|
||||
self._introspectItem = item
|
||||
self._parentChain = self.GetItemChain(item)
|
||||
self.OnIntrospect(event)
|
||||
event.Skip()
|
||||
|
||||
def AppendSubTreeFromNode(self, node, name, parent, insertBefore=None):
|
||||
tree = self._treeCtrl
|
||||
@@ -1125,7 +1169,12 @@ class FramesUI(wx.SplitterWindow):
|
||||
else:
|
||||
treeNode = tree.AppendItem(parent, name)
|
||||
children = node.childNodes
|
||||
if children.length == 0:
|
||||
intro = node.getAttribute('intro')
|
||||
|
||||
if intro == "True":
|
||||
tree.SetItemHasChildren(treeNode, True)
|
||||
tree.SetPyData(treeNode, "Introspect")
|
||||
if node.getAttribute("value"):
|
||||
tree.SetItemText(treeNode, self.StripOuterSingleQuotes(node.getAttribute("value")), 1)
|
||||
for index in range(0, children.length):
|
||||
subNode = children.item(index)
|
||||
@@ -1136,15 +1185,23 @@ class FramesUI(wx.SplitterWindow):
|
||||
value = self.StripOuterSingleQuotes(subNode.getAttribute("value"))
|
||||
n = tree.AppendItem(treeNode, name)
|
||||
tree.SetItemText(n, value, 1)
|
||||
intro = subNode.getAttribute('intro')
|
||||
if intro == "True":
|
||||
tree.SetItemHasChildren(n, True)
|
||||
tree.SetPyData(n, "Introspect")
|
||||
|
||||
return treeNode
|
||||
|
||||
def StripOuterSingleQuotes(self, string):
|
||||
if string.startswith("'") and string.endswith("'"):
|
||||
return string[1:-1]
|
||||
elif type(string) == types.UnicodeType:
|
||||
return string[1:-1]
|
||||
retval = string[1:-1]
|
||||
elif string.startswith("\"") and string.endswith("\""):
|
||||
retval = string[1:-1]
|
||||
else:
|
||||
return string
|
||||
retval = string
|
||||
if retval.startswith("u'") and retval.endswith("'"):
|
||||
retval = retval[1:]
|
||||
return retval
|
||||
|
||||
def HasChildren(self, node):
|
||||
try:
|
||||
@@ -1152,7 +1209,31 @@ class FramesUI(wx.SplitterWindow):
|
||||
except:
|
||||
tp,val,tb=sys.exc_info()
|
||||
return False
|
||||
|
||||
|
||||
def AppendText(self, text):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.AddText(text)
|
||||
self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
|
||||
def AppendErrorText(self, text):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.SetFontColor(wx.RED)
|
||||
self._textCtrl.StyleClearAll()
|
||||
self._textCtrl.AddText(text)
|
||||
self._textCtrl.ScrollToLine(self._textCtrl.GetLineCount())
|
||||
self._textCtrl.SetFontColor(wx.BLACK)
|
||||
self._textCtrl.StyleClearAll()
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
|
||||
def ClearOutput(self, event):
|
||||
self._textCtrl.SetReadOnly(False)
|
||||
self._textCtrl.ClearAll()
|
||||
self._textCtrl.SetReadOnly(True)
|
||||
|
||||
def SwitchToOutputTab(self):
|
||||
self._notebook.SetSelection(0)
|
||||
|
||||
class DebuggerView(Service.ServiceView):
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
@@ -1417,6 +1498,7 @@ class DebuggerCallback:
|
||||
if _VERBOSE: print "+"*40
|
||||
|
||||
class DebuggerService(Service.Service):
|
||||
executors = []
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
@@ -1427,6 +1509,12 @@ class DebuggerService(Service.Service):
|
||||
DEBUG_ID = wx.NewId()
|
||||
DEBUG_WEBSERVER_ID = wx.NewId()
|
||||
|
||||
def KillAllRunningProcesses():
|
||||
execs = DebuggerService.executors
|
||||
for executor in execs:
|
||||
executor.DoStopExecution()
|
||||
KillAllRunningProcesses = staticmethod(KillAllRunningProcesses)
|
||||
|
||||
def ComparePaths(first, second):
|
||||
one = DebuggerService.ExpandPath(first)
|
||||
two = DebuggerService.ExpandPath(second)
|
||||
@@ -1614,6 +1702,14 @@ class DebuggerService(Service.Service):
|
||||
pass
|
||||
|
||||
def OnDebugWebServer(self, event):
|
||||
if _WINDOWS and not _PYWIN32_INSTALLED:
|
||||
wx.MessageBox(_("Python for Windows extensions (pywin32) is required to debug on Windows machines. Please go to http://sourceforge.net/projects/pywin32/, download and install pywin32."))
|
||||
return
|
||||
if not Executor.GetPythonExecutablePath():
|
||||
return
|
||||
if DebugCommandUI.DebuggerRunning():
|
||||
wx.MessageBox(_("A debugger is already running. Please shut down the other debugger first."), _("Debugger Running"))
|
||||
return
|
||||
import WebServerService
|
||||
wsService = wx.GetApp().GetService(WebServerService.WebServerService)
|
||||
fileName, args = wsService.StopAndPrepareToDebug()
|
||||
|
@@ -103,7 +103,7 @@ class FindInDirService(FindService.FindService):
|
||||
dirCtrl = wx.TextCtrl(frame, -1, config.Read(FIND_MATCHDIR, ""), size=(200,-1))
|
||||
dirCtrl.SetToolTipString(dirCtrl.GetValue())
|
||||
lineSizer.Add(dirCtrl, 0, wx.LEFT, HALF_SPACE)
|
||||
findDirButton = wx.Button(frame, -1, "Browse...")
|
||||
findDirButton = wx.Button(frame, -1, _("Browse..."))
|
||||
lineSizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
|
||||
|
||||
|
@@ -16,6 +16,8 @@ import wx.lib.pydocview
|
||||
import sys
|
||||
import wx.grid
|
||||
import os.path
|
||||
import activegrid.util
|
||||
|
||||
_ = wx.GetTranslation
|
||||
ACTIVEGRID_BASE_IDE = False
|
||||
|
||||
@@ -77,7 +79,11 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
import PHPEditor
|
||||
import wx.lib.ogl as ogl
|
||||
import DebuggerService
|
||||
import atexit
|
||||
atexit.register(DebuggerService.DebuggerService.KillAllRunningProcesses)
|
||||
import AboutDialog
|
||||
import SVNService
|
||||
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
import DataModelEditor
|
||||
import ProcessModelEditor
|
||||
@@ -87,7 +93,7 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
import WelcomeService
|
||||
import ViewEditor
|
||||
import PropertyService
|
||||
|
||||
|
||||
|
||||
# This creates some pens and brushes that the OGL library uses.
|
||||
# It should be called after the app object has been created, but
|
||||
@@ -287,8 +293,9 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
deploymentService = self.InstallService(DeploymentService.DeploymentService())
|
||||
dataModelService = self.InstallService(DataModelEditor.DataModelService())
|
||||
welcomeService = self.InstallService(WelcomeService.WelcomeService())
|
||||
optionsService = self.InstallService(wx.lib.pydocview.DocOptionsService(allowModeChanges=False))
|
||||
optionsService = self.InstallService(wx.lib.pydocview.DocOptionsService(supportedModes=wx.lib.docview.DOC_MDI))
|
||||
aboutService = self.InstallService(wx.lib.pydocview.AboutService(AboutDialog.AboutDialog))
|
||||
svnService = self.InstallService(SVNService.SVNService())
|
||||
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
projectService.AddRunHandler(processModelService)
|
||||
@@ -307,6 +314,7 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
optionsService.AddOptionsPanel(PHPEditor.PHPOptionsPanel)
|
||||
optionsService.AddOptionsPanel(STCTextEditor.TextOptionsPanel)
|
||||
optionsService.AddOptionsPanel(HtmlEditor.HtmlOptionsPanel)
|
||||
optionsService.AddOptionsPanel(SVNService.SVNOptionsPanel)
|
||||
|
||||
filePropertiesService.AddCustomEventHandler(projectService)
|
||||
|
||||
@@ -326,7 +334,6 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
propertyService.StartBackgroundTimer()
|
||||
|
||||
self.SetDefaultIcon(getActiveGridIcon())
|
||||
self.SetUseTabbedMDI(True)
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
embeddedWindows = wx.lib.pydocview.EMBEDDED_WINDOW_TOPLEFT | wx.lib.pydocview.EMBEDDED_WINDOW_BOTTOMLEFT |wx.lib.pydocview.EMBEDDED_WINDOW_BOTTOM | wx.lib.pydocview.EMBEDDED_WINDOW_RIGHT
|
||||
else:
|
||||
@@ -343,14 +350,18 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
||||
|
||||
if not projectService.OpenSavedProjects() and not docManager.GetDocuments() and self.IsSDI(): # Have to open something if it's SDI and there are no projects...
|
||||
projectTemplate.CreateDocument('', wx.lib.docview.DOC_NEW).OnNewDocument()
|
||||
|
||||
|
||||
TIPS_FILE_PARTS = ("activegrid", "tool", "data", "tips.txt")
|
||||
tips_path = activegrid.util.mainModuleDir
|
||||
for segment in TIPS_FILE_PARTS:
|
||||
tips_path = os.path.join(tips_path, segment)
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
if not welcomeService.RunWelcomeIfFirstTime():
|
||||
if os.path.exists("activegrid/tool/data/tips.txt"):
|
||||
wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider("activegrid/tool/data/tips.txt", 0))
|
||||
if os.path.exists(tips_path):
|
||||
wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider(tips_path, 0))
|
||||
else:
|
||||
if os.path.exists("activegrid/tool/data/tips.txt"):
|
||||
wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider("activegrid/tool/data/tips.txt", 0))
|
||||
if os.path.exists(tips_path):
|
||||
wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider(tips_path, 0))
|
||||
|
||||
wx.UpdateUIEvent.SetUpdateInterval(200) # Overhead of updating menus was too much. Change to update every 200 milliseconds.
|
||||
|
||||
|
@@ -84,6 +84,7 @@ class OutlineView(Service.ServiceView):
|
||||
item = self.GetControl().GetSelection()
|
||||
if item:
|
||||
self.GetControl().CallDoSelectCallback(item)
|
||||
event.Skip()
|
||||
|
||||
|
||||
def ResumeActionOnSelect(self):
|
||||
|
@@ -153,7 +153,7 @@ class PHPCtrl(CodeEditor.CodeCtrl):
|
||||
|
||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
||||
self.SetLexer(wx.stc.STC_LEX_HTML)
|
||||
self.SetLexer(wx.stc.STC_LEX_PHP)
|
||||
self.SetStyleBits(7)
|
||||
self.SetKeyWords(4, string.join(PHPKEYWORDS))
|
||||
self.SetProperty("fold.html", "1")
|
||||
|
@@ -23,9 +23,11 @@ import sys
|
||||
import activegrid.util.xmlmarshaller
|
||||
import UICommon
|
||||
import Wizard
|
||||
import SVNService
|
||||
from IDE import ACTIVEGRID_BASE_IDE
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
import ProcessModelEditor
|
||||
from SVNService import SVN_INSTALLED
|
||||
|
||||
_ = wx.GetTranslation
|
||||
|
||||
@@ -127,6 +129,8 @@ class ProjectDocument(wx.lib.docview.Document):
|
||||
for path in paths:
|
||||
if path.startswith(curPath):
|
||||
path = "." + path[curPathLen:] # use relative path
|
||||
if os.sep != '/':
|
||||
path = path.replace(os.sep, '/', -1) # always save out with '/' as path separator for cross-platform compatibility.
|
||||
else:
|
||||
pass # use absolute path
|
||||
newFilePaths.append(path)
|
||||
@@ -909,7 +913,16 @@ class ProjectView(wx.lib.docview.View):
|
||||
def GetSelectedFile(self):
|
||||
for item in self._treeCtrl.GetSelections():
|
||||
return self._GetItemFile(item)
|
||||
|
||||
|
||||
def GetSelectedFiles(self):
|
||||
filenames = []
|
||||
for item in self._treeCtrl.GetSelections():
|
||||
filename = self._GetItemFile(item)
|
||||
if filename and filename not in filenames:
|
||||
filenames.append(filename)
|
||||
return filenames
|
||||
|
||||
|
||||
def AddProjectToView(self, document):
|
||||
rootItem = self._treeCtrl.GetRootItem()
|
||||
@@ -927,6 +940,17 @@ class ProjectView(wx.lib.docview.View):
|
||||
document.GetCommandProcessor().SetEditMenu(wx.GetApp().GetEditMenu(self._GetParentFrame()))
|
||||
|
||||
|
||||
def HasFocus(self):
|
||||
winWithFocus = wx.Window.FindFocus()
|
||||
if not winWithFocus:
|
||||
return False
|
||||
while winWithFocus:
|
||||
if winWithFocus == self._treeCtrl:
|
||||
return True
|
||||
winWithFocus = winWithFocus.GetParent()
|
||||
return False
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Control events
|
||||
#----------------------------------------------------------------------------
|
||||
@@ -980,7 +1004,7 @@ class ProjectView(wx.lib.docview.View):
|
||||
|
||||
|
||||
def OnAddDirToProject(self, event):
|
||||
frame = wx.Dialog(None, -1, _("Add All Files from Directory to Project"), size= (320,200))
|
||||
frame = wx.Dialog(None, -1, _("Add Directory Files to Project"), size= (320,200))
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
flexGridSizer = wx.FlexGridSizer(cols = 2, vgap=HALF_SPACE, hgap=HALF_SPACE)
|
||||
@@ -989,7 +1013,7 @@ class ProjectView(wx.lib.docview.View):
|
||||
dirCtrl = wx.TextCtrl(frame, -1, os.path.dirname(self.GetDocument().GetFilename()), size=(250,-1))
|
||||
dirCtrl.SetToolTipString(dirCtrl.GetValue())
|
||||
lineSizer.Add(dirCtrl, 1, wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||
findDirButton = wx.Button(frame, -1, "Browse...")
|
||||
findDirButton = wx.Button(frame, -1, _("Browse..."))
|
||||
lineSizer.Add(findDirButton, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, HALF_SPACE)
|
||||
flexGridSizer.Add(lineSizer, 1, wx.EXPAND)
|
||||
|
||||
@@ -1178,7 +1202,10 @@ class ProjectView(wx.lib.docview.View):
|
||||
else: # Project context
|
||||
itemIDs = [wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS, None]
|
||||
menuBar = self._GetParentFrame().GetMenuBar()
|
||||
itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT, None, wx.ID_UNDO, wx.ID_REDO, None, wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL, ProjectService.RENAME_ID, ProjectService.DELETE_FILE_ID, None, wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID]
|
||||
itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT]
|
||||
if SVN_INSTALLED:
|
||||
itemIDs = itemIDs + [None, SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
|
||||
itemIDs = itemIDs + [None, wx.ID_UNDO, wx.ID_REDO, None, wx.ID_CUT, wx.ID_COPY, wx.ID_PASTE, wx.ID_CLEAR, None, wx.ID_SELECTALL, ProjectService.RENAME_ID, ProjectService.DELETE_FILE_ID, None, wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID]
|
||||
for itemID in itemIDs:
|
||||
if not itemID:
|
||||
menu.AppendSeparator()
|
||||
@@ -1384,8 +1411,9 @@ class ProjectView(wx.lib.docview.View):
|
||||
findFile.Destroy()
|
||||
if newpath:
|
||||
# update Project Model with new location
|
||||
self.GetDocument().RemoveFile(filepath)
|
||||
self.GetDocument().AddFile(newpath)
|
||||
project = self._GetItemProject(item)
|
||||
project.RemoveFile(filepath)
|
||||
project.AddFile(newpath)
|
||||
filepath = newpath
|
||||
|
||||
doc = self.GetDocumentManager().CreateDocument(filepath, wx.lib.docview.DOC_SILENT)
|
||||
@@ -1614,9 +1642,8 @@ class ProjectPropertiesDialog(wx.Dialog):
|
||||
sizer.Add(notebook, 0, wx.ALL | wx.EXPAND, SPACE)
|
||||
sizer.Add(self.CreateButtonSizer(wx.OK), 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.BOTTOM, HALF_SPACE)
|
||||
|
||||
sizer.Fit(self)
|
||||
self.SetDimensions(-1, -1, 310, -1, wx.SIZE_USE_EXISTING)
|
||||
self.SetSizer(sizer)
|
||||
sizer.Fit(self)
|
||||
self.Layout()
|
||||
|
||||
|
||||
@@ -1742,7 +1769,7 @@ class ProjectService(Service.Service):
|
||||
wx.EVT_MENU(frame, ProjectService.ADD_FILES_TO_PROJECT_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, ProjectService.ADD_FILES_TO_PROJECT_ID, frame.ProcessUpdateUIEvent)
|
||||
if not menuBar.FindItemById(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID):
|
||||
projectMenu.Append(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, _("Add All Files to Project..."), _("Adds a directory's documents to the current project"))
|
||||
projectMenu.Append(ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, _("Add Directory Files to Project..."), _("Adds a directory's documents to the current project"))
|
||||
wx.EVT_MENU(frame, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, frame.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, frame.ProcessUpdateUIEvent)
|
||||
if not menuBar.FindItemById(ProjectService.ADD_CURRENT_FILE_TO_PROJECT_ID):
|
||||
|
@@ -194,10 +194,15 @@ class TextView(wx.lib.docview.View):
|
||||
if activate and self.GetCtrl():
|
||||
# In MDI mode just calling set focus doesn't work and in SDI mode using CallAfter causes an endless loop
|
||||
if self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
|
||||
self.GetCtrl().SetFocus()
|
||||
self.SetFocus()
|
||||
else:
|
||||
wx.CallAfter(self.GetCtrl().SetFocus)
|
||||
|
||||
wx.CallAfter(self.SetFocus)
|
||||
|
||||
|
||||
def SetFocus(self):
|
||||
if self.GetCtrl():
|
||||
self.GetCtrl().SetFocus()
|
||||
|
||||
|
||||
def OnClose(self, deleteWindow = True):
|
||||
if not wx.lib.docview.View.OnClose(self, deleteWindow):
|
||||
|
736
wxPython/samples/ide/activegrid/tool/SVNService.py
Normal file
736
wxPython/samples/ide/activegrid/tool/SVNService.py
Normal file
@@ -0,0 +1,736 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: SVNService.py
|
||||
# Purpose: Subversion Service for pydocview
|
||||
#
|
||||
# Author: Morgan Hua
|
||||
#
|
||||
# Created: 5/13/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import wx
|
||||
import os.path
|
||||
import ProjectEditor
|
||||
import MessageService
|
||||
|
||||
import sys # for errors
|
||||
import traceback # for errors
|
||||
|
||||
try:
|
||||
import pysvn # python-subversion integration
|
||||
SVN_INSTALLED = True
|
||||
except ImportError:
|
||||
SVN_INSTALLED = False
|
||||
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
SVN_CONFIG_DIR = "SVNConfigDir"
|
||||
SVN_REPOSITORY_URL = "SVNRepositoryURL"
|
||||
|
||||
SPACE = 10
|
||||
HALF_SPACE = 5
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class SVNService(wx.lib.pydocview.DocService):
|
||||
SVN_UPDATE_ID = wx.NewId()
|
||||
SVN_CHECKIN_ID = wx.NewId()
|
||||
SVN_CHECKOUT_ID = wx.NewId()
|
||||
SVN_REVERT_ID = wx.NewId()
|
||||
SVN_ADD_ID = wx.NewId()
|
||||
SVN_DELETE_ID = wx.NewId()
|
||||
SVN_COMMAND_LIST = [SVN_UPDATE_ID, SVN_CHECKIN_ID, SVN_CHECKOUT_ID, SVN_REVERT_ID, SVN_ADD_ID, SVN_DELETE_ID]
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self._defaultURL = "svn://"
|
||||
|
||||
global SVN_INSTALLED
|
||||
if SVN_INSTALLED:
|
||||
config = wx.ConfigBase_Get()
|
||||
configDir = config.Read(SVN_CONFIG_DIR, "")
|
||||
|
||||
self._client = pysvn.Client(configDir)
|
||||
try:
|
||||
self._defaultURL = self._client.info('.').url
|
||||
except:
|
||||
pass
|
||||
self._client.callback_cancel = self.IfCancel
|
||||
self._client.callback_notify = self.UpdateStatus
|
||||
self._client.callback_get_log_message = self.GetLogMessage
|
||||
self._client.callback_get_login = self.GetLogin
|
||||
self._client.callback_ssl_server_trust_prompt = self.GetSSLServerTrust
|
||||
self._client.callback_ssl_client_cert_password_prompt = self.SSLClientPassword
|
||||
self._client.callback_ssl_client_cert_prompt = self.SSLClientCert
|
||||
self._client.callback_ssl_server_prompt = self.SSLServerPrompt
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# pysvn.Client() Callback Methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def IfCancel(self):
|
||||
""" return True if user wants to cancel current command """
|
||||
return False
|
||||
|
||||
|
||||
def UpdateStatus(self, eventDict):
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.AddLines(_("%s %s\n") % (eventDict['action'], eventDict['path']))
|
||||
|
||||
|
||||
def GetLogMessage(self):
|
||||
dlg = wx.TextEntryDialog(wx.GetApp().GetTopWindow(),
|
||||
_("Comment"),
|
||||
_("SVN Log Message"))
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
retcode = True
|
||||
message = dlg.GetValue()
|
||||
else:
|
||||
retcode = False
|
||||
message = _("Cancel Action")
|
||||
|
||||
dlg.Destroy()
|
||||
|
||||
return retcode, message
|
||||
|
||||
|
||||
def GetLogin(self, realm, username, maySave):
|
||||
dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Login"))
|
||||
|
||||
sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Username:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
usernameTxt = wx.TextCtrl(dlg, -1, username, size = (200, -1))
|
||||
sizer.Add(usernameTxt, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Password:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
passwordTxt = wx.TextCtrl(dlg, -1, size=(200, -1), style=wx.TE_PASSWORD)
|
||||
sizer.Add(passwordTxt, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
|
||||
savePasswordCheckbox = wx.CheckBox(dlg, -1, _("Remember Username and Password"))
|
||||
if not maySave:
|
||||
savePasswordCheckbox.Enable(False)
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
okBtn = wx.Button(dlg, wx.ID_OK)
|
||||
okBtn.SetDefault()
|
||||
buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
|
||||
buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
contentSizer.Add(sizer, 0, wx.LEFT|wx.TOP|wx.RIGHT, SPACE)
|
||||
contentSizer.Add(savePasswordCheckbox, 0, wx.TOP|wx.LEFT|wx.BOTTOM, SPACE)
|
||||
contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
|
||||
|
||||
dlg.SetSizer(contentSizer)
|
||||
dlg.Fit()
|
||||
dlg.Layout()
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
retcode = True
|
||||
username = usernameTxt.GetValue().strip()
|
||||
password = passwordTxt.GetValue()
|
||||
save = savePasswordCheckBox.IsChecked()
|
||||
else:
|
||||
retcode = False
|
||||
username = None
|
||||
password = None
|
||||
save = False
|
||||
|
||||
dlg.Destroy()
|
||||
return retcode, username, password, save
|
||||
|
||||
|
||||
def SSLServerPrompt(self):
|
||||
""" Not implemented, as per pysvn documentation """
|
||||
return
|
||||
|
||||
|
||||
def GetSSLServerTrust(self, trustDict):
|
||||
dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SSL Server Certificate"))
|
||||
|
||||
sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
||||
for k in ['hostname', 'valid_from', 'valid_to', 'issuer_dname', 'realm']:
|
||||
if trustDict.has_key(k):
|
||||
sizer.Add(wx.StaticText(dlg, -1, "%s:" % k), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
sizer.Add(wx.StaticText(dlg, -1, "%s" % trustDict[k]), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
|
||||
box = wx.StaticBoxSizer(wx.StaticBox(dlg, -1, _("Certificate Info")), wx.VERTICAL)
|
||||
box.Add(sizer, 0, wx.EXPAND)
|
||||
|
||||
certRadio = wx.RadioBox(dlg, -1, _("Certificate"), choices=[_("Accept Always"), _("Accept Once"), _("Reject")], majorDimension=1, style=wx.RA_SPECIFY_COLS)
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
okBtn = wx.Button(dlg, wx.ID_OK)
|
||||
okBtn.SetDefault()
|
||||
buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
|
||||
buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
contentSizer.Add(box, 0, wx.TOP|wx.LEFT|wx.RIGHT|wx.EXPAND, SPACE)
|
||||
contentSizer.Add(certRadio, 0, wx.TOP|wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, SPACE)
|
||||
contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
|
||||
|
||||
dlg.SetSizer(contentSizer)
|
||||
dlg.Fit()
|
||||
dlg.Layout()
|
||||
|
||||
# default values for reject
|
||||
retcode = False
|
||||
acceptedFailures = 0
|
||||
save = False
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
cert = certRadio.GetStringSelection()
|
||||
if cert == _("Accept Always"):
|
||||
retcode = True
|
||||
acceptedFailures = trustDict.get('failures')
|
||||
save = True
|
||||
elif cert == _("Accept Once"):
|
||||
retcode = True
|
||||
acceptedFailures = trustDict.get('failures')
|
||||
save = False
|
||||
|
||||
return retcode, acceptedFailures, save
|
||||
|
||||
|
||||
def SSLClientPassword(self, realm, maySave):
|
||||
dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SSL Client Certificate Login"))
|
||||
|
||||
sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Realm:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
sizer.Add(wx.StaticText(dlg, -1, realm), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Password:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
passwordTxt = wx.TextCtrl(dlg, -1, size=(200, -1), style=wx.TE_PASSWORD)
|
||||
sizer.Add(passwordTxt, 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
|
||||
savePasswordCheckbox = wx.CheckBox(dlg, -1, _("Remember Password"))
|
||||
if not maySave:
|
||||
savePasswordCheckbox.Enable(False)
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
okBtn = wx.Button(dlg, wx.ID_OK)
|
||||
okBtn.SetDefault()
|
||||
buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
|
||||
buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
contentSizer.Add(sizer, 0, wx.LEFT|wx.TOP|wx.RIGHT, SPACE)
|
||||
contentSizer.Add(savePasswordCheckbox, 0, wx.TOP|wx.LEFT|wx.BOTTOM, SPACE)
|
||||
contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
|
||||
|
||||
dlg.SetSizer(contentSizer)
|
||||
dlg.Fit()
|
||||
dlg.Layout()
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
retcode = True
|
||||
password = passwordTxt.GetValue()
|
||||
save = savePasswordCheckBox.IsChecked()
|
||||
else:
|
||||
retcode = False
|
||||
password = None
|
||||
save = False
|
||||
|
||||
dlg.Destroy()
|
||||
return retcode, password, save
|
||||
|
||||
|
||||
def SSLClientCert(self):
|
||||
dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
|
||||
message="Choose certificate", defaultDir=os.getcwd(),
|
||||
style=wx.OPEN|wx.CHANGE_DIR
|
||||
)
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
retcode = True
|
||||
certfile = dlg.GetPath()
|
||||
else:
|
||||
retcode = False
|
||||
certfile = None
|
||||
|
||||
dlg.Destroy()
|
||||
return retcode, certfile
|
||||
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Service Methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
|
||||
menu = menuBar.GetMenu(menuBar.FindMenu(_("Project")))
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
wx.EVT_MENU(frame, SVNService.SVN_UPDATE_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_UPDATE_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_UPDATE_ID, _("SVN Update"), _("Update file from Subversion"))
|
||||
wx.EVT_MENU(frame, SVNService.SVN_CHECKIN_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_CHECKIN_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_CHECKIN_ID, _("SVN Commit..."), _("Commit file changes to Subversion"))
|
||||
wx.EVT_MENU(frame, SVNService.SVN_CHECKOUT_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_CHECKOUT_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_CHECKOUT_ID, _("SVN Checkout..."), _("Checkout file from Subversion"))
|
||||
wx.EVT_MENU(frame, SVNService.SVN_REVERT_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_REVERT_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_REVERT_ID, _("SVN Revert"), _("Revert file from Subversion"))
|
||||
|
||||
menu.AppendSeparator()
|
||||
|
||||
wx.EVT_MENU(frame, SVNService.SVN_ADD_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_ADD_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_ADD_ID, _("SVN Add"), _("Add file to Subversion"))
|
||||
wx.EVT_MENU(frame, SVNService.SVN_DELETE_ID, self.ProcessEvent)
|
||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_DELETE_ID, self.ProcessUpdateUIEvent)
|
||||
menu.Append(SVNService.SVN_DELETE_ID, _("SVN Delete"), _("Delete file from Subversion"))
|
||||
|
||||
|
||||
def ProcessEvent(self, event):
|
||||
|
||||
id = event.GetId()
|
||||
|
||||
if not SVN_INSTALLED:
|
||||
if id in SVNService.SVN_COMMAND_LIST:
|
||||
wx.MessageBox(_("pysvn not found. Please install pysvn"), _("Python Subversion"))
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
if id == SVNService.SVN_UPDATE_ID:
|
||||
filenames = self.GetCurrentDocuments()
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Update:\n"))
|
||||
|
||||
for filename in filenames:
|
||||
view.AddLines("%s\n" % filename)
|
||||
try:
|
||||
status = self._client.update(filename)
|
||||
|
||||
if status.number > 0:
|
||||
view.AddLines(_("Updated to revision %s\n") % status.number)
|
||||
|
||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||
for doc in openDocs:
|
||||
if doc.GetFilename() == filename:
|
||||
yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
|
||||
_("Updated file '%s' is currently open. Close it?") % os.path.basename(filename),
|
||||
_("Close File"),
|
||||
wx.YES_NO|wx.ICON_QUESTION)
|
||||
if yesNoMsg.ShowModal() == wx.ID_YES:
|
||||
doc.DeleteAllViews()
|
||||
break
|
||||
else:
|
||||
view.AddLines(_("Update failed.\n"))
|
||||
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines("%s\n" % str(e))
|
||||
wx.MessageBox(str(e), _("SVN Update"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Update failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
|
||||
wx.MessageBox(_("Update failed."), _("SVN Update"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_CHECKIN_ID:
|
||||
filenames = self.GetCurrentDocuments()
|
||||
|
||||
# ask user if dirty files should be saved first
|
||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||
for filename in filenames:
|
||||
for doc in openDocs:
|
||||
if doc.GetFilename() == filename and doc.IsModified():
|
||||
yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
|
||||
_("'%s' has unsaved modifications. Save it before commit?") % os.path.basename(filename),
|
||||
_("SVN Commit"),
|
||||
wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
|
||||
status = yesNoMsg.ShowModal()
|
||||
if status == wx.ID_YES:
|
||||
doc.Save()
|
||||
elif status == wx.ID_NO:
|
||||
pass
|
||||
else: # elif status == wx.CANCEL:
|
||||
return True
|
||||
break
|
||||
|
||||
shortFilenames = []
|
||||
for i, filename in enumerate(filenames):
|
||||
shortFilename = os.path.basename(filename)
|
||||
shortFilenames.append(shortFilename)
|
||||
|
||||
dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Commit"))
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Comment:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
commentText = wx.TextCtrl(dlg, -1, size=(250,-1), style=wx.TE_MULTILINE)
|
||||
sizer.Add(commentText, 1, wx.EXPAND|wx.TOP, HALF_SPACE)
|
||||
|
||||
sizer.Add(wx.StaticText(dlg, -1, _("Files:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, SPACE)
|
||||
fileList = wx.CheckListBox(dlg, -1, choices = shortFilenames)
|
||||
for i in range(fileList.GetCount()):
|
||||
fileList.Check(i, True)
|
||||
sizer.Add(fileList, 0, wx.EXPAND|wx.TOP, HALF_SPACE)
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
okBtn = wx.Button(dlg, wx.ID_OK)
|
||||
okBtn.SetDefault()
|
||||
buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
|
||||
buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
contentSizer.Add(sizer, 0, wx.ALL, SPACE)
|
||||
contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
|
||||
|
||||
dlg.SetSizer(contentSizer)
|
||||
dlg.Fit()
|
||||
dlg.Layout()
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Commit:\n"))
|
||||
|
||||
try:
|
||||
selFilenames = []
|
||||
for i in range(fileList.GetCount()):
|
||||
if fileList.IsChecked(i):
|
||||
selFilenames.append(filenames[i])
|
||||
view.AddLines("%s\n" % filenames[i])
|
||||
|
||||
if len(selFilenames):
|
||||
comment = commentText.GetValue()
|
||||
status = self._client.checkin(selFilenames, comment)
|
||||
|
||||
if status is None:
|
||||
view.AddLines(_("Nothing to commit.\n"))
|
||||
elif status.number > 0:
|
||||
view.AddLines(_("Committed as revision %s.\n") % status.number)
|
||||
else:
|
||||
view.AddLines(_("Commit failed.\n"))
|
||||
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines("%s\n" % str(e))
|
||||
wx.MessageBox(str(e), _("SVN Commit"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Commit failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
wx.MessageBox(_("Commit failed."), _("SVN Commit"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
dlg.Destroy()
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_CHECKOUT_ID:
|
||||
config = wx.ConfigBase_Get()
|
||||
svnUrl = config.Read(SVN_REPOSITORY_URL, self._defaultURL)
|
||||
|
||||
dlg = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("SVN Checkout"))
|
||||
|
||||
gridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
||||
gridSizer.Add(wx.StaticText(dlg, -1, _("Repository URL:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, HALF_SPACE)
|
||||
svnURLText = wx.TextCtrl(dlg, -1, svnUrl, size = (200, -1))
|
||||
svnURLText.SetToolTipString(svnUrl)
|
||||
gridSizer.Add(svnURLText, 0)
|
||||
|
||||
gridSizer.Add(wx.StaticText(dlg, -1, _("Checkout to dir:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, HALF_SPACE)
|
||||
localPath = wx.TextCtrl(dlg, -1, size = (200, -1))
|
||||
localPath.SetToolTipString(_("Path in local file system where files will be located."))
|
||||
findDirButton = wx.Button(dlg, -1, _("Browse..."))
|
||||
|
||||
def OnBrowseButton(event):
|
||||
dirDlg = wx.DirDialog(wx.GetApp().GetTopWindow(), _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
|
||||
dir = localPath.GetValue()
|
||||
if len(dir):
|
||||
dirDlg.SetPath(dir)
|
||||
if dirDlg.ShowModal() == wx.ID_OK:
|
||||
localPath.SetValue(dirDlg.GetPath())
|
||||
localPath.SetToolTipString(localPath.GetValue())
|
||||
localPath.SetInsertionPointEnd()
|
||||
|
||||
dirDlg.Destroy()
|
||||
wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
|
||||
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sizer.Add(localPath, 1, wx.EXPAND)
|
||||
sizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||
gridSizer.Add(sizer, 0)
|
||||
|
||||
buttonSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
okBtn = wx.Button(dlg, wx.ID_OK)
|
||||
okBtn.SetDefault()
|
||||
buttonSizer.Add(okBtn, 0, wx.RIGHT, HALF_SPACE)
|
||||
buttonSizer.Add(wx.Button(dlg, wx.ID_CANCEL), 0)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
contentSizer.Add(gridSizer, 0, wx.ALL, SPACE)
|
||||
contentSizer.Add(buttonSizer, 0, wx.ALL|wx.ALIGN_RIGHT, SPACE)
|
||||
|
||||
dlg.SetSizer(contentSizer)
|
||||
dlg.Fit()
|
||||
dlg.Layout()
|
||||
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Checkout:\n"))
|
||||
|
||||
svnUrl = svnURLText.GetValue()
|
||||
toLocation = localPath.GetValue()
|
||||
try:
|
||||
self._client.checkout(svnUrl, toLocation)
|
||||
view.AddLines(_("Checkout completed.\n"))
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines(_("Checkout failed. %s\n") % str(e))
|
||||
wx.MessageBox(_("Checkout failed. %s") % str(e), _("SVN Checkout"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Checkout failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
wx.MessageBox(_("Checkout failed."), _("SVN Checkout"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
dlg.Destroy()
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_REVERT_ID:
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
filenames = self.GetCurrentDocuments()
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Revert:\n"))
|
||||
for filename in filenames:
|
||||
view.AddLines("%s\n" % filename)
|
||||
|
||||
try:
|
||||
self._client.revert(filenames)
|
||||
view.AddLines(_("Revert completed.\n"))
|
||||
|
||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||
for doc in openDocs[:]: # need to make a copy of the list otherwise ordinality changes as we close the files
|
||||
if doc.GetFilename() in filenames:
|
||||
yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
|
||||
_("Reverted file '%s' is currently open. Close it?") % os.path.basename(doc.GetFilename()),
|
||||
_("Close File"),
|
||||
wx.YES_NO|wx.ICON_QUESTION)
|
||||
if yesNoMsg.ShowModal() == wx.ID_YES:
|
||||
doc.DeleteAllViews()
|
||||
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines("%s\n" % str(e))
|
||||
wx.MessageBox(str(e), _("SVN Revert"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Revert failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
wx.MessageBox(_("Revert failed."), _("SVN Revert"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_ADD_ID:
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
filenames = self.GetCurrentDocuments()
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Add:\n"))
|
||||
for filename in filenames:
|
||||
view.AddLines("%s\n" % filename)
|
||||
|
||||
try:
|
||||
self._client.add(filenames)
|
||||
view.AddLines(_("Add completed.\n"))
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines("%s\n" % str(e))
|
||||
wx.MessageBox(str(e), _("SVN Add"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Add failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
wx.MessageBox(_("Add failed."), _("SVN Add"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_DELETE_ID:
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
filenames = self.GetCurrentDocuments()
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
view.ClearLines()
|
||||
view.AddLines(_("SVN Delete:\n"))
|
||||
for filename in filenames:
|
||||
view.AddLines("%s\n" % filename)
|
||||
|
||||
try:
|
||||
self._client.remove(filenames)
|
||||
view.AddLines(_("Delete completed.\n"))
|
||||
except pysvn.ClientError, e:
|
||||
view.AddLines("%s\n" % str(e))
|
||||
wx.MessageBox(str(e), _("SVN Delete"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
except:
|
||||
extype, ex, tb = sys.exc_info()
|
||||
view.AddLines("Delete failed: (%s) %s\n" % (extype, str(ex)))
|
||||
for line in traceback.format_tb(tb):
|
||||
view.AddLines(line)
|
||||
wx.MessageBox(_("Delete failed."), _("SVN Delete"), wx.OK | wx.ICON_EXCLAMATION)
|
||||
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
id = event.GetId()
|
||||
|
||||
if id in [SVNService.SVN_UPDATE_ID,
|
||||
SVNService.SVN_CHECKIN_ID,
|
||||
SVNService.SVN_REVERT_ID,
|
||||
SVNService.SVN_ADD_ID,
|
||||
SVNService.SVN_DELETE_ID]:
|
||||
if self.GetCurrentDocuments():
|
||||
event.Enable(True)
|
||||
else:
|
||||
event.Enable(False)
|
||||
return True
|
||||
|
||||
elif id == SVNService.SVN_CHECKOUT_ID:
|
||||
event.Enable(True)
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def GetCurrentDocuments(self):
|
||||
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
if projectService:
|
||||
projView = projectService.GetView()
|
||||
|
||||
if projView.HasFocus():
|
||||
filenames = projView.GetSelectedFiles()
|
||||
if len(filenames):
|
||||
return filenames
|
||||
else:
|
||||
return None
|
||||
|
||||
doc = wx.GetApp().GetTopWindow().GetDocumentManager().GetCurrentDocument()
|
||||
if doc:
|
||||
filenames = [doc.GetFilename()]
|
||||
else:
|
||||
filenames = None
|
||||
|
||||
return filenames
|
||||
|
||||
|
||||
class SVNOptionsPanel(wx.Panel):
|
||||
|
||||
|
||||
def __init__(self, parent, id):
|
||||
wx.Panel.__init__(self, parent, id)
|
||||
|
||||
config = wx.ConfigBase_Get()
|
||||
svnService = wx.GetApp().GetService(SVNService)
|
||||
svnUrl = config.Read(SVN_REPOSITORY_URL, svnService._defaultURL)
|
||||
configDir = config.Read(SVN_CONFIG_DIR, "")
|
||||
|
||||
borderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
||||
|
||||
sizer.Add(wx.StaticText(self, -1, _("SVN Config Dir:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
|
||||
self._svnConfigDir = wx.TextCtrl(self, -1, configDir, size = (200, -1))
|
||||
if configDir == "":
|
||||
self._svnConfigDir.SetToolTipString(_("Path Subversion configuration directory."))
|
||||
else:
|
||||
self._svnConfigDir.SetToolTipString(configDir)
|
||||
|
||||
findDirButton = wx.Button(self, -1, _("Browse..."))
|
||||
|
||||
def OnBrowseButton(event):
|
||||
dirDlg = wx.DirDialog(self, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
|
||||
dir = self._svnConfigDir.GetValue()
|
||||
if len(dir):
|
||||
dirDlg.SetPath(dir)
|
||||
if dirDlg.ShowModal() == wx.ID_OK:
|
||||
self._svnConfigDir.SetValue(dirDlg.GetPath())
|
||||
self._svnConfigDir.SetToolTipString(self._svnConfigDir.GetValue())
|
||||
self._svnConfigDir.SetInsertionPointEnd()
|
||||
|
||||
dirDlg.Destroy()
|
||||
wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
|
||||
|
||||
hsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
hsizer.Add(self._svnConfigDir, 1, wx.EXPAND)
|
||||
hsizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||
sizer.Add(hsizer, 0)
|
||||
|
||||
sizer.Add(wx.StaticText(self, -1, _("SVN URL:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||
self._svnURLText = wx.TextCtrl(self, -1, svnUrl, size = (200, -1))
|
||||
self._svnURLText.SetToolTipString(svnUrl)
|
||||
sizer.Add(self._svnURLText, 0)
|
||||
|
||||
borderSizer.Add(sizer, 0, wx.ALL, SPACE)
|
||||
self.SetSizer(borderSizer)
|
||||
self.Layout()
|
||||
parent.AddPage(self, _("SVN"))
|
||||
|
||||
|
||||
def OnOK(self, optionsDialog):
|
||||
config = wx.ConfigBase_Get()
|
||||
config.Write(SVN_CONFIG_DIR, self._svnConfigDir.GetValue())
|
||||
config.Write(SVN_REPOSITORY_URL, self._svnURLText.GetValue())
|
||||
|
Reference in New Issue
Block a user