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:
Robin Dunn
2005-05-19 00:21:49 +00:00
parent 4809f5df5d
commit 6f1a3f9c1a
19 changed files with 1791 additions and 1064 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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:

View File

@@ -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()

View File

@@ -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)

View File

@@ -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.

View File

@@ -84,6 +84,7 @@ class OutlineView(Service.ServiceView):
item = self.GetControl().GetSelection()
if item:
self.GetControl().CallDoSelectCallback(item)
event.Skip()
def ResumeActionOnSelect(self):

View File

@@ -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")

View File

@@ -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):

View File

@@ -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):

View 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())

View File

@@ -10,75 +10,19 @@
# License: wxWindows License
#----------------------------------------------------------------------------
import logging
import cStringIO
import traceback
import sys
import string
import os
def classForName(className):
pathList = className.split('.')
moduleName = string.join(pathList[:-1], '.')
code = __import__(moduleName)
for name in pathList[1:]:
code = code.__dict__[name]
return code
def _registerMainModuleDir():
global mainModuleDir
if sys.executable.find('python') != -1:
utilModuleDir = os.path.dirname(__file__)
if not os.path.isabs(utilModuleDir):
utilModuleDir = os.path.join(os.getcwd(), utilModuleDir)
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
else:
mainModuleDir = os.path.dirname(sys.executable)
def hasattrignorecase(object, name):
for attr in dir(object):
if attr.lower() == name.lower():
return True
for attr in dir(object):
if attr.lower() == '_' + name.lower():
return True
return False
def setattrignorecase(object, name, value):
for attr in object.__dict__:
if attr.lower() == name.lower():
object.__dict__[attr] = value
return
## for attr in dir(object):
## if attr.lower() == '_' + name.lower():
## object.__dict__[attr] = value
## return
object.__dict__[name] = value
def getattrignorecase(object, name):
for attr in object.__dict__:
if attr.lower() == name.lower():
return object.__dict__[attr]
## for attr in dir(object):
## if attr.lower() == '_' + name.lower():
## return object.__dict__[attr]
return object.__dict__[name]
def defaultLoad(fileObject, knownTypes=None):
xml = fileObject.read()
loadedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
if hasattr(fileObject, 'name'):
loadedObject.fileName = os.path.abspath(fileObject.name)
loadedObject.initialize()
return loadedObject
def defaultSave(fileObject, objectToSave, knownTypes=None):
xml = xmlmarshaller.marshal(objectToSave, prettyPrint=True, knownTypes=knownTypes)
fileObject.write(xml)
fileObject.close()
def clone(objectToClone):
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True)
clonedObject = xmlmarshaller.unmarshal(xml)
if hasattr(objectToClone, 'fileName'):
clonedObject.fileName = objectToClone.fileName
clonedObject.initialize()
return clonedObject
def exceptionToString(e):
sio = cStringIO.StringIO()
traceback.print_exception(e.__class__, e, sys.exc_traceback, file=sio)
return sio.getvalue()
_registerMainModuleDir()

View File

