DocView patches from Morgen Hua: bug fixes, and additional SVN
commands, also added a default template that uses the text editor for any unknown file type. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@34473 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
@@ -59,7 +59,7 @@ class AboutDialog(wx.Dialog):
|
|||||||
splash_bmp = getSplashBitmap()
|
splash_bmp = getSplashBitmap()
|
||||||
image = wx.StaticBitmap(aboutPage, -1, splash_bmp, (0,0), (splash_bmp.GetWidth(), splash_bmp.GetHeight()))
|
image = wx.StaticBitmap(aboutPage, -1, splash_bmp, (0,0), (splash_bmp.GetWidth(), splash_bmp.GetHeight()))
|
||||||
sizer.Add(image, 0, wx.ALIGN_CENTER|wx.ALL, 0)
|
sizer.Add(image, 0, wx.ALIGN_CENTER|wx.ALL, 0)
|
||||||
sizer.Add(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\nVersion 0.6 Early Access\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
sizer.Add(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\nVersion 0.7 Early Access\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
||||||
sizer.Add(wx.StaticText(aboutPage, -1, _("http://www.activegrid.com")), 0, wx.ALIGN_LEFT|wx.LEFT|wx.BOTTOM, 10)
|
sizer.Add(wx.StaticText(aboutPage, -1, _("http://www.activegrid.com")), 0, wx.ALIGN_LEFT|wx.LEFT|wx.BOTTOM, 10)
|
||||||
aboutPage.SetSizer(sizer)
|
aboutPage.SetSizer(sizer)
|
||||||
nb.AddPage(aboutPage, _("Copyright"))
|
nb.AddPage(aboutPage, _("Copyright"))
|
||||||
|
@@ -48,8 +48,17 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
self._pt2 = None
|
self._pt2 = None
|
||||||
self._needEraseLasso = False
|
self._needEraseLasso = False
|
||||||
self._propShape = None
|
self._propShape = None
|
||||||
|
self._maxWidth = 2000
|
||||||
|
self._maxHeight = 16000
|
||||||
|
|
||||||
|
|
||||||
|
def OnDraw(self, dc):
|
||||||
|
""" for Print Preview and Print """
|
||||||
|
dc.BeginDrawing()
|
||||||
|
self._canvas.Redraw(dc)
|
||||||
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
|
||||||
def OnCreate(self, doc, flags):
|
def OnCreate(self, doc, flags):
|
||||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
||||||
frame.Show()
|
frame.Show()
|
||||||
@@ -130,9 +139,7 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
wx.EVT_KILL_FOCUS(self._canvas, self.OnKillFocus)
|
wx.EVT_KILL_FOCUS(self._canvas, self.OnKillFocus)
|
||||||
wx.EVT_SET_FOCUS(self._canvas, self.OnFocus)
|
wx.EVT_SET_FOCUS(self._canvas, self.OnFocus)
|
||||||
|
|
||||||
maxWidth = 2000
|
self._canvas.SetScrollbars(20, 20, self._maxWidth / 20, self._maxHeight / 20)
|
||||||
maxHeight = 16000
|
|
||||||
self._canvas.SetScrollbars(20, 20, maxWidth / 20, maxHeight / 20)
|
|
||||||
|
|
||||||
self._canvas.SetBackgroundColour(wx.WHITE)
|
self._canvas.SetBackgroundColour(wx.WHITE)
|
||||||
self._diagram = ogl.Diagram()
|
self._diagram = ogl.Diagram()
|
||||||
@@ -654,7 +661,16 @@ class EditorCanvasShapeEvtHandler(ogl.ShapeEvtHandler):
|
|||||||
self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
|
self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
|
||||||
|
|
||||||
|
|
||||||
|
def OnMovePre(self, dc, x, y, oldX, oldY, display):
|
||||||
|
""" Prevent objects from being dragged outside of viewable area """
|
||||||
|
if (x > self._view._maxWidth) or (y > self._view._maxHeight):
|
||||||
|
return False
|
||||||
|
|
||||||
|
return ogl.ShapeEvtHandler.OnMovePre(self, dc, x, y, oldX, oldY, display)
|
||||||
|
|
||||||
|
|
||||||
def OnMovePost(self, dc, x, y, oldX, oldY, display):
|
def OnMovePost(self, dc, x, y, oldX, oldY, display):
|
||||||
|
""" Update the model's record of where the shape should be. Also enable redo/undo. """
|
||||||
if x == oldX and y == oldY:
|
if x == oldX and y == oldY:
|
||||||
return
|
return
|
||||||
if not self._view.GetDocument():
|
if not self._view.GetDocument():
|
||||||
|
@@ -633,10 +633,8 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
BREAKPOINT_MARKER_MASK = 0x2
|
BREAKPOINT_MARKER_MASK = 0x2
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
if ID == -1:
|
STCTextEditor.TextCtrl.__init__(self, parent, id, style)
|
||||||
ID = wx.NewId()
|
|
||||||
STCTextEditor.TextCtrl.__init__(self, parent, ID, style)
|
|
||||||
|
|
||||||
self.UsePopUp(False)
|
self.UsePopUp(False)
|
||||||
self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
|
self.Bind(wx.EVT_RIGHT_UP, self.OnRightUp)
|
||||||
@@ -672,10 +670,10 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
if _WINDOWS: # should test to see if menu item exists, if it does, add this workaround
|
if _WINDOWS: # should test to see if menu item exists, if it does, add this workaround
|
||||||
self.CmdKeyClear(wx.stc.STC_KEY_TAB, 0) # menu item "Indent Lines" from CodeService.InstallControls() generates another INDENT_LINES_ID event, so we'll explicitly disable the tab processing in the editor
|
self.CmdKeyClear(wx.stc.STC_KEY_TAB, 0) # menu item "Indent Lines" from CodeService.InstallControls() generates another INDENT_LINES_ID event, so we'll explicitly disable the tab processing in the editor
|
||||||
|
|
||||||
wx.stc.EVT_STC_MARGINCLICK(self, ID, self.OnMarginClick)
|
wx.stc.EVT_STC_MARGINCLICK(self, self.GetId(), self.OnMarginClick)
|
||||||
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
|
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
|
||||||
if self.GetMatchingBraces():
|
if self.GetMatchingBraces():
|
||||||
wx.stc.EVT_STC_UPDATEUI(self, ID, self.OnUpdateUI)
|
wx.stc.EVT_STC_UPDATEUI(self, self.GetId(), self.OnUpdateUI)
|
||||||
|
|
||||||
self.StyleClearAll()
|
self.StyleClearAll()
|
||||||
self.UpdateStyles()
|
self.UpdateStyles()
|
||||||
@@ -720,7 +718,8 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
item = menuBar.FindItemById(itemID)
|
item = menuBar.FindItemById(itemID)
|
||||||
if item:
|
if item:
|
||||||
menu.Append(itemID, item.GetLabel())
|
menu.Append(itemID, item.GetLabel())
|
||||||
|
wx.EVT_MENU(self, itemID, self.DSProcessEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow
|
||||||
|
wx.EVT_UPDATE_UI(self, itemID, self.DSProcessUpdateUIEvent) # wxHack: for customized right mouse menu doesn't work with new DynamicSashWindow
|
||||||
return menu
|
return menu
|
||||||
|
|
||||||
|
|
||||||
@@ -834,6 +833,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
|
|
||||||
def DoIndent(self):
|
def DoIndent(self):
|
||||||
self.AddText('\n')
|
self.AddText('\n')
|
||||||
|
self.EnsureCaretVisible()
|
||||||
# Need to do a default one for all languges
|
# Need to do a default one for all languges
|
||||||
|
|
||||||
|
|
||||||
|
@@ -22,6 +22,8 @@ import inspect
|
|||||||
from xml.dom.minidom import getDOMImplementation
|
from xml.dom.minidom import getDOMImplementation
|
||||||
import atexit
|
import atexit
|
||||||
import pickle
|
import pickle
|
||||||
|
import cStringIO
|
||||||
|
import bz2
|
||||||
|
|
||||||
if sys.platform.startswith("win"):
|
if sys.platform.startswith("win"):
|
||||||
import win32api
|
import win32api
|
||||||
@@ -107,7 +109,7 @@ class Adb(bdb.Bdb):
|
|||||||
exc_type_name = exc_type
|
exc_type_name = exc_type
|
||||||
else:
|
else:
|
||||||
exc_type_name = exc_type.__name__
|
exc_type_name = exc_type.__name__
|
||||||
message = "Exception occurred: " + repr(exc_type_name) + " See locals.__exception__ for details."
|
message = "Exception occured: " + repr(exc_type_name) + " See locals.__exception__ for details."
|
||||||
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
traceback.print_exception(exc_type, exc_value, exc_traceback)
|
||||||
self._harness.interaction(message, frame, message)
|
self._harness.interaction(message, frame, message)
|
||||||
|
|
||||||
@@ -189,8 +191,7 @@ class Adb(bdb.Bdb):
|
|||||||
return ""
|
return ""
|
||||||
|
|
||||||
def stop_here(self, frame):
|
def stop_here(self, frame):
|
||||||
if( self._userBreak ):
|
if self._userBreak:
|
||||||
self._userBreak = False
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -270,6 +271,7 @@ class BreakListenerThread(threading.Thread):
|
|||||||
if _VERBOSE: print "Before calling server close on breakpoint server"
|
if _VERBOSE: print "Before calling server close on breakpoint server"
|
||||||
self._server.server_close()
|
self._server.server_close()
|
||||||
if _VERBOSE: print "Calling server close on breakpoint server"
|
if _VERBOSE: print "Calling server close on breakpoint server"
|
||||||
|
self._server = None
|
||||||
|
|
||||||
|
|
||||||
class DebuggerHarness(object):
|
class DebuggerHarness(object):
|
||||||
@@ -312,8 +314,11 @@ class DebuggerHarness(object):
|
|||||||
self._server.register_function(self.clear_breakpoint)
|
self._server.register_function(self.clear_breakpoint)
|
||||||
self._server.register_function(self.set_all_breakpoints)
|
self._server.register_function(self.set_all_breakpoints)
|
||||||
self._server.register_function(self.attempt_introspection)
|
self._server.register_function(self.attempt_introspection)
|
||||||
|
self._server.register_function(self.execute_in_frame)
|
||||||
self._server.register_function(self.add_watch)
|
self._server.register_function(self.add_watch)
|
||||||
|
self._server.register_function(self.request_frame_document)
|
||||||
|
|
||||||
|
self.frame_stack = []
|
||||||
self.message_frame_dict = {}
|
self.message_frame_dict = {}
|
||||||
self.introspection_list = []
|
self.introspection_list = []
|
||||||
atexit.register(self.do_exit)
|
atexit.register(self.do_exit)
|
||||||
@@ -364,7 +369,28 @@ class DebuggerHarness(object):
|
|||||||
tp, val, tb = sys.exc_info()
|
tp, val, tb = sys.exc_info()
|
||||||
return self.get_exception_document(tp, val, tb)
|
return self.get_exception_document(tp, val, tb)
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
def execute_in_frame(self, frame_message, command):
|
||||||
|
frame = self.message_frame_dict[frame_message]
|
||||||
|
output = cStringIO.StringIO()
|
||||||
|
out = sys.stdout
|
||||||
|
err = sys.stderr
|
||||||
|
sys.stdout = output
|
||||||
|
sys.stderr = output
|
||||||
|
try:
|
||||||
|
exec command in frame.f_globals, frame.f_locals
|
||||||
|
return output.getvalue()
|
||||||
|
sys.stdout = out
|
||||||
|
sys.stderr = err
|
||||||
|
except:
|
||||||
|
sys.stdout = out
|
||||||
|
sys.stderr = err
|
||||||
|
|
||||||
|
tp, val, tb = sys.exc_info()
|
||||||
|
output = cStringIO.StringIO()
|
||||||
|
traceback.print_exception(tp, val, tb, file=output)
|
||||||
|
return output.getvalue()
|
||||||
|
|
||||||
def attempt_introspection(self, frame_message, chain):
|
def attempt_introspection(self, frame_message, chain):
|
||||||
try:
|
try:
|
||||||
frame = self.message_frame_dict[frame_message]
|
frame = self.message_frame_dict[frame_message]
|
||||||
@@ -608,22 +634,27 @@ class DebuggerHarness(object):
|
|||||||
|
|
||||||
|
|
||||||
def getFrameXML(self, base_frame):
|
def getFrameXML(self, base_frame):
|
||||||
doc = getDOMImplementation().createDocument(None, "stack", None)
|
|
||||||
top_element = doc.documentElement
|
|
||||||
|
|
||||||
stack = []
|
self.frame_stack = []
|
||||||
frame = base_frame
|
frame = base_frame
|
||||||
while frame is not None:
|
while frame is not None:
|
||||||
if((frame.f_code.co_filename.count('DebuggerHarness.py') == 0) or _DEBUG_DEBUGGER):
|
if((frame.f_code.co_filename.count('DebuggerHarness.py') == 0) or _DEBUG_DEBUGGER):
|
||||||
stack.append(frame)
|
self.frame_stack.append(frame)
|
||||||
frame = frame.f_back
|
frame = frame.f_back
|
||||||
stack.reverse()
|
self.frame_stack.reverse()
|
||||||
self.message_frame_dict = {}
|
self.message_frame_dict = {}
|
||||||
for f in stack:
|
doc = getDOMImplementation().createDocument(None, "stack", None)
|
||||||
self.addFrame(f,top_element, doc)
|
top_element = doc.documentElement
|
||||||
|
numberFrames = len(self.frame_stack)
|
||||||
|
for index in range(numberFrames):
|
||||||
|
frame = self.frame_stack[index]
|
||||||
|
message = self._adb.frame2message(frame)
|
||||||
|
# We include globals and locals only for the last frame as an optimization for cases
|
||||||
|
# where there are a lot of frames.
|
||||||
|
self.addFrame(frame, top_element, doc, includeContent=(index == numberFrames - 1))
|
||||||
return doc.toxml()
|
return doc.toxml()
|
||||||
|
|
||||||
def addFrame(self, frame, root_element, document):
|
def addFrame(self, frame, root_element, document, includeContent=False):
|
||||||
frameNode = document.createElement('frame')
|
frameNode = document.createElement('frame')
|
||||||
root_element.appendChild(frameNode)
|
root_element.appendChild(frameNode)
|
||||||
|
|
||||||
@@ -633,11 +664,19 @@ class DebuggerHarness(object):
|
|||||||
frameNode.setAttribute('line', str(frame.f_lineno))
|
frameNode.setAttribute('line', str(frame.f_lineno))
|
||||||
message = self._adb.frame2message(frame)
|
message = self._adb.frame2message(frame)
|
||||||
frameNode.setAttribute('message', message)
|
frameNode.setAttribute('message', message)
|
||||||
#print "Frame: %s %s %s" %(message, frame.f_lineno, filename)
|
|
||||||
self.message_frame_dict[message] = frame
|
self.message_frame_dict[message] = frame
|
||||||
self.addDict(frameNode, "locals", frame.f_locals, document, 2)
|
if includeContent:
|
||||||
self.addNode(frameNode, "globals", frame.f_globals, document)
|
self.addDict(frameNode, "locals", frame.f_locals, document, 2)
|
||||||
|
self.addNode(frameNode, "globals", frame.f_globals, document)
|
||||||
|
|
||||||
|
def request_frame_document(self, message):
|
||||||
|
frame = self.message_frame_dict[message]
|
||||||
|
doc = getDOMImplementation().createDocument(None, "stack", None)
|
||||||
|
top_element = doc.documentElement
|
||||||
|
if frame:
|
||||||
|
self.addFrame(frame, top_element, doc, includeContent=True)
|
||||||
|
return xmlrpclib.Binary(bz2.compress(doc.toxml()))
|
||||||
|
|
||||||
def getRepr(self, varName, globals, locals):
|
def getRepr(self, varName, globals, locals):
|
||||||
try:
|
try:
|
||||||
return repr(eval(varName, globals, locals))
|
return repr(eval(varName, globals, locals))
|
||||||
@@ -647,23 +686,25 @@ class DebuggerHarness(object):
|
|||||||
|
|
||||||
def saferepr(self, thing):
|
def saferepr(self, thing):
|
||||||
try:
|
try:
|
||||||
return repr(thing)
|
try:
|
||||||
|
return repr(thing)
|
||||||
|
except:
|
||||||
|
return str(type(thing))
|
||||||
except:
|
except:
|
||||||
tp, val, tb = sys.exc_info()
|
tp, val, tb = sys.exc_info()
|
||||||
traceback.print_exception(tp, val, tb)
|
#traceback.print_exception(tp, val, tb)
|
||||||
return repr(val)
|
return repr(val)
|
||||||
|
|
||||||
# The debugger calls this method when it reaches a breakpoint.
|
# The debugger calls this method when it reaches a breakpoint.
|
||||||
def interaction(self, message, frame, info):
|
def interaction(self, message, frame, info):
|
||||||
if _VERBOSE:
|
if _VERBOSE:
|
||||||
print 'hit debug side interaction'
|
print 'hit debug side interaction'
|
||||||
self._userBreak = False
|
self._adb._userBreak = False
|
||||||
|
|
||||||
self._currentFrame = frame
|
self._currentFrame = frame
|
||||||
done = False
|
done = False
|
||||||
while not done:
|
while not done:
|
||||||
try:
|
try:
|
||||||
import bz2
|
|
||||||
xml = self.getFrameXML(frame)
|
xml = self.getFrameXML(frame)
|
||||||
arg = xmlrpclib.Binary(bz2.compress(xml))
|
arg = xmlrpclib.Binary(bz2.compress(xml))
|
||||||
if _VERBOSE:
|
if _VERBOSE:
|
||||||
|
@@ -41,6 +41,7 @@ import pickle
|
|||||||
import DebuggerHarness
|
import DebuggerHarness
|
||||||
import traceback
|
import traceback
|
||||||
import StringIO
|
import StringIO
|
||||||
|
|
||||||
if wx.Platform == '__WXMSW__':
|
if wx.Platform == '__WXMSW__':
|
||||||
try:
|
try:
|
||||||
import win32api
|
import win32api
|
||||||
@@ -72,7 +73,12 @@ class OutputReaderThread(threading.Thread):
|
|||||||
self._lineCount = 0
|
self._lineCount = 0
|
||||||
self._accumulate = accumulate
|
self._accumulate = accumulate
|
||||||
self._callbackOnExit = callbackOnExit
|
self._callbackOnExit = callbackOnExit
|
||||||
|
self.setDaemon(True)
|
||||||
|
|
||||||
|
def __del__(self):
|
||||||
|
# See comment on DebugCommandUI.StopExecution
|
||||||
|
self._keepGoing = False
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
file = self._file
|
file = self._file
|
||||||
start = time.time()
|
start = time.time()
|
||||||
@@ -83,7 +89,7 @@ class OutputReaderThread(threading.Thread):
|
|||||||
text = file.readline()
|
text = file.readline()
|
||||||
if text == '' or text == None:
|
if text == '' or text == None:
|
||||||
self._keepGoing = False
|
self._keepGoing = False
|
||||||
elif not self._accumulate:
|
elif not self._accumulate and self._keepGoing:
|
||||||
self._callback_function(text)
|
self._callback_function(text)
|
||||||
else:
|
else:
|
||||||
# Should use a buffer? StringIO?
|
# Should use a buffer? StringIO?
|
||||||
@@ -91,11 +97,11 @@ class OutputReaderThread(threading.Thread):
|
|||||||
# Seems as though the read blocks if we got an error, so, to be
|
# Seems as though the read blocks if we got an error, so, to be
|
||||||
# sure that at least some of the exception gets printed, always
|
# sure that at least some of the exception gets printed, always
|
||||||
# send the first hundred lines back as they come in.
|
# send the first hundred lines back as they come in.
|
||||||
if self._lineCount < 100:
|
if self._lineCount < 100 and self._keepGoing:
|
||||||
self._callback_function(output)
|
self._callback_function(output)
|
||||||
self._lineCount += 1
|
self._lineCount += 1
|
||||||
output = ""
|
output = ""
|
||||||
elif time.time() - start > 0.25:
|
elif time.time() - start > 0.25 and self._keepGoing:
|
||||||
try:
|
try:
|
||||||
self._callback_function(output)
|
self._callback_function(output)
|
||||||
except wx._core.PyDeadObjectError:
|
except wx._core.PyDeadObjectError:
|
||||||
@@ -103,8 +109,8 @@ class OutputReaderThread(threading.Thread):
|
|||||||
self._keepGoing = False
|
self._keepGoing = False
|
||||||
start = time.time()
|
start = time.time()
|
||||||
output = ""
|
output = ""
|
||||||
except TypeError:
|
#except TypeError:
|
||||||
pass
|
# pass
|
||||||
except:
|
except:
|
||||||
tp, val, tb = sys.exc_info()
|
tp, val, tb = sys.exc_info()
|
||||||
print "Exception in OutputReaderThread.run():", tp, val
|
print "Exception in OutputReaderThread.run():", tp, val
|
||||||
@@ -118,7 +124,7 @@ class OutputReaderThread(threading.Thread):
|
|||||||
|
|
||||||
def AskToStop(self):
|
def AskToStop(self):
|
||||||
self._keepGoing = False
|
self._keepGoing = False
|
||||||
|
|
||||||
import wx.lib.newevent
|
import wx.lib.newevent
|
||||||
(UpdateTextEvent, EVT_UPDATE_STDTEXT) = wx.lib.newevent.NewEvent()
|
(UpdateTextEvent, EVT_UPDATE_STDTEXT) = wx.lib.newevent.NewEvent()
|
||||||
(UpdateErrorEvent, EVT_UPDATE_ERRTEXT) = wx.lib.newevent.NewEvent()
|
(UpdateErrorEvent, EVT_UPDATE_ERRTEXT) = wx.lib.newevent.NewEvent()
|
||||||
@@ -165,7 +171,6 @@ class Executor:
|
|||||||
self._stdOutReader = None
|
self._stdOutReader = None
|
||||||
self._stdErrReader = None
|
self._stdErrReader = None
|
||||||
self._process = None
|
self._process = None
|
||||||
DebuggerService.executors.append(self)
|
|
||||||
|
|
||||||
def OutCall(self, text):
|
def OutCall(self, text):
|
||||||
evt = UpdateTextEvent(value = text)
|
evt = UpdateTextEvent(value = text)
|
||||||
@@ -180,8 +185,6 @@ class Executor:
|
|||||||
startIn = str(os.getcwd())
|
startIn = str(os.getcwd())
|
||||||
startIn = os.path.abspath(startIn)
|
startIn = os.path.abspath(startIn)
|
||||||
command = self._cmd + ' ' + arguments
|
command = self._cmd + ' ' + arguments
|
||||||
#stdinput = process.IOBuffer()
|
|
||||||
#self._process = process.ProcessProxy(command, mode='b', cwd=startIn, stdin=stdinput)
|
|
||||||
self._process = process.ProcessOpen(command, mode='b', cwd=startIn, env=environment)
|
self._process = process.ProcessOpen(command, mode='b', cwd=startIn, env=environment)
|
||||||
# Kick off threads to read stdout and stderr and write them
|
# Kick off threads to read stdout and stderr and write them
|
||||||
# to our text control.
|
# to our text control.
|
||||||
@@ -189,35 +192,46 @@ class Executor:
|
|||||||
self._stdOutReader.start()
|
self._stdOutReader.start()
|
||||||
self._stdErrReader = OutputReaderThread(self._process.stderr, self._stdErrCallback, accumulate=False)
|
self._stdErrReader = OutputReaderThread(self._process.stderr, self._stdErrCallback, accumulate=False)
|
||||||
self._stdErrReader.start()
|
self._stdErrReader.start()
|
||||||
|
|
||||||
|
|
||||||
def DoStopExecution(self):
|
def DoStopExecution(self):
|
||||||
|
# See comment on DebugCommandUI.StopExecution
|
||||||
if(self._process != None):
|
if(self._process != None):
|
||||||
self._process.kill()
|
|
||||||
self._process.close()
|
|
||||||
self._process = None
|
|
||||||
if(self._stdOutReader != None):
|
|
||||||
self._stdOutReader.AskToStop()
|
self._stdOutReader.AskToStop()
|
||||||
if(self._stdErrReader != None):
|
|
||||||
self._stdErrReader.AskToStop()
|
self._stdErrReader.AskToStop()
|
||||||
DebuggerService.executors.remove(self)
|
try:
|
||||||
|
self._process.kill(gracePeriod=2.0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
self._process = None
|
||||||
|
|
||||||
class RunCommandUI(wx.Panel):
|
class RunCommandUI(wx.Panel):
|
||||||
|
runners = []
|
||||||
|
|
||||||
|
def ShutdownAllRunners():
|
||||||
|
# See comment on DebugCommandUI.StopExecution
|
||||||
|
for runner in RunCommandUI.runners:
|
||||||
|
try:
|
||||||
|
runner.StopExecution(None)
|
||||||
|
except wx._core.PyDeadObjectError:
|
||||||
|
pass
|
||||||
|
RunCommandUI.runners = []
|
||||||
|
ShutdownAllRunners = staticmethod(ShutdownAllRunners)
|
||||||
|
|
||||||
def __init__(self, parent, id, fileName):
|
def __init__(self, parent, id, fileName):
|
||||||
wx.Panel.__init__(self, parent, id)
|
wx.Panel.__init__(self, parent, id)
|
||||||
self._noteBook = parent
|
self._noteBook = parent
|
||||||
|
|
||||||
|
threading._VERBOSE = _VERBOSE
|
||||||
|
|
||||||
self.KILL_PROCESS_ID = wx.NewId()
|
self.KILL_PROCESS_ID = wx.NewId()
|
||||||
self.CLOSE_TAB_ID = wx.NewId()
|
self.CLOSE_TAB_ID = wx.NewId()
|
||||||
|
|
||||||
self.Bind(wx.EVT_END_PROCESS, self.OnProcessEnded)
|
|
||||||
|
|
||||||
# GUI Initialization follows
|
# GUI Initialization follows
|
||||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (30,1000), wx.TB_VERTICAL| wx.TB_FLAT, "Runner" )
|
self._tb = tb = wx.ToolBar(self, -1, wx.DefaultPosition, (30,1000), wx.TB_VERTICAL| wx.TB_FLAT, "Runner" )
|
||||||
tb.SetToolBitmapSize((16,16))
|
tb.SetToolBitmapSize((16,16))
|
||||||
sizer.Add(tb, 0, wx.EXPAND |wx.ALIGN_LEFT|wx.ALL, 1)
|
sizer.Add(tb, 0, wx.EXPAND|wx.ALIGN_LEFT|wx.ALL, 1)
|
||||||
|
|
||||||
close_bmp = getCloseBitmap()
|
close_bmp = getCloseBitmap()
|
||||||
tb.AddSimpleTool( self.CLOSE_TAB_ID, close_bmp, _('Close Window'))
|
tb.AddSimpleTool( self.CLOSE_TAB_ID, close_bmp, _('Close Window'))
|
||||||
@@ -245,12 +259,16 @@ class RunCommandUI(wx.Panel):
|
|||||||
self.SetSizer(sizer)
|
self.SetSizer(sizer)
|
||||||
sizer.Fit(self)
|
sizer.Fit(self)
|
||||||
|
|
||||||
|
self._stopped = False
|
||||||
# Executor initialization
|
# Executor initialization
|
||||||
self._executor = Executor(fileName, self, callbackOnExit=self.ExecutorFinished)
|
self._executor = Executor(fileName, self, callbackOnExit=self.ExecutorFinished)
|
||||||
self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
|
self.Bind(EVT_UPDATE_STDTEXT, self.AppendText)
|
||||||
self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
|
self.Bind(EVT_UPDATE_ERRTEXT, self.AppendErrorText)
|
||||||
|
|
||||||
|
RunCommandUI.runners.append(self)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
|
# See comment on DebugCommandUI.StopExecution
|
||||||
self._executor.DoStopExecution()
|
self._executor.DoStopExecution()
|
||||||
|
|
||||||
def Execute(self, initialArgs, startIn, environment):
|
def Execute(self, initialArgs, startIn, environment):
|
||||||
@@ -267,9 +285,11 @@ class RunCommandUI(wx.Panel):
|
|||||||
break
|
break
|
||||||
|
|
||||||
def StopExecution(self):
|
def StopExecution(self):
|
||||||
self.Unbind(EVT_UPDATE_STDTEXT)
|
if not self._stopped:
|
||||||
self.Unbind(EVT_UPDATE_ERRTEXT)
|
self._stopped = True
|
||||||
self._executor.DoStopExecution()
|
self.Unbind(EVT_UPDATE_STDTEXT)
|
||||||
|
self.Unbind(EVT_UPDATE_ERRTEXT)
|
||||||
|
self._executor.DoStopExecution()
|
||||||
|
|
||||||
def AppendText(self, event):
|
def AppendText(self, event):
|
||||||
self._textCtrl.SetReadOnly(False)
|
self._textCtrl.SetReadOnly(False)
|
||||||
@@ -295,10 +315,10 @@ class RunCommandUI(wx.Panel):
|
|||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
|
|
||||||
if id == self.KILL_PROCESS_ID:
|
if id == self.KILL_PROCESS_ID:
|
||||||
self._executor.DoStopExecution()
|
self.StopExecution()
|
||||||
|
|
||||||
elif id == self.CLOSE_TAB_ID:
|
elif id == self.CLOSE_TAB_ID:
|
||||||
self._executor.DoStopExecution()
|
self.StopExecution()
|
||||||
index = self._noteBook.GetSelection()
|
index = self._noteBook.GetSelection()
|
||||||
self._noteBook.GetPage(index).Show(False)
|
self._noteBook.GetPage(index).Show(False)
|
||||||
self._noteBook.RemovePage(index)
|
self._noteBook.RemovePage(index)
|
||||||
@@ -349,8 +369,6 @@ class RunCommandUI(wx.Panel):
|
|||||||
|
|
||||||
foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
|
foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
|
||||||
|
|
||||||
def OnProcessEnded(self, evt):
|
|
||||||
self._executor.DoStopExecution()
|
|
||||||
|
|
||||||
DEFAULT_PORT = 32032
|
DEFAULT_PORT = 32032
|
||||||
DEFAULT_HOST = 'localhost'
|
DEFAULT_HOST = 'localhost'
|
||||||
@@ -374,9 +392,13 @@ class DebugCommandUI(wx.Panel):
|
|||||||
DebuggerRunning = staticmethod(DebuggerRunning)
|
DebuggerRunning = staticmethod(DebuggerRunning)
|
||||||
|
|
||||||
def ShutdownAllDebuggers():
|
def ShutdownAllDebuggers():
|
||||||
|
# See comment on DebugCommandUI.StopExecution
|
||||||
for debugger in DebugCommandUI.debuggers:
|
for debugger in DebugCommandUI.debuggers:
|
||||||
debugger.StopExecution(None)
|
try:
|
||||||
|
debugger.StopExecution(None)
|
||||||
|
except wx._core.PyDeadObjectError:
|
||||||
|
pass
|
||||||
|
DebugCommandUI.debuggers = []
|
||||||
ShutdownAllDebuggers = staticmethod(ShutdownAllDebuggers)
|
ShutdownAllDebuggers = staticmethod(ShutdownAllDebuggers)
|
||||||
|
|
||||||
def GetAvailablePort():
|
def GetAvailablePort():
|
||||||
@@ -549,9 +571,8 @@ class DebugCommandUI(wx.Panel):
|
|||||||
self.framesTab.PopulateBPList()
|
self.framesTab.PopulateBPList()
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
if self in DebugCommandUI.debuggers:
|
# See comment on DebugCommandUI.StopExecution
|
||||||
DebugCommandUI.debuggers.remove(self)
|
self.StopExecution(None)
|
||||||
|
|
||||||
|
|
||||||
def DisableWhileDebuggerRunning(self):
|
def DisableWhileDebuggerRunning(self):
|
||||||
self._tb.EnableTool(self.STEP_ID, False)
|
self._tb.EnableTool(self.STEP_ID, False)
|
||||||
@@ -655,23 +676,42 @@ class DebugCommandUI(wx.Panel):
|
|||||||
|
|
||||||
|
|
||||||
def StopExecution(self, event):
|
def StopExecution(self, event):
|
||||||
self._stopped = True
|
# This is a general comment on shutdown for the running and debugged processes. Basically, the
|
||||||
self.DisableAfterStop()
|
# current state of this is the result of trial and error coding. The common problems were memory
|
||||||
try:
|
# access violations and threads that would not exit. Making the OutputReaderThreads daemons seems
|
||||||
self._callback.ServerClose()
|
# to have side-stepped the hung thread issue. Being very careful not to touch things after calling
|
||||||
except:
|
# process.py:ProcessOpen.kill() also seems to have fixed the memory access violations, but if there
|
||||||
pass
|
# were more ugliness discovered I would not be surprised. If anyone has any help/advice, please send
|
||||||
try:
|
# it on to mfryer@activegrid.com.
|
||||||
if self._executor:
|
if not self._stopped:
|
||||||
self._executor.DoStopExecution()
|
self._stopped = True
|
||||||
self._executor = None
|
try:
|
||||||
except:
|
self.DisableAfterStop()
|
||||||
pass
|
except wx._core.PyDeadObjectError:
|
||||||
self.DeleteCurrentLineMarkers()
|
pass
|
||||||
DebugCommandUI.ReturnPortToPool(self._debuggerPort)
|
try:
|
||||||
DebugCommandUI.ReturnPortToPool(self._guiPort)
|
self._callback.ShutdownServer()
|
||||||
DebugCommandUI.ReturnPortToPool(self._debuggerBreakPort)
|
except:
|
||||||
|
tp,val,tb = sys.exc_info()
|
||||||
|
traceback.print_exception(tp, val, tb)
|
||||||
|
|
||||||
|
try:
|
||||||
|
self.DeleteCurrentLineMarkers()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
DebugCommandUI.ReturnPortToPool(self._debuggerPort)
|
||||||
|
DebugCommandUI.ReturnPortToPool(self._guiPort)
|
||||||
|
DebugCommandUI.ReturnPortToPool(self._debuggerBreakPort)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
try:
|
||||||
|
if self._executor:
|
||||||
|
self._executor.DoStopExecution()
|
||||||
|
self._executor = None
|
||||||
|
except:
|
||||||
|
tp,val,tb = sys.exc_info()
|
||||||
|
traceback.print_exception(tp, val, tb)
|
||||||
def StopAndRemoveUI(self, event):
|
def StopAndRemoveUI(self, event):
|
||||||
self.StopExecution(None)
|
self.StopExecution(None)
|
||||||
if self in DebugCommandUI.debuggers:
|
if self in DebugCommandUI.debuggers:
|
||||||
@@ -695,7 +735,7 @@ class DebugCommandUI(wx.Panel):
|
|||||||
self.framesTab.AppendErrorText(event.value)
|
self.framesTab.AppendErrorText(event.value)
|
||||||
|
|
||||||
def OnClearOutput(self, event):
|
def OnClearOutput(self, event):
|
||||||
self.framesTab.ClearOutput()
|
self.framesTab.ClearOutput(None)
|
||||||
|
|
||||||
def SwitchToOutputTab(self):
|
def SwitchToOutputTab(self):
|
||||||
self.framesTab.SwitchToOutputTab()
|
self.framesTab.SwitchToOutputTab()
|
||||||
@@ -899,10 +939,10 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
self._notebook.Hide()
|
self._notebook.Hide()
|
||||||
sizer3.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
sizer3.Add(self._notebook, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 1)
|
||||||
self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId())
|
self.consoleTab = self.MakeConsoleTab(self._notebook, wx.NewId())
|
||||||
#self.inspectConsoleTab = self.MakeInspectConsoleTab(self._notebook, wx.NewId())
|
self.inspectConsoleTab = self.MakeInspectConsoleTab(self._notebook, wx.NewId())
|
||||||
self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId())
|
self.breakPointsTab = self.MakeBreakPointsTab(self._notebook, wx.NewId())
|
||||||
self._notebook.AddPage(self.consoleTab, "Output")
|
self._notebook.AddPage(self.consoleTab, "Output")
|
||||||
#self._notebook.AddPage(self.inspectConsoleTab, "Interact")
|
self._notebook.AddPage(self.inspectConsoleTab, "Interact")
|
||||||
self._notebook.AddPage(self.breakPointsTab, "Break Points")
|
self._notebook.AddPage(self.breakPointsTab, "Break Points")
|
||||||
|
|
||||||
self.SetMinimumPaneSize(20)
|
self.SetMinimumPaneSize(20)
|
||||||
@@ -936,23 +976,74 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
return panel
|
return panel
|
||||||
|
|
||||||
def MakeInspectConsoleTab(self, parent, id):
|
def MakeInspectConsoleTab(self, parent, id):
|
||||||
def OnEnterPressed(event):
|
self.command_list = []
|
||||||
print "Enter text was %s" % event.GetString()
|
self.command_index = 0
|
||||||
def OnText(event):
|
def ExecuteCommand(command):
|
||||||
print "Command was %s" % event.GetString()
|
if not len(self.command_list) or not command == self.command_list[len(self.command_list) -1]:
|
||||||
|
self.command_list.append(command)
|
||||||
|
self.command_index = len(self.command_list) - 1
|
||||||
|
retval = self._ui._callback._debuggerServer.execute_in_frame(self._framesChoiceCtrl.GetStringSelection(), command)
|
||||||
|
self._interCtrl.AddText("\n" + str(retval))
|
||||||
|
self._interCtrl.ScrollToLine(self._interCtrl.GetLineCount())
|
||||||
|
# Refresh the tree view in case this command resulted in changes there. TODO: Need to reopen tree items.
|
||||||
|
self.PopulateTreeFromFrameMessage(self._framesChoiceCtrl.GetStringSelection())
|
||||||
|
|
||||||
|
def ReplaceLastLine(command):
|
||||||
|
line = self._interCtrl.GetLineCount() - 1
|
||||||
|
self._interCtrl.GotoLine(line)
|
||||||
|
start = self._interCtrl.GetCurrentPos()
|
||||||
|
self._interCtrl.SetTargetStart(start)
|
||||||
|
end = self._interCtrl.GetLineEndPosition(line)
|
||||||
|
self._interCtrl.SetTargetEnd(end)
|
||||||
|
self._interCtrl.ReplaceTarget(">>> " + command)
|
||||||
|
self._interCtrl.GotoLine(line)
|
||||||
|
self._interCtrl.SetSelectionStart(self._interCtrl.GetLineEndPosition(line))
|
||||||
|
|
||||||
panel = wx.Panel(parent, id)
|
def OnKeyPressed(event):
|
||||||
try:
|
key = event.KeyCode()
|
||||||
|
if key == wx.WXK_DELETE or key == wx.WXK_BACK:
|
||||||
|
if self._interCtrl.GetLine(self._interCtrl.GetCurrentLine()) == ">>> ":
|
||||||
|
return
|
||||||
|
elif key == wx.WXK_RETURN:
|
||||||
|
command = self._interCtrl.GetLine(self._interCtrl.GetCurrentLine())[4:]
|
||||||
|
ExecuteCommand(command)
|
||||||
|
self._interCtrl.AddText("\n>>> ")
|
||||||
|
return
|
||||||
|
elif key == wx.WXK_UP:
|
||||||
|
if not len(self.command_list):
|
||||||
|
return
|
||||||
|
ReplaceLastLine(self.command_list[self.command_index])
|
||||||
|
if self.command_index == 0:
|
||||||
|
self.command_index = len(self.command_list) - 1
|
||||||
|
else:
|
||||||
|
self.command_index = self.command_index - 1
|
||||||
|
return
|
||||||
|
elif key == wx.WXK_DOWN:
|
||||||
|
if not len(self.command_list):
|
||||||
|
return
|
||||||
|
if self.command_index < len(self.command_list) - 1:
|
||||||
|
self.command_index = self.command_index + 1
|
||||||
|
else:
|
||||||
|
self.command_index = 0
|
||||||
|
ReplaceLastLine(self.command_list[self.command_index])
|
||||||
|
return
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
try:
|
||||||
|
panel = wx.Panel(parent, id)
|
||||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
self._ictextCtrl = wx.TextCtrl(panel, wx.NewId(), style=wx.TE_MULTILINE|wx.TE_RICH|wx.HSCROLL)
|
self._interCtrl = STCTextEditor.TextCtrl(panel, wx.NewId())
|
||||||
sizer.Add(self._ictextCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 2)
|
sizer.Add(self._interCtrl, 1, wx.ALIGN_LEFT|wx.ALL|wx.EXPAND, 2)
|
||||||
self._ictextCtrl.Bind(wx.EVT_TEXT_ENTER, OnEnterPressed)
|
self._interCtrl.SetViewLineNumbers(False)
|
||||||
self._ictextCtrl.Bind(wx.EVT_TEXT, OnText)
|
|
||||||
if wx.Platform == '__WXMSW__':
|
if wx.Platform == '__WXMSW__':
|
||||||
font = "Courier New"
|
font = "Courier New"
|
||||||
else:
|
else:
|
||||||
font = "Courier"
|
font = "Courier"
|
||||||
self._ictextCtrl.SetDefaultStyle(wx.TextAttr(font=wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font)))
|
self._interCtrl.SetFont(wx.Font(9, wx.DEFAULT, wx.NORMAL, wx.NORMAL, faceName = font))
|
||||||
|
self._interCtrl.SetFontColor(wx.BLACK)
|
||||||
|
self._interCtrl.StyleClearAll()
|
||||||
|
wx.EVT_KEY_DOWN(self._interCtrl, OnKeyPressed)
|
||||||
|
self._interCtrl.AddText(">>> ")
|
||||||
panel.SetSizer(sizer)
|
panel.SetSizer(sizer)
|
||||||
except:
|
except:
|
||||||
tp, val, tb = sys.exc_info()
|
tp, val, tb = sys.exc_info()
|
||||||
@@ -1066,6 +1157,7 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
tree = self._treeCtrl
|
tree = self._treeCtrl
|
||||||
root = self._root
|
root = self._root
|
||||||
tree.DeleteChildren(root)
|
tree.DeleteChildren(root)
|
||||||
|
self._interCtrl.Enable(False)
|
||||||
|
|
||||||
#tree.Hide()
|
#tree.Hide()
|
||||||
|
|
||||||
@@ -1088,6 +1180,8 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
|
|
||||||
def LoadFramesListXML(self, framesXML):
|
def LoadFramesListXML(self, framesXML):
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
|
self._interCtrl.Enable(True)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
domDoc = parseString(framesXML)
|
domDoc = parseString(framesXML)
|
||||||
list = self._framesChoiceCtrl
|
list = self._framesChoiceCtrl
|
||||||
@@ -1103,6 +1197,7 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
frame_count += 1
|
frame_count += 1
|
||||||
index = len(self._stack) - 1
|
index = len(self._stack) - 1
|
||||||
list.SetSelection(index)
|
list.SetSelection(index)
|
||||||
|
|
||||||
node = self._stack[index]
|
node = self._stack[index]
|
||||||
self.currentItem = index
|
self.currentItem = index
|
||||||
self.PopulateTreeFromFrameNode(node)
|
self.PopulateTreeFromFrameNode(node)
|
||||||
@@ -1121,13 +1216,20 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
|
|
||||||
|
|
||||||
def ListItemSelected(self, event):
|
def ListItemSelected(self, event):
|
||||||
message = event.GetString()
|
self.PopulateTreeFromFrameMessage(event.GetString())
|
||||||
|
self.OnSyncFrame(None)
|
||||||
|
|
||||||
|
def PopulateTreeFromFrameMessage(self, message):
|
||||||
index = 0
|
index = 0
|
||||||
for node in self._stack:
|
for node in self._stack:
|
||||||
if node.getAttribute("message") == message:
|
if node.getAttribute("message") == message:
|
||||||
|
binType = self._ui._callback._debuggerServer.request_frame_document(message)
|
||||||
|
xmldoc = bz2.decompress(binType.data)
|
||||||
|
domDoc = parseString(xmldoc)
|
||||||
|
nodeList = domDoc.getElementsByTagName('frame')
|
||||||
self.currentItem = index
|
self.currentItem = index
|
||||||
self.PopulateTreeFromFrameNode(node)
|
if len(nodeList):
|
||||||
self.OnSyncFrame(None)
|
self.PopulateTreeFromFrameNode(nodeList[0])
|
||||||
return
|
return
|
||||||
index = index + 1
|
index = index + 1
|
||||||
|
|
||||||
@@ -1146,7 +1248,8 @@ class FramesUI(wx.SplitterWindow):
|
|||||||
if not firstChild:
|
if not firstChild:
|
||||||
firstChild = treeNode
|
firstChild = treeNode
|
||||||
tree.Expand(root)
|
tree.Expand(root)
|
||||||
tree.Expand(firstChild)
|
if firstChild:
|
||||||
|
tree.Expand(firstChild)
|
||||||
self._p2.FitInside()
|
self._p2.FitInside()
|
||||||
|
|
||||||
def IntrospectCallback(self, event):
|
def IntrospectCallback(self, event):
|
||||||
@@ -1252,7 +1355,13 @@ class DebuggerView(Service.ServiceView):
|
|||||||
|
|
||||||
def OnToolClicked(self, event):
|
def OnToolClicked(self, event):
|
||||||
self.GetFrame().ProcessEvent(event)
|
self.GetFrame().ProcessEvent(event)
|
||||||
|
|
||||||
|
def ProcessUpdateUIEvent(self, event):
|
||||||
|
return False
|
||||||
|
|
||||||
|
def ProcessEvent(self, event):
|
||||||
|
return False
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# Class methods
|
# Class methods
|
||||||
#-----------------------------------------------------------------------------
|
#-----------------------------------------------------------------------------
|
||||||
@@ -1396,9 +1505,9 @@ class DebuggerCallback:
|
|||||||
def start(self):
|
def start(self):
|
||||||
self._serverHandlerThread.start()
|
self._serverHandlerThread.start()
|
||||||
|
|
||||||
def ServerClose(self):
|
def ShutdownServer(self):
|
||||||
rbt = RequestBreakThread(self._breakServer, kill=True)
|
#rbt = RequestBreakThread(self._breakServer, kill=True)
|
||||||
rbt.start()
|
#rbt.start()
|
||||||
self.setWaiting(False)
|
self.setWaiting(False)
|
||||||
if self._serverHandlerThread:
|
if self._serverHandlerThread:
|
||||||
self._serverHandlerThread.AskToStop()
|
self._serverHandlerThread.AskToStop()
|
||||||
@@ -1410,29 +1519,21 @@ class DebuggerCallback:
|
|||||||
|
|
||||||
def SingleStep(self):
|
def SingleStep(self):
|
||||||
self._debuggerUI.DisableWhileDebuggerRunning()
|
self._debuggerUI.DisableWhileDebuggerRunning()
|
||||||
#dot = DebuggerOperationThread(self._debuggerServer.set_step)
|
|
||||||
#dot.start()
|
|
||||||
self._debuggerServer.set_step() # Figure out where to set allowNone
|
self._debuggerServer.set_step() # Figure out where to set allowNone
|
||||||
self.waitForRPC()
|
self.waitForRPC()
|
||||||
|
|
||||||
def Next(self):
|
def Next(self):
|
||||||
self._debuggerUI.DisableWhileDebuggerRunning()
|
self._debuggerUI.DisableWhileDebuggerRunning()
|
||||||
#dot = DebuggerOperationThread(self._debuggerServer.set_next)
|
|
||||||
#dot.start()
|
|
||||||
self._debuggerServer.set_next()
|
self._debuggerServer.set_next()
|
||||||
self.waitForRPC()
|
self.waitForRPC()
|
||||||
|
|
||||||
def Continue(self):
|
def Continue(self):
|
||||||
self._debuggerUI.DisableWhileDebuggerRunning()
|
self._debuggerUI.DisableWhileDebuggerRunning()
|
||||||
#dot = DebuggerOperationThread(self._debuggerServer.set_continue)
|
|
||||||
#dot.start()
|
|
||||||
self._debuggerServer.set_continue()
|
self._debuggerServer.set_continue()
|
||||||
self.waitForRPC()
|
self.waitForRPC()
|
||||||
|
|
||||||
def Return(self):
|
def Return(self):
|
||||||
self._debuggerUI.DisableWhileDebuggerRunning()
|
self._debuggerUI.DisableWhileDebuggerRunning()
|
||||||
#dot = DebuggerOperationThread(self._debuggerServer.set_return)
|
|
||||||
#dot.start()
|
|
||||||
self._debuggerServer.set_return()
|
self._debuggerServer.set_return()
|
||||||
self.waitForRPC()
|
self.waitForRPC()
|
||||||
|
|
||||||
@@ -1498,7 +1599,6 @@ class DebuggerCallback:
|
|||||||
if _VERBOSE: print "+"*40
|
if _VERBOSE: print "+"*40
|
||||||
|
|
||||||
class DebuggerService(Service.Service):
|
class DebuggerService(Service.Service):
|
||||||
executors = []
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Constants
|
# Constants
|
||||||
@@ -1509,11 +1609,6 @@ class DebuggerService(Service.Service):
|
|||||||
DEBUG_ID = wx.NewId()
|
DEBUG_ID = wx.NewId()
|
||||||
DEBUG_WEBSERVER_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):
|
def ComparePaths(first, second):
|
||||||
one = DebuggerService.ExpandPath(first)
|
one = DebuggerService.ExpandPath(first)
|
||||||
@@ -1530,7 +1625,8 @@ class DebuggerService(Service.Service):
|
|||||||
try:
|
try:
|
||||||
return win32api.GetLongPathName(path)
|
return win32api.GetLongPathName(path)
|
||||||
except:
|
except:
|
||||||
print "Cannot get long path for %s" % path
|
if _VERBOSE:
|
||||||
|
print "Cannot get long path for %s" % path
|
||||||
|
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@@ -1755,6 +1851,7 @@ class DebuggerService(Service.Service):
|
|||||||
|
|
||||||
def OnExit(self):
|
def OnExit(self):
|
||||||
DebugCommandUI.ShutdownAllDebuggers()
|
DebugCommandUI.ShutdownAllDebuggers()
|
||||||
|
RunCommandUI.ShutdownAllRunners()
|
||||||
|
|
||||||
def OnRunProject(self, event):
|
def OnRunProject(self, event):
|
||||||
if _WINDOWS and not _PYWIN32_INSTALLED:
|
if _WINDOWS and not _PYWIN32_INSTALLED:
|
||||||
@@ -2010,9 +2107,6 @@ class CommandPropertiesDialog(wx.Dialog):
|
|||||||
self._lastStartIn = str(os.getcwd())
|
self._lastStartIn = str(os.getcwd())
|
||||||
self._startEntry = wx.TextCtrl(self, -1, self._lastStartIn)
|
self._startEntry = wx.TextCtrl(self, -1, self._lastStartIn)
|
||||||
self._startEntry.SetToolTipString(self._lastStartIn)
|
self._startEntry.SetToolTipString(self._lastStartIn)
|
||||||
def TextChanged2(event):
|
|
||||||
self._startEntry.SetToolTipString(event.GetString())
|
|
||||||
self.Bind(wx.EVT_TEXT, TextChanged2, self._startEntry)
|
|
||||||
|
|
||||||
flexGridSizer.Add(self._startEntry, 1, wx.EXPAND)
|
flexGridSizer.Add(self._startEntry, 1, wx.EXPAND)
|
||||||
self._findDir = wx.Button(self, -1, _("Browse..."))
|
self._findDir = wx.Button(self, -1, _("Browse..."))
|
||||||
@@ -2240,19 +2334,20 @@ def getBreakIcon():
|
|||||||
return wx.IconFromBitmap(getBreakBitmap())
|
return wx.IconFromBitmap(getBreakBitmap())
|
||||||
|
|
||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
|
|
||||||
def getClearOutputData():
|
def getClearOutputData():
|
||||||
return \
|
return \
|
||||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
||||||
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
||||||
\x00\x00\xb4IDAT8\x8d\xa5\x92\xdd\r\x03!\x0c\x83\xbf\xa0n\xd4\x9d\xda5\xb81\
|
\x00\x00\xb7IDAT8\x8d\xa5\x93\xdd\x11\xc3 \x0c\x83%`\xa3\xee\xd4\xaeA\xc6\
|
||||||
\xbaS\xbb\x12\xee\x03?\xe5\x08\xe5N\xba\xbc Db\xec\xd8p\xb1l\xb8\xa7\x83\xfe\
|
\xe8N\xedF%\xea\x03\t\x81\xf0\x97\xbb\xf8%G\xce\xfe\x90eC\x1a\x8b;\xe1\xf2\
|
||||||
\xb0\x02H\x92F\xc0_\xa3\x99$\x99\x99\xedznc\xe36\x81\x88\x98"\xb2\x02\xa2\
|
\x83\xd6\xa0Q2\x8de\xf5oW\xa05H\xea\xd7\x93\x84$\x18\xeb\n\x88;\'.\xd5\x1d\
|
||||||
\x1e\xc4Q\x9aUD\x161\xcd\xde\x1c\x83\x15\x084)\x8d\xc5)\x06\xab\xaaZ\x92\xee\
|
\x80\x07\xe1\xa1\x1d\xa2\x1cbF\x92\x0f\x80\xe0\xd1 \xb7\x14\x8c \x00*\x15\
|
||||||
\xce\x11W\xdbGD\x0cIT\x06\xe7\x00\xdeY\xfe\xcc\x89\x06\xf0\xf2\x99\x00\xe0\
|
\x97\x14\x8c\x8246\x1a\xf8\x98\'/\xdf\xd8Jn\xe65\xc0\xa7\x90_L"\x01\xde\x9d\
|
||||||
\x91\x7f\xab\x83\xed\xa4\xc8\xafK\x0c\xcf\x92\x83\x99\x8d\xe3p\xef\xe4\xa1\
|
\xda\xa7\x92\xfb\xc5w\xdf\t\x07\xc4\x05ym{\xd0\x1a\xe3\xb9xS\x81\x04\x18\x05\
|
||||||
\x0b\xe57j\xc8:\x06\t\x08\x87.H\xb2n\xa8\xc9\xa9\x12vQ\xfeG"\xe3\xacw\x00\
|
\xc9\x04\xc9a\x00Dc9\x9d\x82\xa4\xbc\xe8P\xb2\xb5P\xac\xf2\x0c\xd4\xf5\x00\
|
||||||
\x10$M\xd3\x86_\xf0\xe5\xfc\xb4\xfa\x02\xcb\x13j\x10\xc5\xd7\x92D\x00\x00\
|
\x88>\xac\xe17\x84\xe4\xb9G\x8b7\x9f\xf3\x1fsUl^\x7f\xe7y\x0f\x00\x00\x00\
|
||||||
\x00\x00IEND\xaeB`\x82'
|
\x00IEND\xaeB`\x82'
|
||||||
|
|
||||||
def getClearOutputBitmap():
|
def getClearOutputBitmap():
|
||||||
return BitmapFromImage(getClearOutputImage())
|
return BitmapFromImage(getClearOutputImage())
|
||||||
@@ -2295,13 +2390,15 @@ def getContinueData():
|
|||||||
return \
|
return \
|
||||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
||||||
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
||||||
\x00\x00\x9eIDAT8\x8d\xbd\x92\xd1\r\x83@\x0cC\xed\x8a\x11X\xac\x1b\xddF,\xd6\
|
\x00\x00\xcdIDAT8\x8d\xa5\x93\xd1\r\xc20\x0cD\xef\xec,\xc0b\x88\x8d`$\x06Cb\
|
||||||
\x11\x90\xdc\x0f\x9a\x93s)\x14Z\xa9\x91\x10\n\x97\xbc\xd89\x80?\x84\x1a\xa4\
|
\x81\xc6\xc7GI\xeb\x94RZq?U"\xdby\xe7SIs\xfc#\xfbU\xa0\xa8\xba\xc6\xa0og\xee\
|
||||||
\x83\xfc\x1c$\x1e)7\xdf<Y0\xaf\x0b\xe6\xf5\x1d\xa1\xb5\x13C\x03 !\xaa\xfd\
|
!P\xd4y\x80\x04\xf3\xc2U\x82{\x9ct\x8f\x93\xb0\xa2\xdbm\xf5\xba\'h\xcdg=`\
|
||||||
\xed\n:mr\xc0\x1d\x8f\xc9\x9a!\t$\xe5\xd3I\xe2\xe5B$\x99\x00[\x01\xe8\xc5\
|
\xeeTT\xd1\xc6o& \t\x9a\x13\x00J\x9ev\xb1\'\xa3~\x14+\xbfN\x12\x92\x00@\xe6\
|
||||||
\xd9G\xfaN`\xd8\x81I\xed\x8c\xb19\x94\x8d\xcbL\x00;t\xcf\x9fwPh\xdb\x0e\xe8\
|
\x85\xdd\x00\x000w\xe6\xe2\xde\xc7|\xdf\x08\xba\x1d(\xaa2n+\xca\xcd\x8d,\xea\
|
||||||
\xd3,\x17\x8b\xc7\x9d\xbb>\x8a \xec5\x94\tc\xc4\x12\xab\x94\xeb\x7fkWr\xc9B%\
|
\x98\xc4\x07\x01\x00D\x1dd^\xa8\xa8j\x9ew\xed`\xa9\x16\x99\xde\xa6G\x8b\xd3Y\
|
||||||
\xfc\xd2\xfcM<\x01\xf6tn\x12O3c\xe6\x00\x00\x00\x00IEND\xaeB`\x82'
|
\xe6\x85]\n\r\x7f\x99\xf5\x96Jnlz#\xab\xdb\xc1\x17\x19\xb0XV\xc2\xdf\xa3)\
|
||||||
|
\x85<\xe4\x88\x85.F\x9a\xf3H3\xb0\xf3g\xda\xd2\x0b\xc5_|\x17\xe8\xf5R\xd6\
|
||||||
|
\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||||
|
|
||||||
def getContinueBitmap():
|
def getContinueBitmap():
|
||||||
return BitmapFromImage(getContinueImage())
|
return BitmapFromImage(getContinueImage())
|
||||||
@@ -2361,12 +2458,12 @@ def getStepInIcon():
|
|||||||
#----------------------------------------------------------------------
|
#----------------------------------------------------------------------
|
||||||
def getStopData():
|
def getStopData():
|
||||||
return \
|
return \
|
||||||
"\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x06\
|
||||||
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
\x00\x00\x00\x1f\xf3\xffa\x00\x00\x00\x04sBIT\x08\x08\x08\x08|\x08d\x88\x00\
|
||||||
\x00\x00FIDAT8\x8d\xed\x91\xc1\t\xc00\x0c\x03O!\x0b\xa9\xfb\xef\xa6\xfcB\xa1\
|
\x00\x00QIDAT8\x8d\xdd\x93A\n\xc00\x08\x04g\xb5\xff\x7fq\x13sn\xda&\x01\x0b\
|
||||||
N\t\xf4Wr\xa0\x8f\xb1\x0f\x81\xe1\x97\xe4-\xb6}_V%\xc8\xc2, \t\x92\xe6]\xfbZ\
|
\xa5]\xf0"\xec(.J\xe6dd)\xf7\x13\x80\xadoD-12\xc8\\\xd3\r\xe2\xa6\x00j\xd9\
|
||||||
\xf7\x08\xa0W\xc3\xea5\xdb\rl_IX\xe5\xf0d\x00\xfa\x8d#\x7f\xc4\xf7'\xab\x00\
|
\x0f\x03\xde\xbf\xc1\x0f\x00\xa7\x18\x01t\xd5\\\x05\xc8\\}T#\xe9\xfb\xbf\x90\
|
||||||
\x00\x00\x00IEND\xaeB`\x82"
|
\x064\xd8\\\x12\x1fQM\xf5\xd9\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||||
|
|
||||||
def getStopBitmap():
|
def getStopBitmap():
|
||||||
return BitmapFromImage(getStopImage())
|
return BitmapFromImage(getStopImage())
|
||||||
|
@@ -105,14 +105,16 @@ class HtmlService(CodeEditor.CodeService):
|
|||||||
class HtmlCtrl(CodeEditor.CodeCtrl):
|
class HtmlCtrl(CodeEditor.CodeCtrl):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
CodeEditor.CodeCtrl.__init__(self, parent, id, style)
|
||||||
self.SetLexer(wx.stc.STC_LEX_HTML)
|
self.SetLexer(wx.stc.STC_LEX_HTML)
|
||||||
self.SetProperty("fold.html", "1")
|
self.SetProperty("fold.html", "1")
|
||||||
|
|
||||||
|
|
||||||
def GetMatchingBraces(self):
|
def GetMatchingBraces(self):
|
||||||
return "<>[]{}()"
|
return "<>[]{}()"
|
||||||
|
|
||||||
|
|
||||||
def CanWordWrap(self):
|
def CanWordWrap(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
@@ -79,8 +79,6 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
|||||||
import PHPEditor
|
import PHPEditor
|
||||||
import wx.lib.ogl as ogl
|
import wx.lib.ogl as ogl
|
||||||
import DebuggerService
|
import DebuggerService
|
||||||
import atexit
|
|
||||||
atexit.register(DebuggerService.DebuggerService.KillAllRunningProcesses)
|
|
||||||
import AboutDialog
|
import AboutDialog
|
||||||
import SVNService
|
import SVNService
|
||||||
|
|
||||||
@@ -109,6 +107,19 @@ class IDEApplication(wx.lib.pydocview.DocApp):
|
|||||||
docManager = wx.lib.docview.DocManager(flags = self.GetDefaultDocManagerFlags())
|
docManager = wx.lib.docview.DocManager(flags = self.GetDefaultDocManagerFlags())
|
||||||
self.SetDocumentManager(docManager)
|
self.SetDocumentManager(docManager)
|
||||||
|
|
||||||
|
defaultTemplate = wx.lib.docview.DocTemplate(docManager,
|
||||||
|
_("Any"),
|
||||||
|
"*.*",
|
||||||
|
_("Any"),
|
||||||
|
_(".txt"),
|
||||||
|
_("Text Document"),
|
||||||
|
_("Text View"),
|
||||||
|
STCTextEditor.TextDocument,
|
||||||
|
STCTextEditor.TextView,
|
||||||
|
wx.lib.docview.TEMPLATE_INVISIBLE,
|
||||||
|
icon = STCTextEditor.getTextIcon())
|
||||||
|
docManager.AssociateTemplate(defaultTemplate)
|
||||||
|
|
||||||
if not ACTIVEGRID_BASE_IDE:
|
if not ACTIVEGRID_BASE_IDE:
|
||||||
dplTemplate = DeploymentService.DeploymentTemplate(docManager,
|
dplTemplate = DeploymentService.DeploymentTemplate(docManager,
|
||||||
_("Deployment"),
|
_("Deployment"),
|
||||||
|
@@ -39,15 +39,15 @@ class ImageView(wx.lib.docview.View):
|
|||||||
|
|
||||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
||||||
panel = wx.Panel(frame, -1)
|
panel = wx.Panel(frame, -1)
|
||||||
bitmap = wx.Image(doc.GetFilename()).ConvertToBitmap()
|
self._bitmap = wx.Image(doc.GetFilename()).ConvertToBitmap()
|
||||||
self._ctrl = wx.StaticBitmap(panel, -1, bitmap, (0,0), (bitmap.GetWidth(), bitmap.GetHeight()))
|
self._ctrl = wx.StaticBitmap(panel, -1, self._bitmap, (0,0), (self._bitmap.GetWidth(), self._bitmap.GetHeight()))
|
||||||
wx.EVT_LEFT_DOWN(self._ctrl, self.OnFocus)
|
wx.EVT_LEFT_DOWN(self._ctrl, self.OnFocus)
|
||||||
wx.EVT_LEFT_DCLICK(self._ctrl, self.OnFocus)
|
wx.EVT_LEFT_DCLICK(self._ctrl, self.OnFocus)
|
||||||
wx.EVT_RIGHT_DOWN(self._ctrl, self.OnFocus)
|
wx.EVT_RIGHT_DOWN(self._ctrl, self.OnFocus)
|
||||||
wx.EVT_RIGHT_DCLICK(self._ctrl, self.OnFocus)
|
wx.EVT_RIGHT_DCLICK(self._ctrl, self.OnFocus)
|
||||||
wx.EVT_MIDDLE_DOWN(self._ctrl, self.OnFocus)
|
wx.EVT_MIDDLE_DOWN(self._ctrl, self.OnFocus)
|
||||||
wx.EVT_MIDDLE_DCLICK(self._ctrl, self.OnFocus)
|
wx.EVT_MIDDLE_DCLICK(self._ctrl, self.OnFocus)
|
||||||
panel.SetClientSize(bitmap.GetSize())
|
panel.SetClientSize(self._bitmap.GetSize())
|
||||||
frame.SetClientSize(panel.GetSize())
|
frame.SetClientSize(panel.GetSize())
|
||||||
self.Activate()
|
self.Activate()
|
||||||
return True
|
return True
|
||||||
@@ -69,6 +69,13 @@ class ImageView(wx.lib.docview.View):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def OnDraw(self, dc):
|
||||||
|
""" for Print Preview and Print """
|
||||||
|
dc.BeginDrawing()
|
||||||
|
dc.DrawBitmap(self._bitmap, 10, 10, True)
|
||||||
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Icon Bitmaps - generated by encode_bitmaps.py
|
# Icon Bitmaps - generated by encode_bitmaps.py
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
@@ -151,8 +151,8 @@ class PHPService(CodeEditor.CodeService):
|
|||||||
class PHPCtrl(CodeEditor.CodeCtrl):
|
class PHPCtrl(CodeEditor.CodeCtrl):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
CodeEditor.CodeCtrl.__init__(self, parent, id, style)
|
||||||
self.SetLexer(wx.stc.STC_LEX_PHP)
|
self.SetLexer(wx.stc.STC_LEX_PHP)
|
||||||
self.SetStyleBits(7)
|
self.SetStyleBits(7)
|
||||||
self.SetKeyWords(4, string.join(PHPKEYWORDS))
|
self.SetKeyWords(4, string.join(PHPKEYWORDS))
|
||||||
|
@@ -62,8 +62,8 @@ class PerlService(CodeEditor.CodeService):
|
|||||||
class PerlCtrl(CodeEditor.CodeCtrl):
|
class PerlCtrl(CodeEditor.CodeCtrl):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
CodeEditor.CodeCtrl.__init__(self, parent, id, style)
|
||||||
self.SetLexer(wx.stc.STC_LEX_PERL)
|
self.SetLexer(wx.stc.STC_LEX_PERL)
|
||||||
self.SetKeyWords(0, string.join(PERLKEYWORDS))
|
self.SetKeyWords(0, string.join(PERLKEYWORDS))
|
||||||
|
|
||||||
|
@@ -20,7 +20,7 @@ from wxPython.lib.rcsizer import RowColSizer
|
|||||||
import time
|
import time
|
||||||
import Service
|
import Service
|
||||||
import sys
|
import sys
|
||||||
import activegrid.util.xmlmarshaller
|
import activegrid.util.objutils
|
||||||
import UICommon
|
import UICommon
|
||||||
import Wizard
|
import Wizard
|
||||||
import SVNService
|
import SVNService
|
||||||
@@ -47,18 +47,12 @@ HALF_SPACE = 5
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# XML Marshalling Methods
|
# XML Marshalling Methods
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
LOCAL_TYPE_MAPPING = { "projectmodel" : "activegrid.tool.ProjectEditor.ProjectModel", }
|
|
||||||
|
|
||||||
|
|
||||||
def load(fileObject):
|
def load(fileObject):
|
||||||
xml = fileObject.read()
|
return activegrid.util.objutils.defaultLoad(fileObject)
|
||||||
projectModel = activegrid.util.xmlmarshaller.unmarshal(xml, knownTypes=LOCAL_TYPE_MAPPING)
|
|
||||||
return projectModel
|
|
||||||
|
|
||||||
|
|
||||||
def save(fileObject, projectModel):
|
def save(fileObject, projectModel):
|
||||||
xml = activegrid.util.xmlmarshaller.marshal(projectModel, prettyPrint=True, knownTypes=LOCAL_TYPE_MAPPING)
|
activegrid.util.objutils.defaultSave(fileObject, projectModel, prettyPrint=True)
|
||||||
fileObject.write(xml)
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
@@ -72,6 +66,9 @@ class ProjectModel:
|
|||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._files = []
|
self._files = []
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProjectDocument(wx.lib.docview.Document):
|
class ProjectDocument(wx.lib.docview.Document):
|
||||||
@@ -143,8 +140,6 @@ class ProjectDocument(wx.lib.docview.Document):
|
|||||||
if path.startswith("."): # relative to project file
|
if path.startswith("."): # relative to project file
|
||||||
curPath = os.path.dirname(self.GetFilename())
|
curPath = os.path.dirname(self.GetFilename())
|
||||||
path = os.path.normpath(os.path.join(curPath, path))
|
path = os.path.normpath(os.path.join(curPath, path))
|
||||||
elif not ACTIVEGRID_BASE_IDE:
|
|
||||||
print "Warning: absolute path '%s' found in project file, this may affect deployment" % path
|
|
||||||
newFilePaths.append(path)
|
newFilePaths.append(path)
|
||||||
return newFilePaths
|
return newFilePaths
|
||||||
|
|
||||||
@@ -229,7 +224,7 @@ class ProjectDocument(wx.lib.docview.Document):
|
|||||||
if isProject:
|
if isProject:
|
||||||
documents = self.GetDocumentManager().GetDocuments()
|
documents = self.GetDocumentManager().GetDocuments()
|
||||||
for document in documents:
|
for document in documents:
|
||||||
if document.GetFilename() == oldFile: # If the renamed document is open, update it
|
if os.path.normcase(document.GetFilename()) == os.path.normcase(oldFile): # If the renamed document is open, update it
|
||||||
document.SetFilename(newFile)
|
document.SetFilename(newFile)
|
||||||
document.SetTitle(wx.lib.docview.FileNameFromPath(newFile))
|
document.SetTitle(wx.lib.docview.FileNameFromPath(newFile))
|
||||||
document.UpdateAllViews(hint = ("rename", document, newFile))
|
document.UpdateAllViews(hint = ("rename", document, newFile))
|
||||||
@@ -238,7 +233,7 @@ class ProjectDocument(wx.lib.docview.Document):
|
|||||||
self.AddFile(newFile)
|
self.AddFile(newFile)
|
||||||
documents = self.GetDocumentManager().GetDocuments()
|
documents = self.GetDocumentManager().GetDocuments()
|
||||||
for document in documents:
|
for document in documents:
|
||||||
if document.GetFilename() == oldFile: # If the renamed document is open, update it
|
if os.path.normcase(document.GetFilename()) == os.path.normcase(oldFile): # If the renamed document is open, update it
|
||||||
document.SetFilename(newFile, notifyViews = True)
|
document.SetFilename(newFile, notifyViews = True)
|
||||||
document.UpdateAllViews(hint = ("rename", document, newFile))
|
document.UpdateAllViews(hint = ("rename", document, newFile))
|
||||||
return True
|
return True
|
||||||
@@ -293,7 +288,7 @@ class NewProjectWizard(Wizard.BaseWizard):
|
|||||||
# What if the document is already open and we're overwriting it?
|
# What if the document is already open and we're overwriting it?
|
||||||
documents = docManager.GetDocuments()
|
documents = docManager.GetDocuments()
|
||||||
for document in documents:
|
for document in documents:
|
||||||
if document.GetFilename() == self._fullProjectPath: # If the renamed document is open, update it
|
if os.path.normcase(document.GetFilename()) == os.path.normcase(self._fullProjectPath): # If the renamed document is open, update it
|
||||||
document.DeleteAllViews()
|
document.DeleteAllViews()
|
||||||
break
|
break
|
||||||
os.remove(self._fullProjectPath)
|
os.remove(self._fullProjectPath)
|
||||||
@@ -848,10 +843,12 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
or id == ProjectService.RENAME_ID
|
or id == ProjectService.RENAME_ID
|
||||||
or id == ProjectService.ADD_FILES_TO_PROJECT_ID
|
or id == ProjectService.ADD_FILES_TO_PROJECT_ID
|
||||||
or id == ProjectService.ADD_ALL_FILES_TO_PROJECT_ID
|
or id == ProjectService.ADD_ALL_FILES_TO_PROJECT_ID
|
||||||
or id == wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID
|
or id == wx.lib.pydocview.FilePropertiesService.PROPERTIES_ID):
|
||||||
or id == ProjectService.DELETE_FILE_ID):
|
|
||||||
event.Enable(self._HasSelection())
|
event.Enable(self._HasSelection())
|
||||||
return True
|
return True
|
||||||
|
elif id == ProjectService.DELETE_FILE_ID:
|
||||||
|
event.Enable(len(self.GetSelectedFiles()) > 0)
|
||||||
|
return True
|
||||||
elif id == ProjectService.ADD_CURRENT_FILE_TO_PROJECT_ID:
|
elif id == ProjectService.ADD_CURRENT_FILE_TO_PROJECT_ID:
|
||||||
event.Enable(False)
|
event.Enable(False)
|
||||||
return True
|
return True
|
||||||
@@ -866,6 +863,10 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
or id == ProjectService.OPEN_SELECTION_ID):
|
or id == ProjectService.OPEN_SELECTION_ID):
|
||||||
event.Enable(self._HasFilesSelected())
|
event.Enable(self._HasFilesSelected())
|
||||||
return True
|
return True
|
||||||
|
elif (id == wx.ID_PREVIEW
|
||||||
|
or id == wx.ID_PRINT):
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@@ -924,6 +925,16 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
return filenames
|
return filenames
|
||||||
|
|
||||||
|
|
||||||
|
def GetSelectedProjects(self):
|
||||||
|
filenames = []
|
||||||
|
for item in self._treeCtrl.GetSelections():
|
||||||
|
if self._IsItemProject(item):
|
||||||
|
filename = self._treeCtrl.GetLongFilename(item)
|
||||||
|
if filename and filename not in filenames:
|
||||||
|
filenames.append(filename)
|
||||||
|
return filenames
|
||||||
|
|
||||||
|
|
||||||
def AddProjectToView(self, document):
|
def AddProjectToView(self, document):
|
||||||
rootItem = self._treeCtrl.GetRootItem()
|
rootItem = self._treeCtrl.GetRootItem()
|
||||||
projectItem = self._treeCtrl.AppendItem(rootItem, self._MakeProjectName(document))
|
projectItem = self._treeCtrl.AppendItem(rootItem, self._MakeProjectName(document))
|
||||||
@@ -981,8 +992,7 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
allfilter = allfilter + _(';')
|
allfilter = allfilter + _(';')
|
||||||
descr = descr + temp.GetDescription() + _(" (") + temp.GetFileFilter() + _(") |") + temp.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
descr = descr + temp.GetDescription() + _(" (") + temp.GetFileFilter() + _(") |") + temp.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
||||||
allfilter = allfilter + temp.GetFileFilter()
|
allfilter = allfilter + temp.GetFileFilter()
|
||||||
descr = _("All") + _(" (") + allfilter + _(") |") + allfilter + _('|') + descr # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
descr = _("All (%s)|%s|%s|Any (*.*) | *.*") % (allfilter, allfilter, descr) # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
||||||
descr = descr + _("|") + _("Any (*.*) | *.*")
|
|
||||||
else:
|
else:
|
||||||
descr = _("*.*")
|
descr = _("*.*")
|
||||||
|
|
||||||
@@ -1203,8 +1213,10 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
itemIDs = [wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS, None]
|
itemIDs = [wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS, None]
|
||||||
menuBar = self._GetParentFrame().GetMenuBar()
|
menuBar = self._GetParentFrame().GetMenuBar()
|
||||||
itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT]
|
itemIDs = itemIDs + [ProjectService.ADD_FILES_TO_PROJECT_ID, ProjectService.ADD_ALL_FILES_TO_PROJECT_ID, ProjectService.REMOVE_FROM_PROJECT]
|
||||||
|
svnIDs = [SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
|
||||||
if SVN_INSTALLED:
|
if SVN_INSTALLED:
|
||||||
itemIDs = itemIDs + [None, SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
|
itemIDs = itemIDs + [None, SVNService.SVNService.SVN_UPDATE_ID, SVNService.SVNService.SVN_CHECKIN_ID, SVNService.SVNService.SVN_REVERT_ID]
|
||||||
|
globalIDs = [wx.ID_UNDO, wx.ID_REDO, wx.ID_CLOSE, wx.ID_SAVE, wx.ID_SAVEAS]
|
||||||
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]
|
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:
|
for itemID in itemIDs:
|
||||||
if not itemID:
|
if not itemID:
|
||||||
@@ -1218,8 +1230,16 @@ class ProjectView(wx.lib.docview.View):
|
|||||||
wx.EVT_MENU(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self.OnClear)
|
wx.EVT_MENU(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self.OnClear)
|
||||||
wx.EVT_UPDATE_UI(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self._GetParentFrame().ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(self._GetParentFrame(), ProjectService.REMOVE_FROM_PROJECT, self._GetParentFrame().ProcessUpdateUIEvent)
|
||||||
else:
|
else:
|
||||||
|
svnService = wx.GetApp().GetService(SVNService.SVNService)
|
||||||
item = menuBar.FindItemById(itemID)
|
item = menuBar.FindItemById(itemID)
|
||||||
if item:
|
if item:
|
||||||
|
if itemID in svnIDs:
|
||||||
|
if SVN_INSTALLED and svnService:
|
||||||
|
wx.EVT_MENU(self._GetParentFrame(), itemID, svnService.ProcessEvent)
|
||||||
|
elif itemID in globalIDs:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
wx.EVT_MENU(self._treeCtrl, itemID, self.ProcessEvent)
|
||||||
menu.Append(itemID, item.GetLabel())
|
menu.Append(itemID, item.GetLabel())
|
||||||
self._treeCtrl.PopupMenu(menu, wx.Point(event.GetX(), event.GetY()))
|
self._treeCtrl.PopupMenu(menu, wx.Point(event.GetX(), event.GetY()))
|
||||||
menu.Destroy()
|
menu.Destroy()
|
||||||
@@ -1824,9 +1844,43 @@ class ProjectService(Service.Service):
|
|||||||
|
|
||||||
def ProcessEventBeforeWindows(self, event):
|
def ProcessEventBeforeWindows(self, event):
|
||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
|
|
||||||
if id == wx.ID_CLOSE_ALL:
|
if id == wx.ID_CLOSE_ALL:
|
||||||
self.OnFileCloseAll(event)
|
self.OnFileCloseAll(event)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
elif id == wx.ID_CLOSE:
|
||||||
|
document = self.GetDocumentManager().GetCurrentDocument()
|
||||||
|
if document and document.GetDocumentTemplate().GetDocumentType() == ProjectDocument:
|
||||||
|
self.OnProjectClose(event)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def ProcessUpdateUIEventBeforeWindows(self, event):
|
||||||
|
id = event.GetId()
|
||||||
|
|
||||||
|
if id == wx.ID_CLOSE_ALL:
|
||||||
|
for document in self.GetDocumentManager().GetDocuments():
|
||||||
|
if document.GetDocumentTemplate().GetDocumentType() != ProjectDocument:
|
||||||
|
event.Enable(True)
|
||||||
|
return True
|
||||||
|
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
elif id == wx.ID_CLOSE:
|
||||||
|
document = self.GetDocumentManager().GetCurrentDocument()
|
||||||
|
if document and document.GetDocumentTemplate().GetDocumentType() == ProjectDocument:
|
||||||
|
projectFilenames = self.GetView().GetSelectedProjects()
|
||||||
|
if projectFilenames and len(projectFilenames):
|
||||||
|
event.Enable(True)
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
@@ -2055,6 +2109,14 @@ class ProjectService(Service.Service):
|
|||||||
self.GetView().Activate(True) # after add, should put focus on project editor
|
self.GetView().Activate(True) # after add, should put focus on project editor
|
||||||
|
|
||||||
|
|
||||||
|
def OnProjectClose(self, event):
|
||||||
|
projectFilenames = self.GetView().GetSelectedProjects()
|
||||||
|
for filename in projectFilenames:
|
||||||
|
doc = self.FindProjectByFile(filename)
|
||||||
|
if doc:
|
||||||
|
self.GetDocumentManager().CloseDocument(doc, False)
|
||||||
|
|
||||||
|
|
||||||
def OnFileCloseAll(self, event):
|
def OnFileCloseAll(self, event):
|
||||||
for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
|
for document in self.GetDocumentManager().GetDocuments()[:]: # Cloning list to make sure we go through all docs even as they are deleted
|
||||||
if document.GetDocumentTemplate().GetDocumentType() != ProjectDocument:
|
if document.GetDocumentTemplate().GetDocumentType() != ProjectDocument:
|
||||||
|
@@ -49,6 +49,11 @@ class PythonDocument(CodeEditor.CodeDocument):
|
|||||||
class PythonView(CodeEditor.CodeView):
|
class PythonView(CodeEditor.CodeView):
|
||||||
|
|
||||||
|
|
||||||
|
def GetCtrlClass(self):
|
||||||
|
""" Used in split window to instantiate new instances """
|
||||||
|
return PythonCtrl
|
||||||
|
|
||||||
|
|
||||||
def ProcessUpdateUIEvent(self, event):
|
def ProcessUpdateUIEvent(self, event):
|
||||||
if not self.GetCtrl():
|
if not self.GetCtrl():
|
||||||
return False
|
return False
|
||||||
@@ -62,11 +67,6 @@ class PythonView(CodeEditor.CodeView):
|
|||||||
return CodeEditor.CodeView.ProcessUpdateUIEvent(self, event)
|
return CodeEditor.CodeView.ProcessUpdateUIEvent(self, event)
|
||||||
|
|
||||||
|
|
||||||
def GetCtrlClass(self):
|
|
||||||
""" Used in split window to instantiate new instances """
|
|
||||||
return PythonCtrl
|
|
||||||
|
|
||||||
|
|
||||||
def OnActivateView(self, activate, activeView, deactiveView):
|
def OnActivateView(self, activate, activeView, deactiveView):
|
||||||
STCTextEditor.TextView.OnActivateView(self, activate, activeView, deactiveView)
|
STCTextEditor.TextView.OnActivateView(self, activate, activeView, deactiveView)
|
||||||
if activate:
|
if activate:
|
||||||
@@ -345,8 +345,8 @@ class PythonService(CodeEditor.CodeService):
|
|||||||
class PythonCtrl(CodeEditor.CodeCtrl):
|
class PythonCtrl(CodeEditor.CodeCtrl):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
CodeEditor.CodeCtrl.__init__(self, parent, id, style)
|
||||||
self.SetProperty("tab.timmy.whinge.level", "1")
|
self.SetProperty("tab.timmy.whinge.level", "1")
|
||||||
self.SetProperty("fold.comment.python", "1")
|
self.SetProperty("fold.comment.python", "1")
|
||||||
self.SetProperty("fold.quotes.python", "1")
|
self.SetProperty("fold.quotes.python", "1")
|
||||||
@@ -516,6 +516,7 @@ class PythonCtrl(CodeEditor.CodeCtrl):
|
|||||||
if doExtraIndent or len(textNoTrailingSpaces) and textNoTrailingSpaces[-1] == ':':
|
if doExtraIndent or len(textNoTrailingSpaces) and textNoTrailingSpaces[-1] == ':':
|
||||||
spaces = spaces + ' ' * self.GetIndent()
|
spaces = spaces + ' ' * self.GetIndent()
|
||||||
self.AddText('\n' + spaces)
|
self.AddText('\n' + spaces)
|
||||||
|
self.EnsureCaretVisible()
|
||||||
|
|
||||||
|
|
||||||
# Callback for tokenizer in self.DoIndent
|
# Callback for tokenizer in self.DoIndent
|
||||||
|
@@ -47,27 +47,16 @@ TEXT_STATUS_BAR_ID = wx.NewId()
|
|||||||
class TextDocument(wx.lib.docview.Document):
|
class TextDocument(wx.lib.docview.Document):
|
||||||
|
|
||||||
|
|
||||||
def OnSaveDocument(self, filename):
|
def SaveObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
docFile = file(self._documentFile, "w")
|
fileObject.write(view.GetValue())
|
||||||
docFile.write(view.GetValue())
|
|
||||||
docFile.close()
|
|
||||||
self.Modify(False)
|
|
||||||
self.SetDocumentModificationDate()
|
|
||||||
self.SetDocumentSaved(True)
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def LoadObject(self, fileObject):
|
||||||
def OnOpenDocument(self, filename):
|
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
docFile = file(self._documentFile, 'r')
|
data = fileObject.read()
|
||||||
data = docFile.read()
|
|
||||||
view.SetValue(data)
|
view.SetValue(data)
|
||||||
self.SetFilename(filename, True)
|
|
||||||
self.Modify(False)
|
|
||||||
self.SetDocumentModificationDate()
|
|
||||||
self.UpdateAllViews()
|
|
||||||
self._savedYet = True
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -90,12 +79,6 @@ class TextDocument(wx.lib.docview.Document):
|
|||||||
# Don't create a command processor, it has its own
|
# Don't create a command processor, it has its own
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Use this to override MultiClient.Select to prevent yellow background.
|
|
||||||
def MultiClientSelectBGNotYellow(a):
|
|
||||||
a.GetParent().multiView.UnSelect()
|
|
||||||
a.selected = True
|
|
||||||
#a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
|
|
||||||
a.Refresh()
|
|
||||||
|
|
||||||
class TextView(wx.lib.docview.View):
|
class TextView(wx.lib.docview.View):
|
||||||
MARKER_NUM = 0
|
MARKER_NUM = 0
|
||||||
@@ -110,39 +93,32 @@ class TextView(wx.lib.docview.View):
|
|||||||
self._textEditor = None
|
self._textEditor = None
|
||||||
self._markerCount = 0
|
self._markerCount = 0
|
||||||
self._commandProcessor = None
|
self._commandProcessor = None
|
||||||
self._multiSash = None
|
self._dynSash = None
|
||||||
|
|
||||||
|
|
||||||
def GetCtrlClass(self):
|
def GetCtrlClass(self):
|
||||||
|
""" Used in split window to instantiate new instances """
|
||||||
return TextCtrl
|
return TextCtrl
|
||||||
|
|
||||||
|
|
||||||
def GetCtrl(self):
|
|
||||||
# look for active one first
|
|
||||||
self._textEditor = self._GetActiveCtrl(self._multiSash)
|
|
||||||
if self._textEditor == None: # it is possible none are active
|
|
||||||
# look for any existing one
|
|
||||||
self._textEditor = self._FindCtrl(self._multiSash)
|
|
||||||
return self._textEditor
|
|
||||||
|
|
||||||
|
|
||||||
## def GetCtrls(self, parent = None):
|
def GetCtrl(self):
|
||||||
## """ Walk through the MultiSash windows and find all Ctrls """
|
return self._textEditor
|
||||||
## controls = []
|
|
||||||
## if isinstance(parent, self.GetCtrlClass()):
|
|
||||||
## return [parent]
|
def SetCtrl(self, ctrl):
|
||||||
## if hasattr(parent, "GetChildren"):
|
self._textEditor = ctrl
|
||||||
## for child in parent.GetChildren():
|
|
||||||
## controls = controls + self.GetCtrls(child)
|
|
||||||
## return controls
|
def OnCreatePrintout(self):
|
||||||
|
""" for Print Preview and Print """
|
||||||
|
return TextPrintout(self, self.GetDocument().GetPrintableName())
|
||||||
|
|
||||||
|
|
||||||
def OnCreate(self, doc, flags):
|
def OnCreate(self, doc, flags):
|
||||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags, style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
|
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags, style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
|
||||||
wx.lib.multisash.MultiClient.Select = MultiClientSelectBGNotYellow
|
self._dynSash = wx.gizmos.DynamicSashWindow(frame, -1, style=wx.CLIP_CHILDREN)
|
||||||
self._multiSash = wx.lib.multisash.MultiSash(frame, -1)
|
self._dynSash._view = self
|
||||||
self._multiSash.SetDefaultChildClass(self.GetCtrlClass()) # wxBug: MultiSash instantiates the first TextCtrl with this call
|
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
||||||
self._textEditor = self.GetCtrl() # wxBug: grab the TextCtrl from the MultiSash datastructure
|
|
||||||
self._CreateSizer(frame)
|
self._CreateSizer(frame)
|
||||||
self.Activate()
|
self.Activate()
|
||||||
frame.Show(True)
|
frame.Show(True)
|
||||||
@@ -150,33 +126,9 @@ class TextView(wx.lib.docview.View):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def _GetActiveCtrl(self, parent):
|
|
||||||
""" Walk through the MultiSash windows and find the active Control """
|
|
||||||
if isinstance(parent, wx.lib.multisash.MultiClient) and parent.selected:
|
|
||||||
return parent.child
|
|
||||||
if hasattr(parent, "GetChildren"):
|
|
||||||
for child in parent.GetChildren():
|
|
||||||
found = self._GetActiveCtrl(child)
|
|
||||||
if found:
|
|
||||||
return found
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def _FindCtrl(self, parent):
|
|
||||||
""" Walk through the MultiSash windows and find the first TextCtrl """
|
|
||||||
if isinstance(parent, self.GetCtrlClass()):
|
|
||||||
return parent
|
|
||||||
if hasattr(parent, "GetChildren"):
|
|
||||||
for child in parent.GetChildren():
|
|
||||||
found = self._FindCtrl(child)
|
|
||||||
if found:
|
|
||||||
return found
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def _CreateSizer(self, frame):
|
def _CreateSizer(self, frame):
|
||||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizer.Add(self._multiSash, 1, wx.EXPAND)
|
sizer.Add(self._dynSash, 1, wx.EXPAND)
|
||||||
frame.SetSizer(sizer)
|
frame.SetSizer(sizer)
|
||||||
frame.SetAutoLayout(True)
|
frame.SetAutoLayout(True)
|
||||||
|
|
||||||
@@ -300,12 +252,12 @@ class TextView(wx.lib.docview.View):
|
|||||||
|
|
||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
if id == wx.ID_UNDO:
|
if id == wx.ID_UNDO:
|
||||||
event.Enable(self.GetCtrl().CanUndo())
|
event.Enable(self.GetCtrl().CanUndo())
|
||||||
event.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
|
event.SetText(_("&Undo\tCtrl+Z")) # replace menu string
|
||||||
return True
|
return True
|
||||||
elif id == wx.ID_REDO:
|
elif id == wx.ID_REDO:
|
||||||
event.Enable(self.GetCtrl().CanRedo())
|
event.Enable(self.GetCtrl().CanRedo())
|
||||||
event.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
|
event.SetText(_("&Redo\tCtrl+Y")) # replace menu string
|
||||||
return True
|
return True
|
||||||
elif (id == wx.ID_CUT
|
elif (id == wx.ID_CUT
|
||||||
or id == wx.ID_COPY
|
or id == wx.ID_COPY
|
||||||
@@ -586,6 +538,7 @@ class TextView(wx.lib.docview.View):
|
|||||||
def GetLine(self, lineNum):
|
def GetLine(self, lineNum):
|
||||||
return self.GetCtrl().GetLine(lineNum-1) # line numbering for editor is 0 based, we are 1 based.
|
return self.GetCtrl().GetLine(lineNum-1) # line numbering for editor is 0 based, we are 1 based.
|
||||||
|
|
||||||
|
|
||||||
def MarkerDefine(self):
|
def MarkerDefine(self):
|
||||||
""" This must be called after the texteditor is instantiated """
|
""" This must be called after the texteditor is instantiated """
|
||||||
self.GetCtrl().MarkerDefine(TextView.MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, wx.BLUE)
|
self.GetCtrl().MarkerDefine(TextView.MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, wx.BLUE)
|
||||||
@@ -601,6 +554,7 @@ class TextView(wx.lib.docview.View):
|
|||||||
self.GetCtrl().MarkerAdd(lineNum, marker_index)
|
self.GetCtrl().MarkerAdd(lineNum, marker_index)
|
||||||
self._markerCount += 1
|
self._markerCount += 1
|
||||||
|
|
||||||
|
|
||||||
def MarkerAdd(self, lineNum = -1, marker_index=MARKER_NUM, mask=MARKER_MASK):
|
def MarkerAdd(self, lineNum = -1, marker_index=MARKER_NUM, mask=MARKER_MASK):
|
||||||
if lineNum == -1:
|
if lineNum == -1:
|
||||||
lineNum = self.GetCtrl().GetCurrentLine()
|
lineNum = self.GetCtrl().GetCurrentLine()
|
||||||
@@ -959,10 +913,14 @@ class TextOptionsPanel(wx.Panel):
|
|||||||
|
|
||||||
class TextCtrl(wx.stc.StyledTextCtrl):
|
class TextCtrl(wx.stc.StyledTextCtrl):
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
if ID == -1:
|
wx.stc.StyledTextCtrl.__init__(self, parent, id, style=style)
|
||||||
ID = wx.NewId()
|
|
||||||
wx.stc.StyledTextCtrl.__init__(self, parent, ID, style = style)
|
if isinstance(parent, wx.gizmos.DynamicSashWindow):
|
||||||
|
self._dynSash = parent
|
||||||
|
self.SetupDSScrollBars()
|
||||||
|
self.Bind(wx.gizmos.EVT_DYNAMIC_SASH_SPLIT, self.OnDSSplit)
|
||||||
|
self.Bind(wx.gizmos.EVT_DYNAMIC_SASH_UNIFY, self.OnDSUnify)
|
||||||
|
|
||||||
self._font = None
|
self._font = None
|
||||||
self._fontColor = None
|
self._fontColor = None
|
||||||
@@ -975,6 +933,8 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
self.CmdKeyAssign(wx.stc.STC_KEY_NEXT, wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
|
self.CmdKeyAssign(wx.stc.STC_KEY_NEXT, wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
|
||||||
self.Bind(wx.stc.EVT_STC_ZOOM, self.OnUpdateLineNumberMarginWidth) # auto update line num width on zoom
|
self.Bind(wx.stc.EVT_STC_ZOOM, self.OnUpdateLineNumberMarginWidth) # auto update line num width on zoom
|
||||||
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
|
wx.EVT_KEY_DOWN(self, self.OnKeyPressed)
|
||||||
|
wx.EVT_KILL_FOCUS(self, self.OnKillFocus)
|
||||||
|
wx.EVT_SET_FOCUS(self, self.OnFocus)
|
||||||
self.SetMargins(0,0)
|
self.SetMargins(0,0)
|
||||||
|
|
||||||
self.SetUseTabs(0)
|
self.SetUseTabs(0)
|
||||||
@@ -998,21 +958,23 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
self.SetFontColor(color)
|
self.SetFontColor(color)
|
||||||
self.MarkerDefineDefault()
|
self.MarkerDefineDefault()
|
||||||
|
|
||||||
# for multisash initialization
|
|
||||||
if isinstance(parent, wx.lib.multisash.MultiClient):
|
def OnFocus(self, event):
|
||||||
while parent.GetParent():
|
self.SetSelBackground(1, "BLUE")
|
||||||
parent = parent.GetParent()
|
self.SetSelForeground(1, "WHITE")
|
||||||
if hasattr(parent, "GetView"):
|
if hasattr(self, "_dynSash"):
|
||||||
break
|
self._dynSash._view.SetCtrl(self)
|
||||||
if hasattr(parent, "GetView"):
|
event.Skip()
|
||||||
textEditor = parent.GetView()._textEditor
|
|
||||||
if textEditor:
|
|
||||||
doc = textEditor.GetDocPointer()
|
|
||||||
if doc:
|
|
||||||
self.SetDocPointer(doc)
|
|
||||||
|
|
||||||
|
|
||||||
|
def OnKillFocus(self, event):
|
||||||
|
self.SetSelBackground(0, "BLUE")
|
||||||
|
self.SetSelForeground(0, "WHITE")
|
||||||
|
self.SetSelBackground(1, "#C0C0C0")
|
||||||
|
# Don't set foreground color, use syntax highlighted default colors.
|
||||||
|
event.Skip()
|
||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self, configPrefix = "Text", hasWordWrap = True, hasTabs = False):
|
def SetViewDefaults(self, configPrefix = "Text", hasWordWrap = True, hasTabs = False):
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
|
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
|
||||||
@@ -1031,7 +993,6 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
self.SetIndent(4)
|
self.SetIndent(4)
|
||||||
self.SetTabWidth(4)
|
self.SetTabWidth(4)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def GetDefaultFont(self):
|
def GetDefaultFont(self):
|
||||||
""" Subclasses should override this """
|
""" Subclasses should override this """
|
||||||
@@ -1064,6 +1025,7 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
def GetFont(self):
|
def GetFont(self):
|
||||||
return self._font
|
return self._font
|
||||||
|
|
||||||
|
|
||||||
def SetFont(self, font):
|
def SetFont(self, font):
|
||||||
self._font = font
|
self._font = font
|
||||||
self.StyleSetFont(wx.stc.STC_STYLE_DEFAULT, self._font)
|
self.StyleSetFont(wx.stc.STC_STYLE_DEFAULT, self._font)
|
||||||
@@ -1202,6 +1164,160 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
else:
|
else:
|
||||||
self.SetWrapMode(wx.stc.STC_WRAP_NONE)
|
self.SetWrapMode(wx.stc.STC_WRAP_NONE)
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# DynamicSashWindow methods
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def SetupDSScrollBars(self):
|
||||||
|
# hook the scrollbars provided by the wxDynamicSashWindow
|
||||||
|
# to this view
|
||||||
|
v_bar = self._dynSash.GetVScrollBar(self)
|
||||||
|
h_bar = self._dynSash.GetHScrollBar(self)
|
||||||
|
v_bar.Bind(wx.EVT_SCROLL, self.OnDSSBScroll)
|
||||||
|
h_bar.Bind(wx.EVT_SCROLL, self.OnDSSBScroll)
|
||||||
|
v_bar.Bind(wx.EVT_SET_FOCUS, self.OnDSSBFocus)
|
||||||
|
h_bar.Bind(wx.EVT_SET_FOCUS, self.OnDSSBFocus)
|
||||||
|
|
||||||
|
# And set the wxStyledText to use these scrollbars instead
|
||||||
|
# of its built-in ones.
|
||||||
|
self.SetVScrollBar(v_bar)
|
||||||
|
self.SetHScrollBar(h_bar)
|
||||||
|
|
||||||
|
|
||||||
|
def OnDSSplit(self, evt):
|
||||||
|
newCtrl = self._dynSash._view.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
||||||
|
newCtrl.SetDocPointer(self.GetDocPointer()) # use the same document
|
||||||
|
self.SetupDSScrollBars()
|
||||||
|
if self == self._dynSash._view.GetCtrl(): # originally had focus
|
||||||
|
wx.CallAfter(self.SetFocus) # do this to set colors correctly. wxBug: for some reason, if we don't do a CallAfter, it immediately calls OnKillFocus right after our SetFocus.
|
||||||
|
|
||||||
|
|
||||||
|
def OnDSUnify(self, evt):
|
||||||
|
self.SetupDSScrollBars()
|
||||||
|
self.SetFocus() # do this to set colors correctly
|
||||||
|
|
||||||
|
|
||||||
|
def OnDSSBScroll(self, evt):
|
||||||
|
# redirect the scroll events from the _dynSash's scrollbars to the STC
|
||||||
|
self.GetEventHandler().ProcessEvent(evt)
|
||||||
|
|
||||||
|
|
||||||
|
def OnDSSBFocus(self, evt):
|
||||||
|
# when the scrollbar gets the focus move it back to the STC
|
||||||
|
self.SetFocus()
|
||||||
|
|
||||||
|
|
||||||
|
def DSProcessEvent(self, event):
|
||||||
|
# wxHack: Needed for customized right mouse click menu items.
|
||||||
|
if hasattr(self, "_dynSash"):
|
||||||
|
if event.GetId() == wx.ID_SELECTALL:
|
||||||
|
# force focus so that select all occurs in the window user right clicked on.
|
||||||
|
self.SetFocus()
|
||||||
|
|
||||||
|
return self._dynSash._view.ProcessEvent(event)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def DSProcessUpdateUIEvent(self, event):
|
||||||
|
# wxHack: Needed for customized right mouse click menu items.
|
||||||
|
if hasattr(self, "_dynSash"):
|
||||||
|
id = event.GetId()
|
||||||
|
if (id == wx.ID_SELECTALL # allow select all even in non-active window, then force focus to it, see above ProcessEvent
|
||||||
|
or id == wx.ID_UNDO
|
||||||
|
or id == wx.ID_REDO):
|
||||||
|
pass # allow these actions even in non-active window
|
||||||
|
else: # disallow events in non-active windows. Cut/Copy/Paste/Delete is too confusing user experience.
|
||||||
|
if self._dynSash._view.GetCtrl() != self:
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
|
||||||
|
return self._dynSash._view.ProcessUpdateUIEvent(event)
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
class TextPrintout(wx.lib.docview.DocPrintout):
|
||||||
|
""" for Print Preview and Print """
|
||||||
|
|
||||||
|
|
||||||
|
def OnPreparePrinting(self):
|
||||||
|
""" initialization """
|
||||||
|
dc = self.GetDC()
|
||||||
|
|
||||||
|
ppiScreenX, ppiScreenY = self.GetPPIScreen()
|
||||||
|
ppiPrinterX, ppiPrinterY = self.GetPPIPrinter()
|
||||||
|
scaleX = float(ppiPrinterX)/ppiScreenX
|
||||||
|
scaleY = float(ppiPrinterY)/ppiScreenY
|
||||||
|
|
||||||
|
pageWidth, pageHeight = self.GetPageSizePixels()
|
||||||
|
self._scaleFactorX = scaleX/pageWidth
|
||||||
|
self._scaleFactorY = scaleY/pageHeight
|
||||||
|
|
||||||
|
w, h = dc.GetSize()
|
||||||
|
overallScaleX = self._scaleFactorX * w
|
||||||
|
overallScaleY = self._scaleFactorY * h
|
||||||
|
|
||||||
|
txtCtrl = self._printoutView.GetCtrl()
|
||||||
|
font, color = txtCtrl.GetFontAndColorFromConfig()
|
||||||
|
|
||||||
|
self._margin = 40
|
||||||
|
self._fontHeight = font.GetPointSize() + 1
|
||||||
|
self._pageLines = int((h/overallScaleY - (2 * self._margin))/self._fontHeight)
|
||||||
|
self._maxLines = txtCtrl.GetLineCount()
|
||||||
|
self._numPages, remainder = divmod(self._maxLines, self._pageLines)
|
||||||
|
if remainder != 0:
|
||||||
|
self._numPages += 1
|
||||||
|
|
||||||
|
spaces = 1
|
||||||
|
lineNum = self._maxLines
|
||||||
|
while lineNum >= 10:
|
||||||
|
lineNum = lineNum/10
|
||||||
|
spaces += 1
|
||||||
|
self._printFormat = "%%0%sd: %%s" % spaces
|
||||||
|
|
||||||
|
|
||||||
|
def OnPrintPage(self, page):
|
||||||
|
""" Prints the given page of the view """
|
||||||
|
dc = self.GetDC()
|
||||||
|
|
||||||
|
txtCtrl = self._printoutView.GetCtrl()
|
||||||
|
font, color = txtCtrl.GetFontAndColorFromConfig()
|
||||||
|
dc.SetFont(font)
|
||||||
|
|
||||||
|
w, h = dc.GetSize()
|
||||||
|
dc.SetUserScale(self._scaleFactorX * w, self._scaleFactorY * h)
|
||||||
|
|
||||||
|
dc.BeginDrawing()
|
||||||
|
|
||||||
|
dc.DrawText("%s - page %s" % (self.GetTitle(), page), self._margin, self._margin/2)
|
||||||
|
|
||||||
|
startY = self._margin
|
||||||
|
startLine = (page - 1) * self._pageLines
|
||||||
|
endLine = min((startLine + self._pageLines), self._maxLines)
|
||||||
|
for i in range(startLine, endLine):
|
||||||
|
text = txtCtrl.GetLine(i).rstrip()
|
||||||
|
startY += self._fontHeight
|
||||||
|
if txtCtrl.GetViewLineNumbers():
|
||||||
|
dc.DrawText(self._printFormat % (i+1, text), self._margin, startY)
|
||||||
|
else:
|
||||||
|
dc.DrawText(text, self._margin, startY)
|
||||||
|
|
||||||
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def HasPage(self, pageNum):
|
||||||
|
return pageNum <= self._numPages
|
||||||
|
|
||||||
|
|
||||||
|
def GetPageInfo(self):
|
||||||
|
minPage = 1
|
||||||
|
maxPage = self._numPages
|
||||||
|
selPageFrom = 1
|
||||||
|
selPageTo = self._numPages
|
||||||
|
return (minPage, maxPage, selPageFrom, selPageTo)
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Icon Bitmaps - generated by encode_bitmaps.py
|
# Icon Bitmaps - generated by encode_bitmaps.py
|
||||||
|
@@ -11,6 +11,7 @@
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
import wx
|
import wx
|
||||||
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import ProjectEditor
|
import ProjectEditor
|
||||||
import MessageService
|
import MessageService
|
||||||
@@ -31,7 +32,7 @@ _ = wx.GetTranslation
|
|||||||
# Constants
|
# Constants
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
SVN_CONFIG_DIR = "SVNConfigDir"
|
SVN_CONFIG_DIR = "SVNConfigDir"
|
||||||
SVN_REPOSITORY_URL = "SVNRepositoryURL"
|
SVN_REPOSITORY_URL = "SVNRepositoryURLs"
|
||||||
|
|
||||||
SPACE = 10
|
SPACE = 10
|
||||||
HALF_SPACE = 5
|
HALF_SPACE = 5
|
||||||
@@ -42,13 +43,15 @@ HALF_SPACE = 5
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
class SVNService(wx.lib.pydocview.DocService):
|
class SVNService(wx.lib.pydocview.DocService):
|
||||||
|
SVN_UPDATE_ALL_ID = wx.NewId()
|
||||||
SVN_UPDATE_ID = wx.NewId()
|
SVN_UPDATE_ID = wx.NewId()
|
||||||
SVN_CHECKIN_ID = wx.NewId()
|
SVN_CHECKIN_ID = wx.NewId()
|
||||||
|
SVN_CHECKIN_ALL_ID = wx.NewId()
|
||||||
SVN_CHECKOUT_ID = wx.NewId()
|
SVN_CHECKOUT_ID = wx.NewId()
|
||||||
SVN_REVERT_ID = wx.NewId()
|
SVN_REVERT_ID = wx.NewId()
|
||||||
SVN_ADD_ID = wx.NewId()
|
SVN_ADD_ID = wx.NewId()
|
||||||
SVN_DELETE_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]
|
SVN_COMMAND_LIST = [SVN_UPDATE_ALL_ID, SVN_CHECKIN_ALL_ID, SVN_UPDATE_ID, SVN_CHECKIN_ID, SVN_CHECKOUT_ID, SVN_REVERT_ID, SVN_ADD_ID, SVN_DELETE_ID]
|
||||||
|
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@@ -57,13 +60,14 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
global SVN_INSTALLED
|
global SVN_INSTALLED
|
||||||
if SVN_INSTALLED:
|
if SVN_INSTALLED:
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
configDir = config.Read(SVN_CONFIG_DIR, "")
|
configDir = config.Read(SVN_CONFIG_DIR, "")
|
||||||
|
|
||||||
self._client = pysvn.Client(configDir)
|
self._client = pysvn.Client(configDir)
|
||||||
try:
|
try:
|
||||||
self._defaultURL = self._client.info('.').url
|
self._defaultURL = self._client.info('.').url
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
self._client.callback_cancel = self.IfCancel
|
self._client.callback_cancel = self.IfCancel
|
||||||
self._client.callback_notify = self.UpdateStatus
|
self._client.callback_notify = self.UpdateStatus
|
||||||
self._client.callback_get_log_message = self.GetLogMessage
|
self._client.callback_get_log_message = self.GetLogMessage
|
||||||
@@ -274,6 +278,12 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
menu.AppendSeparator()
|
menu.AppendSeparator()
|
||||||
|
|
||||||
|
wx.EVT_MENU(frame, SVNService.SVN_UPDATE_ALL_ID, self.ProcessEvent)
|
||||||
|
wx.EVT_UPDATE_UI(frame, SVNService.SVN_UPDATE_ALL_ID, self.ProcessUpdateUIEvent)
|
||||||
|
menu.Append(SVNService.SVN_UPDATE_ALL_ID, _("SVN Update All in Project"), _("Update all files in a project from Subversion"))
|
||||||
|
wx.EVT_MENU(frame, SVNService.SVN_CHECKIN_ALL_ID, self.ProcessEvent)
|
||||||
|
wx.EVT_UPDATE_UI(frame, SVNService.SVN_CHECKIN_ALL_ID, self.ProcessUpdateUIEvent)
|
||||||
|
menu.Append(SVNService.SVN_CHECKIN_ALL_ID, _("SVN Commit All in Project..."), _("Commit all files changes in a project to Subversion"))
|
||||||
wx.EVT_MENU(frame, SVNService.SVN_UPDATE_ID, self.ProcessEvent)
|
wx.EVT_MENU(frame, SVNService.SVN_UPDATE_ID, self.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, SVNService.SVN_UPDATE_ID, self.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, SVNService.SVN_UPDATE_ID, self.ProcessUpdateUIEvent)
|
||||||
menu.Append(SVNService.SVN_UPDATE_ID, _("SVN Update"), _("Update file from Subversion"))
|
menu.Append(SVNService.SVN_UPDATE_ID, _("SVN Update"), _("Update file from Subversion"))
|
||||||
@@ -309,9 +319,10 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
|
|
||||||
if id == SVNService.SVN_UPDATE_ID:
|
if id == SVNService.SVN_UPDATE_ID:
|
||||||
filenames = self.GetCurrentDocuments()
|
|
||||||
|
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
|
|
||||||
|
filenames = self.GetCurrentDocuments()[:]
|
||||||
|
filenames.sort(self.BasenameCaseInsensitiveCompare)
|
||||||
|
|
||||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||||
messageService.ShowWindow()
|
messageService.ShowWindow()
|
||||||
@@ -355,9 +366,174 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
elif id == SVNService.SVN_UPDATE_ALL_ID:
|
||||||
|
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"))
|
||||||
|
|
||||||
|
projects = self.GetCurrentProjects()
|
||||||
|
for project in projects:
|
||||||
|
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||||
|
for doc in openDocs:
|
||||||
|
if doc.GetFilename() == project:
|
||||||
|
filenames = doc.GetFiles()[:] # make a copy and sort it.
|
||||||
|
filenames.sort(self.BasenameCaseInsensitiveCompare)
|
||||||
|
|
||||||
|
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.CANCEL|wx.ICON_QUESTION)
|
||||||
|
status = yesNoMsg.ShowModal()
|
||||||
|
if status == wx.ID_YES:
|
||||||
|
doc.DeleteAllViews()
|
||||||
|
elif status == wx.ID_NO:
|
||||||
|
pass
|
||||||
|
else: # elif status == wx.CANCEL:
|
||||||
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||||
|
return True
|
||||||
|
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_ALL_ID:
|
||||||
|
filenames = []
|
||||||
|
projects = self.GetCurrentProjects()
|
||||||
|
for project in projects:
|
||||||
|
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||||
|
for doc in openDocs:
|
||||||
|
if doc.GetFilename() == project:
|
||||||
|
for filename in doc.GetFiles():
|
||||||
|
if filename not in filenames:
|
||||||
|
filenames.append(filename)
|
||||||
|
filenames.sort(self.BasenameCaseInsensitiveCompare)
|
||||||
|
|
||||||
|
# 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_CHECKIN_ID:
|
elif id == SVNService.SVN_CHECKIN_ID:
|
||||||
filenames = self.GetCurrentDocuments()
|
filenames = self.GetCurrentDocuments()[:]
|
||||||
|
filenames.sort(self.BasenameCaseInsensitiveCompare)
|
||||||
|
|
||||||
# ask user if dirty files should be saved first
|
# ask user if dirty files should be saved first
|
||||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||||
@@ -459,9 +635,14 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
gridSizer = wx.FlexGridSizer(cols = 2, hgap = 5, vgap = 5)
|
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)
|
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))
|
svnUrlList = ReadSvnUrlList()
|
||||||
svnURLText.SetToolTipString(svnUrl)
|
svnURLCombobox = wx.ComboBox(dlg, -1, size=(200, -1), choices=svnUrlList, style=wx.CB_DROPDOWN)
|
||||||
gridSizer.Add(svnURLText, 0)
|
if len(svnUrlList):
|
||||||
|
svnURLCombobox.SetToolTipString(svnUrlList[0])
|
||||||
|
svnURLCombobox.SetStringSelection(svnUrlList[0])
|
||||||
|
else:
|
||||||
|
svnURLCombobox.SetToolTipString(_("Set Repository URL"))
|
||||||
|
gridSizer.Add(svnURLCombobox, 0)
|
||||||
|
|
||||||
gridSizer.Add(wx.StaticText(dlg, -1, _("Checkout to dir:")), 0, wx.ALIGN_CENTER_VERTICAL|wx.RIGHT|wx.TOP, HALF_SPACE)
|
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 = wx.TextCtrl(dlg, -1, size = (200, -1))
|
||||||
@@ -502,6 +683,8 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
if dlg.ShowModal() == wx.ID_OK:
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
|
|
||||||
|
WriteSvnUrlList(svnURLCombobox)
|
||||||
|
|
||||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||||
messageService.ShowWindow()
|
messageService.ShowWindow()
|
||||||
@@ -510,7 +693,7 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
view.ClearLines()
|
view.ClearLines()
|
||||||
view.AddLines(_("SVN Checkout:\n"))
|
view.AddLines(_("SVN Checkout:\n"))
|
||||||
|
|
||||||
svnUrl = svnURLText.GetValue()
|
svnUrl = svnURLCombobox.GetValue()
|
||||||
toLocation = localPath.GetValue()
|
toLocation = localPath.GetValue()
|
||||||
try:
|
try:
|
||||||
self._client.checkout(svnUrl, toLocation)
|
self._client.checkout(svnUrl, toLocation)
|
||||||
@@ -651,9 +834,31 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
event.Enable(True)
|
event.Enable(True)
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
elif (id == SVNService.SVN_UPDATE_ALL_ID
|
||||||
|
or id == SVNService.SVN_CHECKIN_ALL_ID):
|
||||||
|
if self.GetCurrentProjects():
|
||||||
|
event.Enable(True)
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def GetCurrentProjects(self):
|
||||||
|
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||||
|
if projectService:
|
||||||
|
projView = projectService.GetView()
|
||||||
|
|
||||||
|
if projView.HasFocus():
|
||||||
|
filenames = projView.GetSelectedProjects()
|
||||||
|
if len(filenames):
|
||||||
|
return filenames
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def GetCurrentDocuments(self):
|
def GetCurrentDocuments(self):
|
||||||
|
|
||||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||||
@@ -676,6 +881,17 @@ class SVNService(wx.lib.pydocview.DocService):
|
|||||||
return filenames
|
return filenames
|
||||||
|
|
||||||
|
|
||||||
|
def BasenameCaseInsensitiveCompare(self, s1, s2):
|
||||||
|
s1L = os.path.basename(s1).lower()
|
||||||
|
s2L = os.path.basename(s2).lower()
|
||||||
|
if s1L == s2L:
|
||||||
|
return 0
|
||||||
|
elif s1L < s2L:
|
||||||
|
return -1
|
||||||
|
else:
|
||||||
|
return 1
|
||||||
|
|
||||||
|
|
||||||
class SVNOptionsPanel(wx.Panel):
|
class SVNOptionsPanel(wx.Panel):
|
||||||
|
|
||||||
|
|
||||||
@@ -683,8 +899,6 @@ class SVNOptionsPanel(wx.Panel):
|
|||||||
wx.Panel.__init__(self, parent, id)
|
wx.Panel.__init__(self, parent, id)
|
||||||
|
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
svnService = wx.GetApp().GetService(SVNService)
|
|
||||||
svnUrl = config.Read(SVN_REPOSITORY_URL, svnService._defaultURL)
|
|
||||||
configDir = config.Read(SVN_CONFIG_DIR, "")
|
configDir = config.Read(SVN_CONFIG_DIR, "")
|
||||||
|
|
||||||
borderSizer = wx.BoxSizer(wx.VERTICAL)
|
borderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
@@ -718,10 +932,42 @@ class SVNOptionsPanel(wx.Panel):
|
|||||||
hsizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
hsizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||||
sizer.Add(hsizer, 0)
|
sizer.Add(hsizer, 0)
|
||||||
|
|
||||||
|
|
||||||
|
svnUrlList = ReadSvnUrlList()
|
||||||
sizer.Add(wx.StaticText(self, -1, _("SVN URL:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
sizer.Add(wx.StaticText(self, -1, _("SVN URL:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._svnURLText = wx.TextCtrl(self, -1, svnUrl, size = (200, -1))
|
self._svnURLCombobox = wx.ComboBox(self, -1, size=(200, -1), choices=svnUrlList, style=wx.CB_DROPDOWN)
|
||||||
self._svnURLText.SetToolTipString(svnUrl)
|
if len(svnUrlList):
|
||||||
sizer.Add(self._svnURLText, 0)
|
self._svnURLCombobox.SetToolTipString(svnUrlList[0])
|
||||||
|
self._svnURLCombobox.SetStringSelection(svnUrlList[0])
|
||||||
|
else:
|
||||||
|
self._svnURLCombobox.SetToolTipString(_("Set Repository URL"))
|
||||||
|
sizer.Add(self._svnURLCombobox, 0)
|
||||||
|
|
||||||
|
|
||||||
|
sizer.Add(wx.StaticText(self, -1, _("SVN_SSH:")), 0, wx.ALIGN_CENTER_VERTICAL)
|
||||||
|
svnSSH = os.getenv("SVN_SSH")
|
||||||
|
if not svnSSH or svnSSH == "":
|
||||||
|
self._svnSSH = wx.TextCtrl(self, -1, size = (200, -1))
|
||||||
|
else:
|
||||||
|
self._svnSSH = wx.TextCtrl(self, -1, svnSSH, size = (200, -1))
|
||||||
|
self._svnSSH.SetToolTipString(_("Override SVN_SSH environment variable temporarily."))
|
||||||
|
|
||||||
|
findSSHButton = wx.Button(self, -1, _("Browse..."))
|
||||||
|
|
||||||
|
def OnBrowseFileButton(event):
|
||||||
|
dirDlg = wx.FileDialog(self, _("Choose a file:"), style=wx.OPEN|wx.CHANGE_DIR)
|
||||||
|
if dirDlg.ShowModal() == wx.ID_OK:
|
||||||
|
self._svnSSH.SetValue(dirDlg.GetPath())
|
||||||
|
self._svnSSH.SetToolTipString(self._svnSSH.GetValue())
|
||||||
|
self._svnSSH.SetInsertionPointEnd()
|
||||||
|
dirDlg.Destroy()
|
||||||
|
wx.EVT_BUTTON(findSSHButton, -1, OnBrowseFileButton)
|
||||||
|
|
||||||
|
hsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
hsizer.Add(self._svnSSH, 1, wx.EXPAND)
|
||||||
|
hsizer.Add(findSSHButton, 0, wx.LEFT, HALF_SPACE)
|
||||||
|
sizer.Add(hsizer, 0)
|
||||||
|
|
||||||
|
|
||||||
borderSizer.Add(sizer, 0, wx.ALL, SPACE)
|
borderSizer.Add(sizer, 0, wx.ALL, SPACE)
|
||||||
self.SetSizer(borderSizer)
|
self.SetSizer(borderSizer)
|
||||||
@@ -731,6 +977,43 @@ class SVNOptionsPanel(wx.Panel):
|
|||||||
|
|
||||||
def OnOK(self, optionsDialog):
|
def OnOK(self, optionsDialog):
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
config.Write(SVN_CONFIG_DIR, self._svnConfigDir.GetValue())
|
config.Write(SVN_CONFIG_DIR, self._svnConfigDir.GetValue())
|
||||||
config.Write(SVN_REPOSITORY_URL, self._svnURLText.GetValue())
|
|
||||||
|
WriteSvnUrlList(self._svnURLCombobox)
|
||||||
|
|
||||||
|
os.environ["SVN_SSH"] = self._svnSSH.GetValue()
|
||||||
|
|
||||||
|
|
||||||
|
def ReadSvnUrlList():
|
||||||
|
""" Read in list of SNV repository URLs. First in list is the last one path used. """
|
||||||
|
config = wx.ConfigBase_Get()
|
||||||
|
urlStringList = config.Read(SVN_REPOSITORY_URL)
|
||||||
|
if len(urlStringList):
|
||||||
|
urlList = eval(urlStringList)
|
||||||
|
else:
|
||||||
|
urlList = []
|
||||||
|
if len(urlList) == 0:
|
||||||
|
svnService = wx.GetApp().GetService(SVNService)
|
||||||
|
if svnService and hasattr(svnService, "_defaultURL"):
|
||||||
|
urlList.append(svnService._defaultURL)
|
||||||
|
return urlList
|
||||||
|
|
||||||
|
|
||||||
|
def WriteSvnUrlList(comboBox):
|
||||||
|
""" Save out list of SVN repository URLs from combobox. Put on top the current selection. Only save out first 10 from the list """
|
||||||
|
urlList = []
|
||||||
|
|
||||||
|
url = comboBox.GetValue()
|
||||||
|
if len(url):
|
||||||
|
urlList.append(url)
|
||||||
|
|
||||||
|
for i in range(min(comboBox.GetCount(), 10)):
|
||||||
|
url = comboBox.GetString(i)
|
||||||
|
if url not in urlList:
|
||||||
|
urlList.append(url)
|
||||||
|
|
||||||
|
config = wx.ConfigBase_Get()
|
||||||
|
config.Write(SVN_REPOSITORY_URL, urlList.__repr__())
|
||||||
|
|
||||||
|
|
||||||
|
@@ -56,6 +56,10 @@ def CreateDirectoryControl( parent, fileLabel, dirLabel, fileExtension, starting
|
|||||||
if nameControl.GetValue().find(' ') != -1:
|
if nameControl.GetValue().find(' ') != -1:
|
||||||
wx.MessageBox(_("Please provide a filename that does not contains spaces."), _("Spaces in Filename"))
|
wx.MessageBox(_("Please provide a filename that does not contains spaces."), _("Spaces in Filename"))
|
||||||
return False
|
return False
|
||||||
|
if not os.path.exists(dirControl.GetValue()):
|
||||||
|
wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
|
||||||
|
return False
|
||||||
|
|
||||||
filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(nameControl.GetValue(), "." + fileExtension))
|
filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(nameControl.GetValue(), "." + fileExtension))
|
||||||
if os.path.exists(filePath):
|
if os.path.exists(filePath):
|
||||||
if allowOverwriteOnPrompt:
|
if allowOverwriteOnPrompt:
|
||||||
|
@@ -63,8 +63,8 @@ class XmlService(CodeEditor.CodeService):
|
|||||||
class XmlCtrl(CodeEditor.CodeCtrl):
|
class XmlCtrl(CodeEditor.CodeCtrl):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, ID = -1, style = wx.NO_FULL_REPAINT_ON_RESIZE):
|
def __init__(self, parent, id=-1, style=wx.NO_FULL_REPAINT_ON_RESIZE):
|
||||||
CodeEditor.CodeCtrl.__init__(self, parent, ID, style)
|
CodeEditor.CodeCtrl.__init__(self, parent, id, style)
|
||||||
self.SetLexer(wx.stc.STC_LEX_XML)
|
self.SetLexer(wx.stc.STC_LEX_XML)
|
||||||
self.SetProperty("fold.html", "1")
|
self.SetProperty("fold.html", "1")
|
||||||
|
|
||||||
|
@@ -1924,7 +1924,7 @@ class IOBuffer:
|
|||||||
|
|
||||||
self.__buf = ''
|
self.__buf = ''
|
||||||
# A state change is defined as the buffer being closed or a
|
# A state change is defined as the buffer being closed or a
|
||||||
# write occurring.
|
# write occuring.
|
||||||
if mutex is not None:
|
if mutex is not None:
|
||||||
self._mutex = mutex
|
self._mutex = mutex
|
||||||
else:
|
else:
|
||||||
|
@@ -21,8 +21,9 @@ def _registerMainModuleDir():
|
|||||||
if not os.path.isabs(utilModuleDir):
|
if not os.path.isabs(utilModuleDir):
|
||||||
utilModuleDir = os.path.join(os.getcwd(), 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)))
|
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
|
||||||
|
if mainModuleDir.endswith('.zip'):
|
||||||
|
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
|
||||||
else:
|
else:
|
||||||
mainModuleDir = os.path.dirname(sys.executable)
|
mainModuleDir = os.path.dirname(sys.executable)
|
||||||
|
|
||||||
_registerMainModuleDir()
|
_registerMainModuleDir()
|
||||||
|
|
||||||
|
@@ -14,23 +14,89 @@ import logging
|
|||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
import xmlmarshaller
|
import xmlmarshaller
|
||||||
|
|
||||||
|
AG_TYPE_MAPPING = { "ag:append" : "activegrid.model.processmodel.AppendOperation",
|
||||||
|
"ag:body" : "activegrid.model.processmodel.Body",
|
||||||
|
"ag:copy" : "activegrid.model.processmodel.CopyOperation",
|
||||||
|
"ag:cssRule" : "activegrid.model.processmodel.CssRule",
|
||||||
|
"ag:datasource" : "activegrid.data.dataservice.DataSource",
|
||||||
|
"ag:debug" : "activegrid.model.processmodel.DebugOperation",
|
||||||
|
"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:schemaOptions" : "activegrid.model.schema.SchemaOptions",
|
||||||
|
"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:catch" : "activegrid.model.processmodel.BPELCatch",
|
||||||
|
"bpws:faultHandlers" : "activegrid.model.processmodel.BPELFaultHandlers",
|
||||||
|
"bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
|
||||||
|
"bpws:onMessage" : "activegrid.model.processmodel.BPELOnMessage",
|
||||||
|
"bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
|
||||||
|
"bpws:pick" : "activegrid.model.processmodel.BPELPick",
|
||||||
|
"bpws:process" : "activegrid.model.processmodel.BPELProcess",
|
||||||
|
"bpws:receive" : "activegrid.model.processmodel.BPELReceive",
|
||||||
|
"bpws:reply" : "activegrid.model.processmodel.BPELReply",
|
||||||
|
"bpws:scope" : "activegrid.model.processmodel.BPELScope",
|
||||||
|
"bpws:sequence" : "activegrid.model.processmodel.BPELSequence",
|
||||||
|
"bpws:switch" : "activegrid.model.processmodel.BPELSwitch",
|
||||||
|
"bpws:terminate" : "activegrid.model.processmodel.BPELTerminate",
|
||||||
|
"bpws:variable" : "activegrid.model.processmodel.BPELVariable",
|
||||||
|
"bpws:variables" : "activegrid.model.processmodel.BPELVariables",
|
||||||
|
"bpws:while" : "activegrid.model.processmodel.BPELWhile",
|
||||||
|
"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",
|
||||||
|
"xs:all" : "activegrid.model.schema.XsdSequence",
|
||||||
|
"xs:complexType" : "activegrid.model.schema.XsdComplexType",
|
||||||
|
"xs:element" : "activegrid.model.schema.XsdElement",
|
||||||
|
"xs:field" : "activegrid.model.schema.XsdKeyField",
|
||||||
|
"xs:key" : "activegrid.model.schema.XsdKey",
|
||||||
|
"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
|
||||||
|
"xs:schema" : "activegrid.model.schema.Schema",
|
||||||
|
"xs:selector" : "activegrid.model.schema.XsdKeySelector",
|
||||||
|
"xs:sequence" : "activegrid.model.schema.XsdSequence",
|
||||||
|
"projectmodel" : "activegrid.tool.ProjectEditor.ProjectModel",
|
||||||
|
}
|
||||||
|
|
||||||
def defaultLoad(fileObject, knownTypes=None):
|
def defaultLoad(fileObject, knownTypes=None):
|
||||||
xml = fileObject.read()
|
xml = fileObject.read()
|
||||||
loadedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
loadedObject = defaultUnmarshal(xml, knownTypes=knownTypes)
|
||||||
if hasattr(fileObject, 'name'):
|
if hasattr(fileObject, 'name'):
|
||||||
loadedObject.fileName = os.path.abspath(fileObject.name)
|
loadedObject.fileName = os.path.abspath(fileObject.name)
|
||||||
loadedObject.initialize()
|
loadedObject.initialize()
|
||||||
return loadedObject
|
return loadedObject
|
||||||
|
|
||||||
def defaultSave(fileObject, objectToSave, knownTypes=None, withEncoding=1, encoding='utf-8'):
|
def defaultUnmarshal(xml, knownTypes=None):
|
||||||
xml = xmlmarshaller.marshal(objectToSave, prettyPrint=True, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
|
if not knownTypes: knownTypes = AG_TYPE_MAPPING
|
||||||
|
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
||||||
|
|
||||||
|
def defaultSave(fileObject, objectToSave, prettyPrint=True, knownTypes=None, withEncoding=1, encoding='utf-8'):
|
||||||
|
xml = defaultMarshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
|
||||||
fileObject.write(xml)
|
fileObject.write(xml)
|
||||||
fileObject.flush()
|
fileObject.flush()
|
||||||
|
|
||||||
|
def defaultMarshal(objectToSave, prettyPrint=True, knownTypes=None, withEncoding=1, encoding='utf-8'):
|
||||||
|
if not knownTypes: knownTypes = AG_TYPE_MAPPING
|
||||||
|
return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
|
||||||
|
|
||||||
def clone(objectToClone, knownTypes=None, encoding='utf-8'):
|
def clone(objectToClone, knownTypes=None, encoding='utf-8'):
|
||||||
|
if not knownTypes: knownTypes = AG_TYPE_MAPPING
|
||||||
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
|
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
|
||||||
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
||||||
if hasattr(objectToClone, 'fileName'):
|
if hasattr(objectToClone, 'fileName'):
|
||||||
@@ -91,3 +157,116 @@ def hasPropertyValue(obj, attr):
|
|||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
return hasProp
|
return hasProp
|
||||||
|
|
||||||
|
def toDiffableString(value):
|
||||||
|
s = repr(value)
|
||||||
|
ds = ""
|
||||||
|
i = s.find(" at 0x")
|
||||||
|
start = 0
|
||||||
|
while (i >= 0):
|
||||||
|
j = s.find(">", i)
|
||||||
|
if (j < i):
|
||||||
|
break
|
||||||
|
ds += s[start:i]
|
||||||
|
start = j
|
||||||
|
i = s.find(" at 0x", start)
|
||||||
|
return ds + s[start:]
|
||||||
|
|
||||||
|
PRINT_OBJ_GETATTR = 1
|
||||||
|
PRINT_OBJ_HIDE_INTERNAL = 2
|
||||||
|
PRINT_OBJ_COMPACT = 4
|
||||||
|
PRINT_OBJ_NONONE = 8
|
||||||
|
PRINT_OBJ_INTERNAL = 512
|
||||||
|
|
||||||
|
def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent=30):
|
||||||
|
if ((maxIndent != None) and (indent > maxIndent)):
|
||||||
|
print >> out, " "*indent, name, str(object)
|
||||||
|
return True
|
||||||
|
finalNewLine = False
|
||||||
|
printed = True
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) > 0):
|
||||||
|
if (exclude and object in exclude):
|
||||||
|
return
|
||||||
|
indent = 0
|
||||||
|
if ((flags & PRINT_OBJ_INTERNAL) == 0):
|
||||||
|
finalNewLine = True
|
||||||
|
flags |= PRINT_OBJ_INTERNAL
|
||||||
|
if (object == None):
|
||||||
|
if (flags & PRINT_OBJ_NONONE) == 0:
|
||||||
|
print >> out, " "*indent, name, " = None",
|
||||||
|
else:
|
||||||
|
finalNewLine = False
|
||||||
|
printed = False
|
||||||
|
elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
|
||||||
|
finalNewLine = False
|
||||||
|
printed = False
|
||||||
|
elif (isinstance(object, (list, tuple))):
|
||||||
|
if (exclude and object in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (already printed)",
|
||||||
|
elif (exclude and name in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (excluded)",
|
||||||
|
else:
|
||||||
|
if (exclude != None): exclude.append(object)
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " of length = %i" % len(object),
|
||||||
|
for i, o in enumerate(object):
|
||||||
|
print >> out
|
||||||
|
printObject(out, o, name="[%i]" % i, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||||
|
elif (isinstance(object, dict)):
|
||||||
|
if (exclude and object in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " (already printed)",
|
||||||
|
else:
|
||||||
|
if (exclude != None): exclude.append(object)
|
||||||
|
if (len(name) > 0):
|
||||||
|
print >> out, " "*indent, name,
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||||
|
print >> out
|
||||||
|
indent += 2
|
||||||
|
print >> out, " "*indent, "{",
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||||
|
print >> out
|
||||||
|
keys = object.keys()
|
||||||
|
keys.sort()
|
||||||
|
for n in keys:
|
||||||
|
if ((n != None) and (not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))):
|
||||||
|
if printObject(out, object[n], name=n, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent):
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||||
|
print >> out
|
||||||
|
else:
|
||||||
|
print >> out, ",",
|
||||||
|
print >> out, " "*indent, "}",
|
||||||
|
elif (hasattr(object, "__dict__")):
|
||||||
|
if (exclude and object in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " (already printed) = ", toDiffableString(object),
|
||||||
|
else:
|
||||||
|
if (exclude != None): exclude.append(object)
|
||||||
|
if (name.startswith("_")):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object),
|
||||||
|
elif (exclude and object.__dict__ in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " (already printed)",
|
||||||
|
else:
|
||||||
|
print >> out, " "*indent, name, " : ", type(object),
|
||||||
|
if ((flags & PRINT_OBJ_GETATTR) == 0):
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||||
|
print >> out
|
||||||
|
printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||||
|
else:
|
||||||
|
keys = object.__dict__.keys()
|
||||||
|
keys.sort()
|
||||||
|
for n in keys:
|
||||||
|
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||||
|
print >> out
|
||||||
|
printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||||
|
elif (indent < 0):
|
||||||
|
print >> out, object,
|
||||||
|
elif isinstance(object, basestring):
|
||||||
|
if (exclude and name in exclude):
|
||||||
|
print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (excluded)",
|
||||||
|
elif (len(object) > 100):
|
||||||
|
print >> out, " "*indent, name, ":", type(object), "[%i] = %s...%s" % (len(object), object[:50], object[-50:]),
|
||||||
|
else:
|
||||||
|
print >> out, " "*indent, name, ":", type(object), "=", str(object),
|
||||||
|
else:
|
||||||
|
print >> out, " "*indent, name, ":", type(object), "=", str(object),
|
||||||
|
if (finalNewLine):
|
||||||
|
print >> out
|
||||||
|
return printed
|
||||||
|
@@ -195,6 +195,8 @@ def _objectfactory(objname, objargs=None, xsname=None):
|
|||||||
try:
|
try:
|
||||||
if __builtin__.__dict__.has_key(objname):
|
if __builtin__.__dict__.has_key(objname):
|
||||||
module = __builtin__
|
module = __builtin__
|
||||||
|
elif knownGlobalModule:
|
||||||
|
module = knownGlobalModule
|
||||||
else:
|
else:
|
||||||
if modulename:
|
if modulename:
|
||||||
module = __import__(modulename)
|
module = __import__(modulename)
|
||||||
@@ -431,12 +433,13 @@ def _getXmlValue(pythonValue):
|
|||||||
else:
|
else:
|
||||||
return str(pythonValue)
|
return str(pythonValue)
|
||||||
|
|
||||||
def unmarshal(xmlstr, knownTypes=None):
|
def unmarshal(xmlstr, knownTypes=None, knownModule=None):
|
||||||
global knownGlobalTypes
|
global knownGlobalTypes, knownGlobalModule
|
||||||
if (knownTypes == None):
|
if (knownTypes == None):
|
||||||
knownGlobalTypes = {}
|
knownGlobalTypes = {}
|
||||||
else:
|
else:
|
||||||
knownGlobalTypes = knownTypes
|
knownGlobalTypes = knownTypes
|
||||||
|
knownGlobalModule = knownModule
|
||||||
objectfactory = XMLObjectFactory()
|
objectfactory = XMLObjectFactory()
|
||||||
xml.sax.parseString(xmlstr, objectfactory)
|
xml.sax.parseString(xmlstr, objectfactory)
|
||||||
return objectfactory.getRootObject()
|
return objectfactory.getRootObject()
|
||||||
|
@@ -435,6 +435,7 @@ class Document(wx.EvtHandler):
|
|||||||
msgTitle = _("File Error")
|
msgTitle = _("File Error")
|
||||||
|
|
||||||
backupFilename = None
|
backupFilename = None
|
||||||
|
fileObject = None
|
||||||
try:
|
try:
|
||||||
# if current file exists, move it to a safe place temporarily
|
# if current file exists, move it to a safe place temporarily
|
||||||
if os.path.exists(filename):
|
if os.path.exists(filename):
|
||||||
@@ -457,10 +458,18 @@ class Document(wx.EvtHandler):
|
|||||||
fileObject = file(filename, 'w')
|
fileObject = file(filename, 'w')
|
||||||
self.SaveObject(fileObject)
|
self.SaveObject(fileObject)
|
||||||
fileObject.close()
|
fileObject.close()
|
||||||
|
fileObject = None
|
||||||
|
|
||||||
if backupFilename:
|
if backupFilename:
|
||||||
os.remove(backupFilename)
|
os.remove(backupFilename)
|
||||||
except:
|
except:
|
||||||
|
# for debugging purposes
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
if fileObject:
|
||||||
|
fileObject.close() # file is still open, close it, need to do this before removal
|
||||||
|
|
||||||
# save failed, restore old file
|
# save failed, restore old file
|
||||||
if backupFilename:
|
if backupFilename:
|
||||||
os.remove(filename)
|
os.remove(filename)
|
||||||
@@ -501,7 +510,16 @@ class Document(wx.EvtHandler):
|
|||||||
fileObject = file(filename, 'r')
|
fileObject = file(filename, 'r')
|
||||||
try:
|
try:
|
||||||
self.LoadObject(fileObject)
|
self.LoadObject(fileObject)
|
||||||
|
fileObject.close()
|
||||||
|
fileObject = None
|
||||||
except:
|
except:
|
||||||
|
# for debugging purposes
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
if fileObject:
|
||||||
|
fileObject.close() # file is still open, close it
|
||||||
|
|
||||||
wx.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename), sys.exc_value),
|
wx.MessageBox("Could not open '%s'. %s" % (FileNameFromPath(filename), sys.exc_value),
|
||||||
msgTitle,
|
msgTitle,
|
||||||
wx.OK | wx.ICON_EXCLAMATION,
|
wx.OK | wx.ICON_EXCLAMATION,
|
||||||
@@ -945,7 +963,7 @@ class View(wx.EvtHandler):
|
|||||||
|
|
||||||
Override to return an instance of a class other than wxDocPrintout.
|
Override to return an instance of a class other than wxDocPrintout.
|
||||||
"""
|
"""
|
||||||
return DocPrintout(self)
|
return DocPrintout(self, self.GetDocument().GetPrintableName())
|
||||||
|
|
||||||
|
|
||||||
def GetFrame(self):
|
def GetFrame(self):
|
||||||
@@ -1229,6 +1247,10 @@ class DocTemplate(wx.Object):
|
|||||||
Returns True if the path's extension matches one of this template's
|
Returns True if the path's extension matches one of this template's
|
||||||
file filter extensions.
|
file filter extensions.
|
||||||
"""
|
"""
|
||||||
|
## print "*** path", path
|
||||||
|
## if "*.*" in self.GetFileFilter():
|
||||||
|
## return True
|
||||||
|
##
|
||||||
ext = FindExtension(path)
|
ext = FindExtension(path)
|
||||||
if not ext: return False
|
if not ext: return False
|
||||||
return ext in self.GetFileFilter()
|
return ext in self.GetFileFilter()
|
||||||
@@ -1450,9 +1472,14 @@ class DocManager(wx.EvtHandler):
|
|||||||
|
|
||||||
printout = view.OnCreatePrintout()
|
printout = view.OnCreatePrintout()
|
||||||
if printout:
|
if printout:
|
||||||
pdd = wx.PrintDialogData()
|
if not hasattr(self, "printData"):
|
||||||
|
self.printData = wx.PrintData()
|
||||||
|
self.printData.SetPaperId(wx.PAPER_LETTER)
|
||||||
|
self.printData.SetPrintMode(wx.PRINT_MODE_PRINTER)
|
||||||
|
|
||||||
|
pdd = wx.PrintDialogData(self.printData)
|
||||||
printer = wx.Printer(pdd)
|
printer = wx.Printer(pdd)
|
||||||
printer.Print(view.GetFrame(), printout) # , True)
|
printer.Print(view.GetFrame(), printout)
|
||||||
|
|
||||||
|
|
||||||
def OnPrintSetup(self, event):
|
def OnPrintSetup(self, event):
|
||||||
@@ -1465,11 +1492,21 @@ class DocManager(wx.EvtHandler):
|
|||||||
else:
|
else:
|
||||||
parentWin = wx.GetApp().GetTopWindow()
|
parentWin = wx.GetApp().GetTopWindow()
|
||||||
|
|
||||||
data = wx.PrintDialogData()
|
if not hasattr(self, "printData"):
|
||||||
|
self.printData = wx.PrintData()
|
||||||
|
self.printData.SetPaperId(wx.PAPER_LETTER)
|
||||||
|
|
||||||
|
data = wx.PrintDialogData(self.printData)
|
||||||
printDialog = wx.PrintDialog(parentWin, data)
|
printDialog = wx.PrintDialog(parentWin, data)
|
||||||
printDialog.GetPrintDialogData().SetSetupDialog(True)
|
printDialog.GetPrintDialogData().SetSetupDialog(True)
|
||||||
printDialog.ShowModal()
|
printDialog.ShowModal()
|
||||||
# TODO: Confirm that we don't have to remember PrintDialogData
|
|
||||||
|
# this makes a copy of the wx.PrintData instead of just saving
|
||||||
|
# a reference to the one inside the PrintDialogData that will
|
||||||
|
# be destroyed when the dialog is destroyed
|
||||||
|
self.printData = wx.PrintData(printDialog.GetPrintDialogData().GetPrintData())
|
||||||
|
|
||||||
|
printDialog.Destroy()
|
||||||
|
|
||||||
|
|
||||||
def OnPreview(self, event):
|
def OnPreview(self, event):
|
||||||
@@ -1483,13 +1520,22 @@ class DocManager(wx.EvtHandler):
|
|||||||
|
|
||||||
printout = view.OnCreatePrintout()
|
printout = view.OnCreatePrintout()
|
||||||
if printout:
|
if printout:
|
||||||
|
if not hasattr(self, "printData"):
|
||||||
|
self.printData = wx.PrintData()
|
||||||
|
self.printData.SetPaperId(wx.PAPER_LETTER)
|
||||||
|
self.printData.SetPrintMode(wx.PRINT_MODE_PREVIEW)
|
||||||
|
|
||||||
|
data = wx.PrintDialogData(self.printData)
|
||||||
# Pass two printout objects: for preview, and possible printing.
|
# Pass two printout objects: for preview, and possible printing.
|
||||||
preview = wx.PrintPreview(printout, view.OnCreatePrintout())
|
preview = wx.PrintPreview(printout, view.OnCreatePrintout(), data)
|
||||||
|
if not preview.Ok():
|
||||||
|
wx.MessageBox(_("Unable to display print preview."))
|
||||||
|
return
|
||||||
# wxWindows source doesn't use base frame's pos, size, and icon, but did it this way so it would work like MS Office etc.
|
# wxWindows source doesn't use base frame's pos, size, and icon, but did it this way so it would work like MS Office etc.
|
||||||
mimicFrame = wx.GetApp().GetTopWindow()
|
mimicFrame = wx.GetApp().GetTopWindow()
|
||||||
frame = wx.PreviewFrame(preview, mimicFrame, _("Print Preview"), mimicFrame.GetPosition(), mimicFrame.GetSize())
|
frame = wx.PreviewFrame(preview, mimicFrame, _("Print Preview"), mimicFrame.GetPosition(), mimicFrame.GetSize())
|
||||||
frame.SetIcon(mimicFrame.GetIcon())
|
frame.SetIcon(mimicFrame.GetIcon())
|
||||||
frame.SetTitle(mimicFrame.GetTitle() + _(" - Preview"))
|
frame.SetTitle(_("%s - %s - Preview") % (mimicFrame.GetTitle(), view.GetDocument().GetPrintableName()))
|
||||||
frame.Initialize()
|
frame.Initialize()
|
||||||
frame.Show(True)
|
frame.Show(True)
|
||||||
|
|
||||||
@@ -1575,7 +1621,7 @@ class DocManager(wx.EvtHandler):
|
|||||||
if doc and doc.GetCommandProcessor():
|
if doc and doc.GetCommandProcessor():
|
||||||
doc.GetCommandProcessor().SetMenuStrings()
|
doc.GetCommandProcessor().SetMenuStrings()
|
||||||
else:
|
else:
|
||||||
event.SetText(_("Undo") + '\t' + _('Ctrl+Z'))
|
event.SetText(_("&Undo\tCtrl+Z"))
|
||||||
|
|
||||||
|
|
||||||
def OnUpdateRedo(self, event):
|
def OnUpdateRedo(self, event):
|
||||||
@@ -1587,7 +1633,7 @@ class DocManager(wx.EvtHandler):
|
|||||||
if doc and doc.GetCommandProcessor():
|
if doc and doc.GetCommandProcessor():
|
||||||
doc.GetCommandProcessor().SetMenuStrings()
|
doc.GetCommandProcessor().SetMenuStrings()
|
||||||
else:
|
else:
|
||||||
event.SetText(_("Redo") + '\t' + _('Ctrl+Y'))
|
event.SetText(_("&Redo\tCtrl+Y"))
|
||||||
|
|
||||||
|
|
||||||
def OnUpdatePrint(self, event):
|
def OnUpdatePrint(self, event):
|
||||||
@@ -1800,9 +1846,9 @@ class DocManager(wx.EvtHandler):
|
|||||||
temp, path = self.SelectDocumentPath(templates, path, flags)
|
temp, path = self.SelectDocumentPath(templates, path, flags)
|
||||||
|
|
||||||
# Existing document
|
# Existing document
|
||||||
if self.GetFlags() & DOC_OPEN_ONCE:
|
if path and self.GetFlags() & DOC_OPEN_ONCE:
|
||||||
for document in self._docs:
|
for document in self._docs:
|
||||||
if document.GetFilename() == path:
|
if document.GetFilename() and os.path.normcase(document.GetFilename()) == os.path.normcase(path):
|
||||||
""" check for file modification outside of application """
|
""" check for file modification outside of application """
|
||||||
if os.path.exists(path) and os.path.getmtime(path) != document.GetDocumentModificationDate():
|
if os.path.exists(path) and os.path.getmtime(path) != document.GetDocumentModificationDate():
|
||||||
msgTitle = wx.GetApp().GetAppName()
|
msgTitle = wx.GetApp().GetAppName()
|
||||||
@@ -2034,11 +2080,17 @@ class DocManager(wx.EvtHandler):
|
|||||||
Given a path, try to find template that matches the extension. This is
|
Given a path, try to find template that matches the extension. This is
|
||||||
only an approximate method of finding a template for creating a
|
only an approximate method of finding a template for creating a
|
||||||
document.
|
document.
|
||||||
|
|
||||||
|
Note this wxPython verson looks for and returns a default template if no specific template is found.
|
||||||
"""
|
"""
|
||||||
|
default = None
|
||||||
for temp in self._templates:
|
for temp in self._templates:
|
||||||
if temp.FileMatchesTemplate(path):
|
if temp.FileMatchesTemplate(path):
|
||||||
return temp
|
return temp
|
||||||
return None
|
|
||||||
|
if "*.*" in temp.GetFileFilter():
|
||||||
|
default = temp
|
||||||
|
return default
|
||||||
|
|
||||||
|
|
||||||
def FindSuitableParent(self):
|
def FindSuitableParent(self):
|
||||||
@@ -2077,7 +2129,7 @@ class DocManager(wx.EvtHandler):
|
|||||||
allfilter = allfilter + _(';')
|
allfilter = allfilter + _(';')
|
||||||
descr = descr + temp.GetDescription() + _(" (") + temp.GetFileFilter() + _(") |") + temp.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
descr = descr + temp.GetDescription() + _(" (") + temp.GetFileFilter() + _(") |") + temp.GetFileFilter() # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
||||||
allfilter = allfilter + temp.GetFileFilter()
|
allfilter = allfilter + temp.GetFileFilter()
|
||||||
descr = _("All") + _(" (") + allfilter + _(") |") + allfilter + _('|') + descr # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
descr = _("All (%s)|%s|%s|Any (*.*) | *.*") % (allfilter, allfilter, descr) # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
||||||
else:
|
else:
|
||||||
descr = _("*.*")
|
descr = _("*.*")
|
||||||
|
|
||||||
@@ -2790,7 +2842,7 @@ class DocPrintout(wx.Printout):
|
|||||||
"""
|
"""
|
||||||
Constructor.
|
Constructor.
|
||||||
"""
|
"""
|
||||||
wx.Printout.__init__(self)
|
wx.Printout.__init__(self, title)
|
||||||
self._printoutView = view
|
self._printoutView = view
|
||||||
|
|
||||||
|
|
||||||
@@ -3058,15 +3110,15 @@ class CommandProcessor(wx.Object):
|
|||||||
else:
|
else:
|
||||||
redoAccel = ''
|
redoAccel = ''
|
||||||
if undoCommand and undoItem and undoCommand.CanUndo():
|
if undoCommand and undoItem and undoCommand.CanUndo():
|
||||||
undoItem.SetText(_("Undo ") + undoCommand.GetName() + undoAccel)
|
undoItem.SetText(_("&Undo ") + undoCommand.GetName() + undoAccel)
|
||||||
#elif undoCommand and not undoCommand.CanUndo():
|
#elif undoCommand and not undoCommand.CanUndo():
|
||||||
# undoItem.SetText(_("Can't Undo") + undoAccel)
|
# undoItem.SetText(_("Can't Undo") + undoAccel)
|
||||||
else:
|
else:
|
||||||
undoItem.SetText(_("Undo" + undoAccel))
|
undoItem.SetText(_("&Undo" + undoAccel))
|
||||||
if redoCommand and redoItem:
|
if redoCommand and redoItem:
|
||||||
redoItem.SetText(_("Redo ") + redoCommand.GetName() + redoAccel)
|
redoItem.SetText(_("&Redo ") + redoCommand.GetName() + redoAccel)
|
||||||
else:
|
else:
|
||||||
redoItem.SetText(_("Redo") + redoAccel)
|
redoItem.SetText(_("&Redo") + redoAccel)
|
||||||
|
|
||||||
|
|
||||||
def CanUndo(self):
|
def CanUndo(self):
|
||||||
|
@@ -295,7 +295,7 @@ class DocMDIParentFrameMixIn:
|
|||||||
|
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
if config.ReadInt("MDIFrameMaximized", False):
|
if config.ReadInt("MDIFrameMaximized", False):
|
||||||
# wxBug: On maximize, statusbar leaves a residual that needs to be refreshed, happens even when user does it
|
# wxBug: On maximize, statusbar leaves a residual that needs to be refereshed, happens even when user does it
|
||||||
self.Maximize()
|
self.Maximize()
|
||||||
|
|
||||||
self.CreateEmbeddedWindows(embeddedWindows)
|
self.CreateEmbeddedWindows(embeddedWindows)
|
||||||
@@ -1603,7 +1603,7 @@ class DocApp(wx.PySimpleApp):
|
|||||||
args = pickle.loads(data)
|
args = pickle.loads(data)
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
|
if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
|
||||||
self.GetDocumentManager().CreateDocument(arg, wx.lib.docview.DOC_SILENT)
|
self.GetDocumentManager().CreateDocument(os.path.normpath(arg), wx.lib.docview.DOC_SILENT)
|
||||||
|
|
||||||
# force display of running app
|
# force display of running app
|
||||||
topWindow = wx.GetApp().GetTopWindow()
|
topWindow = wx.GetApp().GetTopWindow()
|
||||||
@@ -1624,7 +1624,7 @@ class DocApp(wx.PySimpleApp):
|
|||||||
args = sys.argv[1:]
|
args = sys.argv[1:]
|
||||||
for arg in args:
|
for arg in args:
|
||||||
if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
|
if arg[0] != '/' and arg[0] != '-' and os.path.exists(arg):
|
||||||
self.GetDocumentManager().CreateDocument(arg, wx.lib.docview.DOC_SILENT)
|
self.GetDocumentManager().CreateDocument(os.path.normpath(arg), wx.lib.docview.DOC_SILENT)
|
||||||
|
|
||||||
|
|
||||||
def GetDocumentManager(self):
|
def GetDocumentManager(self):
|
||||||
|
Reference in New Issue
Block a user