@@ -0,0 +1,93 @@
#----------------------------------------------------------------------------
# Name: objutils.py
# Purpose: Object Utilities
#
# Author: Alan Mullendore
#
# Created: 5/10/05
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import logging
import traceback
import sys
import os
import xmlmarshaller
def defaultLoad(fileObject, knownTypes=None):
xml = fileObject.read()
loadedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
if hasattr(fileObject, 'name'):
loadedObject.fileName = os.path.abspath(fileObject.name)
loadedObject.initialize()
return loadedObject
def defaultSave(fileObject, objectToSave, knownTypes=None, withEncoding=1, encoding='utf-8'):
xml = xmlmarshaller.marshal(objectToSave, prettyPrint=True, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
fileObject.write(xml)
fileObject.flush()
def clone(objectToClone, knownTypes=None, encoding='utf-8'):
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
if hasattr(objectToClone, 'fileName'):
clonedObject.fileName = objectToClone.fileName
try:
clonedObject.initialize()
except AttributeError:
pass
return clonedObject
def classForName(className):
pathList = className.split('.')
moduleName = '.'.join(pathList[:-1])
code = __import__(moduleName)
for name in pathList[1:]:
code = code.__dict__[name]
return code
def hasattrignorecase(object, name):
namelow = name.lower()
for attr in dir(object):
if attr.lower() == namelow:
return True
for attr in dir(object):
if attr.lower() == '_' + namelow:
return True
return False
def setattrignorecase(object, name, value):
namelow = name.lower()
for attr in object.__dict__:
if attr.lower() == namelow:
object.__dict__[attr] = value
return
object.__dict__[name] = value
def getattrignorecase(object, name):
namelow = name.lower()
for attr in object.__dict__:
if attr.lower() == namelow:
return object.__dict__[attr]
return object.__dict__[name]
def hasPropertyValue(obj, attr):
hasProp = False
try:
prop = obj.__class__.__dict__[attr]
if (isinstance(prop, property)):
hasProp = hasattr(obj, attr)
if (hasProp):
# It's a property and it has a value but sometimes we don't want it.
# If there is a _hasattr method execute it and the
# result will tell us whether to include this value
try:
hasProp = obj._hasattr(attr)
except:
pass
except KeyError:
pass
return hasProp

View File

@@ -9,14 +9,17 @@
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
from activegrid import util
import inspect
import __builtin__
import sys
from types import *
import xml.sax
import xml.sax.handler
import __builtin__
from xml.sax import saxutils
import objutils
MODULE_PATH = "__main__"
### ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
"""
@@ -147,52 +150,6 @@ MEMBERS_TO_SKIP = ('__module__', '__doc__', '__xmlname__', '__xmlattributes__',
'__xmldefaultnamespace__', '__xmlattrnamespaces__',
'__xmlattrgroups__')
#WELL_KNOWN_OBJECTS = { #"xs:element" : "activegrid.model.schema.XsdElement",
#"xs:complexType" : "activegrid.model.schema.XsdComplexType",
#"xs:sequence" : "activegrid.model.schema.XsdSequence",
#"xs:element" : "activegrid.model.schema.XsdElement",
#"xs:key" : "activegrid.model.schema.XsdKey",
#"xs:field" : "activegrid.model.schema.XsdKeyField",
#"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
#"xs:selector" : "activegrid.model.schema.XsdKeySelector",
#"xs:schema" : "activegrid.model.schema.Schema",
#"ag:schemaOptions":"activegrid.model.schema.SchemaOptions",
#"ag:debug" : "activegrid.model.processmodel.DebugOperation",
#"ag:body" : "activegrid.model.processmodel.Body", # alan (start)
#"ag:cssRule" : "activegrid.model.processmodel.CssRule",
#"ag:datasource" : "activegrid.data.dataservice.DataSource",
#"ag:deployment" : "activegrid.server.deployment.Deployment",
#"ag:glue" : "activegrid.model.processmodel.Glue",
#"ag:hr" : "activegrid.model.processmodel.HorizontalRow",
#"ag:image" : "activegrid.model.processmodel.Image",
#"ag:inputs" : "activegrid.model.processmodel.Inputs",
#"ag:label" : "activegrid.model.processmodel.Label",
#"ag:processmodel" : "activegrid.model.processmodel.ProcessModel",
#"ag:processmodelref" : "activegrid.server.deployment.ProcessModelRef",
#"ag:query" : "activegrid.model.processmodel.Query",
#"ag:schemaref" : "activegrid.server.deployment.SchemaRef",
#"ag:set" : "activegrid.model.processmodel.SetOperation",
#"ag:text" : "activegrid.model.processmodel.Text",
#"ag:title" : "activegrid.model.processmodel.Title",
#"ag:view" : "activegrid.model.processmodel.View",
#"bpws:case" : "activegrid.model.processmodel.BPELCase",
#"bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
#"bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
#"bpws:process" : "activegrid.model.processmodel.BPELProcess",
#"bpws:reply" : "activegrid.model.processmodel.BPELReply",
#"bpws:switch" : "activegrid.model.processmodel.BPELSwitch",
#"bpws:variable" : "activegrid.model.processmodel.BPELVariable",
#"projectmodel" : "activegrid.tool.ProjectEditor.ProjectModel",
#"wsdl:message" : "activegrid.model.processmodel.WSDLMessage",
#"wsdl:part" : "activegrid.model.processmodel.WSDLPart",
#"xforms:group" : "activegrid.model.processmodel.XFormsGroup",
#"xforms:input" : "activegrid.model.processmodel.XFormsInput",
#"xforms:label" : "activegrid.model.processmodel.XFormsLabel",
#"xforms:output" : "activegrid.model.processmodel.XFormsOutput",
#"xforms:secret" : "activegrid.model.processmodel.XFormsSecret",
#"xforms:submit" : "activegrid.model.processmodel.XFormsSubmit"} # alan(end)
################################################################################
#
# classes and functions
@@ -200,45 +157,42 @@ MEMBERS_TO_SKIP = ('__module__', '__doc__', '__xmlname__', '__xmlattributes__',
################################################################################
def _objectfactory(objname, objargs=None, xsname=None):
try:
'''dynamically create an object based on the objname and return
it. look it up in the BASETYPE_ELEMENT_MAP first.
'''
# split the objname into the typename and module path,
# importing the module if need be.
if not isinstance(objargs, list):
objargs = [objargs]
'''dynamically create an object based on the objname and return
it. look it up in the BASETYPE_ELEMENT_MAP first.
'''
# split the objname into the typename and module path,
# importing the module if need be.
if not isinstance(objargs, list):
objargs = [objargs]
if (xsname):
try:
objname = knownGlobalTypes[xsname]
except KeyError:
pass
if (xsname):
try:
objname = knownGlobalTypes[xsname]
except KeyError:
pass
## print "[objectfactory] creating an object of type %s and value %s, xsname=%s" % (objname, objargs, xsname)
objtype = objname.split('.')[-1]
pathlist = objname.split('.')
modulename = '.'.join(pathlist[0:-1])
## print "[objectfactory] creating an object of type %s and value %s, xsname=%s" % (objname, objargs, xsname)
objtype = objname.split('.')[-1]
pathlist = objname.split('.')
modulename = '.'.join(pathlist[0:-1])
## print "[objectfactory] objtype is %s" % objtype
## print "[objectfactory] objargs is %s" % `objargs`
## since the bool constructor will turn a string of non-zero
## length into True, we call it with no argument (yielding a
## False) if the string contains 'false'
if objtype == 'bool' and objargs[0].lower() == 'false':
objargs = None
## if objtype == 'str':
## print type(objargs)
## print "string we're unescaping: '%s'" % objargs[0]
## objargs = saxutils.unescape(objargs[0])
if objtype in ('float', 'int', 'str', 'long'):
## print "[objectfactory] object [%s] %s(%r)" % (objname, objtype, objargs)
if objname == 'bool':
return not objargs[0].lower() == 'false'
elif objname == 'str': # don't strip strings - blanks are significant !!!
if len(objargs) > 0:
return saxutils.unescape(objargs[0]).encode()
else:
return ''
elif objname == 'unicode': # don't strip strings - blanks are significant !!!
if len(objargs) > 0:
return saxutils.unescape(objargs[0]).encode()
else:
return ''
elif objtype in ('float', 'int', 'str', 'long'):
objargs = [x.strip() for x in objargs]
if objtype == 'str':
objargs = [saxutils.unescape(x) for x in objargs]
try:
if __builtin__.__dict__.has_key(objname):
module = __builtin__
else:
@@ -379,7 +333,7 @@ class XMLObjectFactory(xml.sax.ContentHandler):
if attrname == "maxOccurs" and attr == "unbounded":
attr = "-1"
attr = _objectfactory(type, attr)
util.setattrignorecase(obj, _toAttrName(obj, attrname), attr)
objutils.setattrignorecase(obj, _toAttrName(obj, attrname), attr)
## obj.__dict__[_toAttrName(obj, attrname)] = attr
# stuff any child attributes meant to be in a sequence via the __xmlflattensequence__
flattenDict = {}
@@ -407,9 +361,7 @@ class XMLObjectFactory(xml.sax.ContentHandler):
try:
## print "[endElement] obj.__dict__ is: ", obj.__dict__
sequencevalue = obj.__dict__[sequencename]
except AttributeError:
sequencevalue = None
except KeyError:
except (AttributeError, KeyError):
sequencevalue = None
if sequencevalue == None:
sequencevalue = []
@@ -420,7 +372,7 @@ class XMLObjectFactory(xml.sax.ContentHandler):
obj.append(child)
else:
## print "childname = %s, obj = %s, child = %s" % (childname, repr(obj), repr(child))
util.setattrignorecase(obj, _toAttrName(obj, childname), child)
objutils.setattrignorecase(obj, _toAttrName(obj, childname), child)
obj.__dict__[_toAttrName(obj, childname)] = child
if complexType:
@@ -474,6 +426,8 @@ def xsdToPythonType(xsdType):
def _getXmlValue(pythonValue):
if (isinstance(pythonValue, bool)):
return str(pythonValue).lower()
elif (isinstance(pythonValue, unicode)):
return pythonValue.encode()
else:
return str(pythonValue)
@@ -488,7 +442,17 @@ def unmarshal(xmlstr, knownTypes=None):
return objectfactory.getRootObject()
def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPrint=False, indent=0, knownTypes=None):
def marshal(obj, elementName=None, prettyPrint=False, indent=0, knownTypes=None, withEncoding=True, encoding=None):
xmlstr = ''.join(_marshal(obj, elementName, prettyPrint=prettyPrint, indent=indent, knownTypes=knownTypes))
if withEncoding:
if encoding is None:
return '<?xml version="1.0" encoding="%s"?>\n%s' % (sys.getdefaultencoding(), xmlstr)
else:
return '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr.encode(encoding))
else:
return xmlstr
def _marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPrint=False, indent=0, knownTypes=None):
if prettyPrint or indent:
prefix = ' '*indent
newline = '\n'
@@ -563,7 +527,7 @@ def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPr
except KeyError:
continue
## # But, check and see if it is a property first:
## if (hasPropertyValue(obj, attr)):
## if (objutils.hasPropertyValue(obj, attr)):
## value = getattr(obj, attr)
## else:
## continue
@@ -593,7 +557,7 @@ def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPr
if hasattr(obj, '__xmlattrnamespaces__'):
## print "marshal: found __xmlattrnamespaces__"
for nameSpaceKey, nameSpaceAttributes in getattr(obj, '__xmlattrnamespaces__').items():
if nameSpaceKey == nameSpacePrefix[:-1]: # Don't need to specify attribute namespace if it is the same as it selement
if nameSpaceKey == nameSpacePrefix[:-1]: # Don't need to specify attribute namespace if it is the same as it's element
continue
if attr in nameSpaceAttributes:
attrNameSpacePrefix = nameSpaceKey + ':'
@@ -607,95 +571,76 @@ def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPr
objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, value)
## print "marshal: new objattrs is: ", objattrs
objtype = type(obj)
if isinstance(obj, NoneType):
#print "marshal: skipping an element with no type"
return ''
# return '%s<%s objtype="None"/>%s' % (prefix, elementName, newline)
elif isinstance(obj, bool):
xmlString = '%s<%s objtype="bool">%s</%s>%s' % (prefix, elementName, obj, elementName, newline)
#print "marshal: returning a bool element: \n", xmlString
return xmlString
return ['%s<%s objtype="bool">%s</%s>%s' % (prefix, elementName, obj, elementName, newline)]
elif isinstance(obj, int):
xmlString = '''%s<%s objtype="int">%s</%s>%s''' % (prefix, elementName, str(obj), elementName, newline)
#print "marshal: returning a int element: \n", xmlString
return xmlString
return ['''%s<%s objtype="int">%s</%s>%s''' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, long):
xmlString = '%s<%s objtype="long">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)
#print "marshal: returning a long element: \n", xmlString
return xmlString
return ['%s<%s objtype="long">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, float):
xmlString = '%s<%s objtype="float">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)
#print "marshal: returning a float element: \n", xmlString
return xmlString
return ['%s<%s objtype="float">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, unicode): # have to check before basestring - unicode is instance of base string
return ['''%s<%s>%s</%s>%s''' % (prefix, elementName, saxutils.escape(obj.encode()), elementName, newline)]
elif isinstance(obj, basestring):
xmlString = '''%s<%s>%s</%s>%s''' % (prefix, elementName, saxutils.escape(obj), elementName, newline)
#print "marshal: returning a str element: \n", xmlString
return xmlString
## elif isinstance(obj, unicode):
## return '''%s<%s>%s</%s>%s''' % (prefix, elementName, obj, elementName, newline)
return ['''%s<%s>%s</%s>%s''' % (prefix, elementName, saxutils.escape(obj), elementName, newline)]
elif isinstance(obj, list):
if len(obj) < 1:
#print "marshal: skipping an empty list"
return ''
xmlString = '%s<%s objtype="list">%s' % (prefix, elementName, newline)
xmlString = ['%s<%s objtype="list">%s' % (prefix, elementName, newline)]
for item in obj:
xmlString += marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes)
xmlString += '%s</%s>%s' % (prefix, elementName, newline)
#print "marshal: returning a list element: \n", xmlString
xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
return xmlString
elif isinstance(obj, tuple):
if len(obj) < 1:
#print "marshal: skipping an empty tuple"
return ''
xmlString = '%s<%s objtype="list" mutable="false">%s' % (prefix, elementName, newline)
xmlString = ['%s<%s objtype="list" mutable="false">%s' % (prefix, elementName, newline)]
for item in obj:
xmlString += marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes)
xmlString += '%s</%s>%s' % (prefix, elementName, newline)
#print "marshal: returning a tuple element: \n", xmlString
xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
return xmlString
elif isinstance(obj, dict):
xmlString = '%s<%s objtype="dict">%s' % (prefix, elementName, newline)
xmlString = ['%s<%s objtype="dict">%s' % (prefix, elementName, newline)]
subprefix = prefix + ' '*increment
subindent = indent + 2*increment
for key, val in obj.iteritems():
xmlString += "%s<key>%s%s%s</key>%s%s<value>%s%s%s</value>%s" \
% (subprefix, newline, marshal(key, indent=subindent, knownTypes=knownTypes), subprefix, newline, subprefix, newline, marshal(val, nameSpaces=nameSpaces, indent=subindent, knownTypes=knownTypes), subprefix, newline)
xmlString += '%s</%s>%s' % (prefix, elementName, newline)
#print "marshal: returning a dict element: \n", xmlString
xmlString.append("%s<key>%s" % (subprefix, newline))
xmlString.extend(_marshal(key, indent=subindent, knownTypes=knownTypes))
xmlString.append("%s</key>%s%s<value>%s" % (subprefix, newline, subprefix, newline))
xmlString.extend(_marshal(val, nameSpaces=nameSpaces, indent=subindent, knownTypes=knownTypes))
xmlString.append("%s</value>%s" % (subprefix, newline))
xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
return xmlString
else:
moduleName = obj.__class__.__module__
if (moduleName == "activegrid.model.schema"):
## print "marshal: found an activegrid.model.schema class element"
xmlString = '%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)
xmlString = ['%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)]
else:
## print "marshal: found a ", moduleName, " class element"
# Only add the objtype if the element tag is unknown to us.
try:
objname = knownTypes[elementName]
## print "successfully mapped ", elementName, " to known-objtype ", objname
xmlString = '%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)
xmlString = ['%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)]
except KeyError:
## print "failed to map elementName: ", elementName, "; knownTypes: ", knownTypes
xmlString = '%s<%s%s%s objtype="%s.%s"' % (prefix, elementName, nameSpaceAttrs, objattrs, moduleName, className)
xmlString = ['%s<%s%s%s objtype="%s.%s"' % (prefix, elementName, nameSpaceAttrs, objattrs, moduleName, className)]
## print "UnknownTypeException: Unknown type (%s.%s) passed to marshaller" % (moduleName, className)
# get the member, value pairs for the object, filtering out
# the types we don't support.
## print "marshal: elementString: \n", xmlString
# get the member, value pairs for the object, filtering out the types we don't support
if (elementAdd != None):
prefix += increment*' '
indent += increment
xmlMemberString = ''
xmlMemberString = []
if hasattr(obj, '__xmlbody__'):
xmlMemberString = getattr(obj, obj.__xmlbody__)
xmlbody = getattr(obj, obj.__xmlbody__)
if xmlbody != None:
xmlMemberString.append(xmlbody)
else:
entryList = obj.__dict__.items()
## # Add in properties
## for key in obj.__class__.__dict__.iterkeys():
## if (key not in members_to_skip and key not in obj.__dict__
## and hasPropertyValue(obj, key)):
## and objutils.hasPropertyValue(obj, key)):
## value = getattr(obj, key)
## entryList.append((key, value))
entryList.sort()
@@ -719,7 +664,7 @@ def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPr
if (eName != '__nogroup__'):
prefix += increment*' '
indent += increment
xmlMemberString += '%s<%s objtype="None">%s' % (prefix, eName, newline)
xmlMemberString.append('%s<%s objtype="None">%s' % (prefix, eName, newline))
for name in eList:
value = obj.__dict__[name]
## print " ", name, " = ", value
@@ -754,91 +699,38 @@ def marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPr
xmlname = name
## xmlname = name.lower()
for seqitem in value:
xmlMemberString += marshal(seqitem, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes)
xmlMemberString.extend(_marshal(seqitem, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
else:
if (hasattr(obj, "__xmlrename__") and name in obj.__xmlrename__):
xmlname = obj.__xmlrename__[name]
else:
xmlname = name
## xmlname = name.lower()
## # skip
## if xmlname.startswith('_') and not xmlname.startswith('__'):
## xmlname = xmlname[1:]
## if (indent > 30):
## print "getting pretty deep, xmlname = ", xmlname
## print "marshal: marshalling ", xmlname
xmlMemberString += marshal(value, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes)
## print "marshal: back with new xmlMemberString: \n", xmlMemberString
xmlMemberString.extend(_marshal(value, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
if (eName != '__nogroup__'):
## print "marshal: Completing attrGroup ", eName
xmlMemberString += '%s</%s>%s' % (prefix, eName, newline)
xmlMemberString.append('%s</%s>%s' % (prefix, eName, newline))
prefix = prefix[:-increment]
indent -= increment
# if we have nested elements, add them here, otherwise close the element tag immediately.
if xmlMemberString:
xmlString += '>'
xmlMemberString = filter(lambda x: len(x)>0, xmlMemberString)
if len(xmlMemberString) > 0:
xmlString.append('>')
if hasattr(obj, '__xmlbody__'):
xmlString += xmlMemberString
xmlString += '</%s>%s' % (elementName, newline)
xmlString.extend(xmlMemberString)
xmlString.append('</%s>%s' % (elementName, newline))
else:
xmlString += newline
xmlString.append(newline)
if (elementAdd != None):
xmlString += '%s<%s>%s' % (prefix, elementAdd, newline)
xmlString += xmlMemberString
xmlString.append('%s<%s>%s' % (prefix, elementAdd, newline))
xmlString.extend(xmlMemberString)
if (elementAdd != None):
xmlString += '%s</%s>%s' % (prefix, elementAdd, newline)
xmlString.append('%s</%s>%s' % (prefix, elementAdd, newline))
prefix = prefix[:-increment]
indent -= increment
xmlString += '%s</%s>%s' % (prefix, elementName, newline)
xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
else:
xmlString = xmlString + '/>%s' % newline
xmlString.append('/>%s' % newline)
return xmlString
# We don't use this anymore but in case we want to get properties this is how
# you do it
def hasPropertyValue(obj, attr):
hasProp = False
try:
prop = obj.__class__.__dict__[attr]
if (isinstance(prop, property)):
hasProp = hasattr(obj, attr)
if (hasProp):
# It's a property and it has a value but sometimes we don't want it.
# If there is a _hasattr method execute it and the
# result will tell us whether to include this value
try:
hasProp = obj._hasattr(attr)
except:
pass
except KeyError:
pass
return hasProp
if __name__ == '__main__':
from xmlmarshallertests import Person, marshalledint, marshalledlist
l = [1, 2, 3]
d = {'1': 1, '2': 2}
outerlist = [l]
xmlstr = marshal(d, "d", prettyPrint=True)
print xmlstr
person = Person()
person.firstName = "Albert"
person.lastName = "Camus"
person.addressLine1 = "23 Absurd St."
person.city = "Ennui"
person.state = "MO"
person.zip = "54321"
person._phoneNumber = "808-303-2323"
person.favoriteWords = ['angst', 'ennui', 'existence']
person.weight = 150
xmlstring = marshal(person, 'person', prettyPrint=True)
print xmlstring
obj = unmarshal(marshalledlist)
print "obj has type %s and value %s" % (type(obj), str(obj))
for item in obj:
print "item: %s" % str(item)

View File

@@ -1,183 +0,0 @@
#----------------------------------------------------------------------------
# Name: xmlmarshallertests.py
# Purpose:
#
# Author: John Spurling
#
# Created: 8/16/04
# CVS-ID: $Id$
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import unittest
import xmlmarshaller
from xmlprettyprinter import xmlprettyprint
marshalledPersonObject = """
<person objtype="Person">
<firstName>Albert</firstName>
<lastName>Camus</lastName>
<address>23 Absurd St.</address>
<city>Ennui</city>
<state>MO</state>
<zip>54321</zip>
<_phoneNumber>808-303-2323</_phoneNumber>
<favoriteWords objtype="list">
<item>angst</item>
<item>ennui</item>
<item>existence</item>
</favoriteWords>
<weight objtype="float">150</weight>
</person>
"""
marshalledint = '''
<item objtype="int">23</item>
'''
marshalledlist = '''
<mylist objtype="list">
<item>foo</item>
<item>bar</item>
</mylist>
'''
## a dummy class taken from the old XmlMarshaller module.
## class Person:
## def __init__(self):
## # These are not necessary but are nice if you want to tailor
## # the Python object <-> XML binding
## # The xml element name to use for this object, otherwise it
## # will use a fully qualified Python name like __main__.Person
## # which can be ugly.
## self.__xmlname__ = "person"
## self.firstName = None
## self.lastName = None
## self.addressLine1 = None
## self.addressLine2 = None
## self.city = None
## self.state = None
## self.zip = None
## self._phoneNumber = None
## self.favoriteWords = None
## self.weight = None
class Person:
__xmlflattensequence__ = {'asequence': ('the_earth_is_flat',)}
class XmlMarshallerTestFunctions(unittest.TestCase):
def setUp(self):
'''common setup code goes here.'''
pass
def testInt(self):
xml = xmlmarshaller.marshal(1)
print "\n#########################################"
print "# testString test case #"
print "#########################################"
print "marshalled int object:\n"
print xmlprettyprint(xml)
def testDict(self):
xml = xmlmarshaller.marshal({'one': 1,
'two': 2,
'three': 3})
print "\n#########################################"
print "# testString test case #"
print "#########################################"
print "marshalled dict object:\n"
print xmlprettyprint(xml)
def testBool(self):
xmltrue = xmlmarshaller.marshal(True)
xmlfalse = xmlmarshaller.marshal(False)
print "\n#########################################"
print "# testBool test case #"
print "#########################################"
print "marshalled boolean true object:\n"
print xmlprettyprint(xmltrue)
print "\nmarshalled boolean false object:\n"
print xmlprettyprint(xmlfalse)
pytrue = xmlmarshaller.unmarshal(xmltrue)
assert pytrue is True
pyfalse = xmlmarshaller.unmarshal(xmlfalse)
assert pyfalse is False
def testString(self):
xml = xmlmarshaller.marshal(
"all your marshalled objects are belong to us")
print "\n#########################################"
print "# testString test case #"
print "#########################################"
print xmlprettyprint(xml)
def testEmptyElement(self):
person = Person()
person.firstName = "Albert"
person.__xmlattributes__ = ('firstName',)
xml = xmlmarshaller.marshal(person, 'person')
print "\n#########################################"
print "# testEmptyElement test case #"
print "#########################################"
print xml
assert (xml == """<person objtype="__main__.Person" firstName="Albert"/>""")
def testXMLFlattenSequence(self):
person = Person()
person.asequence = ('one', 'two')
xml = xmlmarshaller.marshal(person, 'person')
print "\n#########################################"
print "# testXMLFlattenSequence test case #"
print "#########################################"
print xml
assert (xml == """<person objtype="__main__.Person"><the_earth_is_flat>one</the_earth_is_flat><the_earth_is_flat>two</the_earth_is_flat></person>""")
unmarshalledperson = xmlmarshaller.unmarshal(xml)
assert(hasattr(unmarshalledperson, 'asequence'))
assert(len(unmarshalledperson.asequence) == 2)
def testInstance(self):
print "\n#########################################"
print "# testInstance test case #"
print "#########################################"
class Foo:
def __init__(self):
self.alist = [1,2]
self.astring = 'f00'
f = Foo()
xml = xmlmarshaller.marshal(f, 'foo')
print xml
def testPerson(self):
person = Person()
person.firstName = "Albert"
person.lastName = "Camus"
person.addressLine1 = "23 Absurd St."
person.city = "Ennui"
person.state = "MO"
person.zip = "54321"
person._phoneNumber = "808-303-2323"
person.favoriteWords = ['angst', 'ennui', 'existence']
person.weight = 150
# __xmlattributes__ = ('fabulousness',)
person.fabulousness = "tres tres"
xml = xmlmarshaller.marshal(person)
print "\n#########################################"
print "# testPerson test case #"
print "#########################################"
print "Person object marshalled into XML:\n"
print xml
# When encountering a "person" element, use the Person class
## elementMappings = { "person" : Person }
## obj = unmarshal(xml, elementMappings = elementMappings)
## print "Person object recreated from XML with attribute types indicated:"
## print obj.person.__class__
## for (attr, value) in obj.person.__dict__.items():
## if not attr.startswith("__"):
## print attr, "=", value, type(value)
## print
if __name__ == "__main__":
unittest.main()