DocView and ActiveGrid IDE updates from Morgan Hua:
New Features: In Tab-View mode, Ctrl-number will take the user to the numbered tab view. Modified files now show an '*' astrisk in the view title. Debugger framework can now support PHP debugging. Not important for python development, but at least that means the debugger framework is more generalized. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38852 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
20
wxPython/samples/ide/activegrid/model/projectmodel.py
Normal file
20
wxPython/samples/ide/activegrid/model/projectmodel.py
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: projectmodel.py
|
||||||
|
# Purpose: This file contains project model information
|
||||||
|
#
|
||||||
|
# Author: Morgan Hua
|
||||||
|
#
|
||||||
|
# Created: 4/18/06
|
||||||
|
# CVS-ID: $Id$
|
||||||
|
# Copyright: (c) 2006 ActiveGrid, Inc.
|
||||||
|
# License: wxWindows License
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Constants
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
LANGUAGE_PYTHON = "python"
|
||||||
|
LANGUAGE_PHP = "php"
|
||||||
|
LANGUAGE_DEFAULT = LANGUAGE_PYTHON
|
||||||
|
LANGUAGE_LIST = [LANGUAGE_PHP, LANGUAGE_PYTHON]
|
@@ -5,7 +5,7 @@
|
|||||||
# Author: Morgan Hua
|
# Author: Morgan Hua
|
||||||
#
|
#
|
||||||
# Created: 3/22/05
|
# Created: 3/22/05
|
||||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
# License: wxWindows License
|
# License: wxWindows License
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
@@ -30,23 +30,25 @@ licenseData = [ # add licenses for base IDE features
|
|||||||
("Python 2.4", "Python Software Foundation License", "http://www.python.org/2.4/license.html"),
|
("Python 2.4", "Python Software Foundation License", "http://www.python.org/2.4/license.html"),
|
||||||
("wxPython 2.6", "wxWidgets 2 - LGPL", "http://wxwidgets.org/newlicen.htm"),
|
("wxPython 2.6", "wxWidgets 2 - LGPL", "http://wxwidgets.org/newlicen.htm"),
|
||||||
("wxWidgets", "wxWindows Library License 3", "http://www.wxwidgets.org/manuals/2.6.1/wx_wxlicense.html"),
|
("wxWidgets", "wxWindows Library License 3", "http://www.wxwidgets.org/manuals/2.6.1/wx_wxlicense.html"),
|
||||||
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
|
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
|
||||||
("process.py", "See file", "http://starship.python.net/~tmick/"),
|
("process.py", "See file", "http://starship.python.net/~tmick/"),
|
||||||
("pysvn", "Apache License, Version 2.0", "http://pysvn.tigris.org/"),
|
("pysvn", "Apache License, Version 2.0", "http://pysvn.tigris.org/"),
|
||||||
]
|
]
|
||||||
|
|
||||||
if not ACTIVEGRID_BASE_IDE: # add licenses for non-base IDE features such as database connections
|
if not ACTIVEGRID_BASE_IDE: # add licenses for non-base IDE features such as database connections
|
||||||
licenseData += [
|
licenseData += [
|
||||||
("pydb2", "LGPL", "http://sourceforge.net/projects/pydb2"),
|
("pydb2", "LGPL", "http://sourceforge.net/projects/pydb2"),
|
||||||
("pysqlite", "Python License (CNRI)", "http://sourceforge.net/projects/pysqlite"),
|
("pysqlite", "Python License (CNRI)", "http://sourceforge.net/projects/pysqlite"),
|
||||||
("mysql-python", "GPL, Python License (CNRI), Zope Public License", "http://sourceforge.net/projects/mysql-python"),
|
("mysql-python", "GPL, Python License (CNRI), Zope Public License", "http://sourceforge.net/projects/mysql-python"),
|
||||||
("cx_Oracle", "Computronix", "http://www.computronix.com/download/License(cxOracle).txt"),
|
("cx_Oracle", "Computronix", "http://www.computronix.com/download/License(cxOracle).txt"),
|
||||||
("SQLite", "Public Domain", "http://www.sqlite.org/copyright.html"),
|
("SQLite", "Public Domain", "http://www.sqlite.org/copyright.html"),
|
||||||
("PyGreSQL", "BSD", "http://www.pygresql.org"),
|
("PyGreSQL", "BSD", "http://www.pygresql.org"),
|
||||||
("pyXML", "CNRI Python License", "http://sourceforge.net/softwaremap/trove_list.php?form_cat=194"),
|
("pyXML", "CNRI Python License", "http://sourceforge.net/softwaremap/trove_list.php?form_cat=194"),
|
||||||
("Zolera Soap Infrastructure", "Zope Public License 2.0", "http://www.zope.org/Resources/License/"),
|
("Zolera Soap Infrastructure", "Zope Public License 2.0", "http://www.zope.org/Resources/License/"),
|
||||||
|
("python-ldap", "Python Software Foundation License", "http://python-ldap.sourceforge.net"),
|
||||||
("Sarissa", "LGPL", "http://sourceforge.net/projects/sarissa/"),
|
("Sarissa", "LGPL", "http://sourceforge.net/projects/sarissa/"),
|
||||||
("Dynarch DHTML Calendar", "LGPL", "http://www.dynarch.com/projects/calendar/"),
|
("Dynarch DHTML Calendar", "LGPL", "http://www.dynarch.com/projects/calendar/"),
|
||||||
|
("python-dateutil", "Python Software Foundation License", "http://labix.org/python-dateutil"),
|
||||||
]
|
]
|
||||||
|
|
||||||
if wx.Platform == '__WXMSW__': # add Windows only licenses
|
if wx.Platform == '__WXMSW__': # add Windows only licenses
|
||||||
@@ -70,7 +72,7 @@ class AboutDialog(wx.Dialog):
|
|||||||
else:
|
else:
|
||||||
splash_bmp = getIDESplashBitmap()
|
splash_bmp = getIDESplashBitmap()
|
||||||
|
|
||||||
# find version number from
|
# find version number from
|
||||||
versionFilepath = os.path.join(sysutilslib.mainModuleDir, "version.txt")
|
versionFilepath = os.path.join(sysutilslib.mainModuleDir, "version.txt")
|
||||||
if os.path.exists(versionFilepath):
|
if os.path.exists(versionFilepath):
|
||||||
versionfile = open(versionFilepath, 'r')
|
versionfile = open(versionFilepath, 'r')
|
||||||
@@ -82,7 +84,7 @@ class AboutDialog(wx.Dialog):
|
|||||||
|
|
||||||
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() + _("\n%s\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.") % version), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
sizer.Add(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\n%s\n\nCopyright (c) 2003-2006 ActiveGrid Incorporated and Contributors. All rights reserved.") % version), 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"))
|
||||||
@@ -90,15 +92,14 @@ class AboutDialog(wx.Dialog):
|
|||||||
licensePage = wx.Panel(nb, -1)
|
licensePage = wx.Panel(nb, -1)
|
||||||
grid = wx.grid.Grid(licensePage, -1)
|
grid = wx.grid.Grid(licensePage, -1)
|
||||||
grid.CreateGrid(len(licenseData), 2)
|
grid.CreateGrid(len(licenseData), 2)
|
||||||
|
|
||||||
dc = wx.ClientDC(grid)
|
dc = wx.ClientDC(grid)
|
||||||
dc.SetFont(grid.GetLabelFont())
|
dc.SetFont(grid.GetLabelFont())
|
||||||
grid.SetColLabelValue(0, _("License"))
|
grid.SetColLabelValue(0, _("License"))
|
||||||
grid.SetColLabelValue(1, _("URL"))
|
grid.SetColLabelValue(1, _("URL"))
|
||||||
w, maxHeight = dc.GetTextExtent(_("License"))
|
w, h1 = dc.GetTextExtent(_("License"))
|
||||||
w, h = dc.GetTextExtent(_("URL"))
|
w, h2 = dc.GetTextExtent(_("URL"))
|
||||||
if h > maxHeight:
|
maxHeight = max(h1, h2)
|
||||||
maxHeight = h
|
|
||||||
grid.SetColLabelSize(maxHeight + 6) # add a 6 pixel margin
|
grid.SetColLabelSize(maxHeight + 6) # add a 6 pixel margin
|
||||||
|
|
||||||
maxW = 0
|
maxW = 0
|
||||||
@@ -115,7 +116,7 @@ class AboutDialog(wx.Dialog):
|
|||||||
grid.SetCellValue(row, 0, license)
|
grid.SetCellValue(row, 0, license)
|
||||||
if url:
|
if url:
|
||||||
grid.SetCellValue(row, 1, url)
|
grid.SetCellValue(row, 1, url)
|
||||||
|
|
||||||
grid.EnableEditing(False)
|
grid.EnableEditing(False)
|
||||||
grid.EnableDragGridSize(False)
|
grid.EnableDragGridSize(False)
|
||||||
grid.EnableDragColSize(False)
|
grid.EnableDragColSize(False)
|
||||||
@@ -132,10 +133,10 @@ class AboutDialog(wx.Dialog):
|
|||||||
|
|
||||||
creditsPage = wx.Panel(nb, -1)
|
creditsPage = wx.Panel(nb, -1)
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
sizer.Add(wx.StaticText(creditsPage, -1, _("ActiveGrid Development Team:\n\nLarry Abrahams\nLawrence Bruhmuller\nEric Chu\nBeth Fryer\nMatt Fryer\nJoel Hare\nMorgan Hua\nMatt McNulty\nPratik Mehta\nAlan Mullendore\nJeff Norton\nSimon Toens\nKevin Wang\nPeter Yared")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
sizer.Add(wx.StaticText(creditsPage, -1, _("ActiveGrid Development Team:\n\nLarry Abrahams\nLawrence Bruhmuller\nEric Chu\nBeth Fryer\nMatt Fryer\nFrankie Fu\nJoel Hare\nMorgan Hua\nMatt McNulty\nPratik Mehta\nAlan Mullendore\nJeff Norton\nKevin Ollivier\nMatt Small\nSimon Toens\nKevin Wang\nPeter Yared\nJeremy Yun")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
||||||
creditsPage.SetSizer(sizer)
|
creditsPage.SetSizer(sizer)
|
||||||
nb.AddPage(creditsPage, _("Credits"))
|
nb.AddPage(creditsPage, _("Credits"))
|
||||||
|
|
||||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
sizer.Add(nb, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
sizer.Add(nb, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||||
btn = wx.Button(self, wx.ID_OK)
|
btn = wx.Button(self, wx.ID_OK)
|
||||||
@@ -145,5 +146,5 @@ class AboutDialog(wx.Dialog):
|
|||||||
self.Layout()
|
self.Layout()
|
||||||
self.Fit()
|
self.Fit()
|
||||||
grid.ForceRefresh() # wxBug: Get rid of unnecessary scrollbars
|
grid.ForceRefresh() # wxBug: Get rid of unnecessary scrollbars
|
||||||
|
|
||||||
|
|
||||||
|
@@ -36,6 +36,7 @@ PARKING_VERTICAL = 1
|
|||||||
PARKING_HORIZONTAL = 2
|
PARKING_HORIZONTAL = 2
|
||||||
PARKING_OFFSET = 30 # space between shapes
|
PARKING_OFFSET = 30 # space between shapes
|
||||||
|
|
||||||
|
FORCE_REDRAW_METHOD = "ForceRedraw"
|
||||||
|
|
||||||
def GetRawModel(model):
|
def GetRawModel(model):
|
||||||
if hasattr(model, "GetRawModel"):
|
if hasattr(model, "GetRawModel"):
|
||||||
@@ -85,6 +86,7 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
self._propShape = None
|
self._propShape = None
|
||||||
self._maxWidth = 2000
|
self._maxWidth = 2000
|
||||||
self._maxHeight = 16000
|
self._maxHeight = 16000
|
||||||
|
self._valetParking = False
|
||||||
|
|
||||||
|
|
||||||
def OnDraw(self, dc):
|
def OnDraw(self, dc):
|
||||||
@@ -195,6 +197,16 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
self.SetPropertyModel(None)
|
self.SetPropertyModel(None)
|
||||||
|
|
||||||
|
|
||||||
|
def SetLastRightClick(self, x, y):
|
||||||
|
self._lastRightClick = (x,y)
|
||||||
|
|
||||||
|
|
||||||
|
def GetLastRightClick(self):
|
||||||
|
if hasattr(self, "_lastRightClick"):
|
||||||
|
return self._lastRightClick
|
||||||
|
return (-1,-1)
|
||||||
|
|
||||||
|
|
||||||
def OnKeyPressed(self, event):
|
def OnKeyPressed(self, event):
|
||||||
key = event.KeyCode()
|
key = event.KeyCode()
|
||||||
if key == wx.WXK_DELETE:
|
if key == wx.WXK_DELETE:
|
||||||
@@ -211,6 +223,7 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
dc = wx.ClientDC(self._canvas)
|
dc = wx.ClientDC(self._canvas)
|
||||||
self._canvas.PrepareDC(dc)
|
self._canvas.PrepareDC(dc)
|
||||||
x, y = event.GetLogicalPosition(dc) # this takes into account scrollbar offset
|
x, y = event.GetLogicalPosition(dc) # this takes into account scrollbar offset
|
||||||
|
self.SetLastRightClick(x, y)
|
||||||
shape = self._canvas.FindShape(x, y)[0]
|
shape = self._canvas.FindShape(x, y)[0]
|
||||||
|
|
||||||
model = None
|
model = None
|
||||||
@@ -260,12 +273,15 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# click on empty part of canvas, deselect everything
|
# click on empty part of canvas, deselect everything
|
||||||
|
forceRedrawShapes = []
|
||||||
needRefresh = False
|
needRefresh = False
|
||||||
for shape in self._diagram.GetShapeList():
|
for shape in self._diagram.GetShapeList():
|
||||||
if hasattr(shape, "GetModel"):
|
if hasattr(shape, "GetModel"):
|
||||||
if shape.Selected():
|
if shape.Selected():
|
||||||
needRefresh = True
|
needRefresh = True
|
||||||
shape.Select(False, dc)
|
shape.Select(False, dc)
|
||||||
|
if hasattr(shape, FORCE_REDRAW_METHOD):
|
||||||
|
forceRedrawShapes.append(shape)
|
||||||
if needRefresh:
|
if needRefresh:
|
||||||
self._canvas.Redraw(dc)
|
self._canvas.Redraw(dc)
|
||||||
|
|
||||||
@@ -274,7 +290,8 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
if len(self.GetSelection()) == 0:
|
if len(self.GetSelection()) == 0:
|
||||||
self.SetPropertyShape(None)
|
self.SetPropertyShape(None)
|
||||||
|
|
||||||
|
for shape in forceRedrawShapes:
|
||||||
|
shape.ForceRedraw()
|
||||||
|
|
||||||
def OnLeftDoubleClick(self, event):
|
def OnLeftDoubleClick(self, event):
|
||||||
propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
|
propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
|
||||||
@@ -401,8 +418,20 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
dc.EndDrawing()
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
|
||||||
|
def SetValetParking(self, enable=True):
|
||||||
|
""" If valet parking is enabled, remember last parking spot and try for a spot near it """
|
||||||
|
self._valetParking = enable
|
||||||
|
if enable:
|
||||||
|
self._valetPosition = None
|
||||||
|
|
||||||
|
|
||||||
def FindParkingSpot(self, width, height, parking=PARKING_HORIZONTAL, x=PARKING_OFFSET, y=PARKING_OFFSET):
|
def FindParkingSpot(self, width, height, parking=PARKING_HORIZONTAL, x=PARKING_OFFSET, y=PARKING_OFFSET):
|
||||||
""" given a width and height, find a upper left corner where shape can be parked without overlapping other shape """
|
"""
|
||||||
|
Given a width and height, find a upper left corner where shape can be parked without overlapping other shape
|
||||||
|
"""
|
||||||
|
if self._valetParking and self._valetPosition:
|
||||||
|
x, y = self._valetPosition
|
||||||
|
|
||||||
max = 700 # max distance to the right where we'll place tables
|
max = 700 # max distance to the right where we'll place tables
|
||||||
noParkingSpot = True
|
noParkingSpot = True
|
||||||
|
|
||||||
@@ -422,6 +451,9 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
else:
|
else:
|
||||||
noParkingSpot = False
|
noParkingSpot = False
|
||||||
|
|
||||||
|
if self._valetParking:
|
||||||
|
self._valetPosition = (x, y)
|
||||||
|
|
||||||
return x, y
|
return x, y
|
||||||
|
|
||||||
|
|
||||||
@@ -518,7 +550,8 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
self._diagram.RemoveShape(line)
|
self._diagram.RemoveShape(line)
|
||||||
line.Delete()
|
line.Delete()
|
||||||
|
|
||||||
shape.RemoveFromCanvas(self._canvas)
|
if self._canvas:
|
||||||
|
shape.RemoveFromCanvas(self._canvas)
|
||||||
self._diagram.RemoveShape(shape)
|
self._diagram.RemoveShape(shape)
|
||||||
shape.Delete()
|
shape.Delete()
|
||||||
|
|
||||||
@@ -698,6 +731,9 @@ class CanvasView(wx.lib.docview.View):
|
|||||||
self._propShape.SetTextColour("WHITE", 0)
|
self._propShape.SetTextColour("WHITE", 0)
|
||||||
self._propShape.Draw(dc)
|
self._propShape.Draw(dc)
|
||||||
|
|
||||||
|
if hasattr(self._propShape, FORCE_REDRAW_METHOD):
|
||||||
|
self._propShape.ForceRedraw()
|
||||||
|
|
||||||
dc.EndDrawing()
|
dc.EndDrawing()
|
||||||
|
|
||||||
|
|
||||||
|
@@ -19,7 +19,6 @@ import os
|
|||||||
import re
|
import re
|
||||||
import string
|
import string
|
||||||
import sys
|
import sys
|
||||||
import DebuggerService
|
|
||||||
import MarkerService
|
import MarkerService
|
||||||
from UICommon import CaseInsensitiveCompare
|
from UICommon import CaseInsensitiveCompare
|
||||||
_ = wx.GetTranslation
|
_ = wx.GetTranslation
|
||||||
@@ -120,16 +119,27 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
return False
|
return False
|
||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
if id == EXPAND_TEXT_ID:
|
if id == EXPAND_TEXT_ID:
|
||||||
event.Enable(self.GetCtrl().CanLineExpand(self.GetCtrl().GetCurrentLine()))
|
if self.GetCtrl().GetViewFolding():
|
||||||
|
event.Enable(self.GetCtrl().CanLineExpand(self.GetCtrl().GetCurrentLine()))
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
return True
|
return True
|
||||||
elif id == COLLAPSE_TEXT_ID:
|
elif id == COLLAPSE_TEXT_ID:
|
||||||
event.Enable(self.GetCtrl().CanLineCollapse(self.GetCtrl().GetCurrentLine()))
|
if self.GetCtrl().GetViewFolding():
|
||||||
|
event.Enable(self.GetCtrl().CanLineCollapse(self.GetCtrl().GetCurrentLine()))
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
return True
|
return True
|
||||||
elif (id == EXPAND_TOP_ID
|
elif (id == EXPAND_TOP_ID
|
||||||
or id == COLLAPSE_TOP_ID
|
or id == COLLAPSE_TOP_ID
|
||||||
or id == EXPAND_ALL_ID
|
or id == EXPAND_ALL_ID
|
||||||
or id == COLLAPSE_ALL_ID
|
or id == COLLAPSE_ALL_ID):
|
||||||
or id == AUTO_COMPLETE_ID
|
if self.GetCtrl().GetViewFolding():
|
||||||
|
event.Enable(self.GetCtrl().GetTextLength() > 0)
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
elif (id == AUTO_COMPLETE_ID
|
||||||
or id == CLEAN_WHITESPACE
|
or id == CLEAN_WHITESPACE
|
||||||
or id == INDENT_LINES_ID
|
or id == INDENT_LINES_ID
|
||||||
or id == DEDENT_LINES_ID
|
or id == DEDENT_LINES_ID
|
||||||
@@ -140,10 +150,12 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
elif id == CHECK_CODE_ID:
|
elif id == CHECK_CODE_ID:
|
||||||
event.Enable(False)
|
event.Enable(False)
|
||||||
return True
|
return True
|
||||||
elif (id == SET_INDENT_WIDTH_ID
|
elif id == SET_INDENT_WIDTH_ID:
|
||||||
or id == FOLDING_ID):
|
|
||||||
event.Enable(True)
|
event.Enable(True)
|
||||||
return True
|
return True
|
||||||
|
elif id == FOLDING_ID:
|
||||||
|
event.Enable(self.GetCtrl().GetViewFolding())
|
||||||
|
return True
|
||||||
elif id == USE_TABS_ID:
|
elif id == USE_TABS_ID:
|
||||||
event.Enable(True)
|
event.Enable(True)
|
||||||
event.Check(self.GetCtrl().GetUseTabs())
|
event.Check(self.GetCtrl().GetUseTabs())
|
||||||
@@ -210,7 +222,7 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
filename = document.GetFilename()
|
filename = document.GetFilename()
|
||||||
if filename:
|
if filename:
|
||||||
rootItem = treeCtrl.AddRoot(os.path.basename(filename))
|
rootItem = treeCtrl.AddRoot(os.path.basename(filename))
|
||||||
treeCtrl.SetDoSelectCallback(rootItem, self, None)
|
treeCtrl.SetDoSelectCallback(rootItem, self, (0,0))
|
||||||
else:
|
else:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
@@ -232,11 +244,13 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
if classLine:
|
if classLine:
|
||||||
indent = classLine.start(0)
|
indent = classLine.start(0)
|
||||||
itemStr = classLine.string[classLine.start(0):classLine.end(0)-1] # don't take the closing ':'
|
itemStr = classLine.string[classLine.start(0):classLine.end(0)-1] # don't take the closing ':'
|
||||||
|
itemStr = itemStr.replace("\n", "").replace("\r", "").replace(",\\", ",").replace(" ", "") # remove line continuations and spaces from outline view
|
||||||
else:
|
else:
|
||||||
defLine = defPat.search(line)
|
defLine = defPat.search(line)
|
||||||
if defLine:
|
if defLine:
|
||||||
indent = defLine.start(0)
|
indent = defLine.start(0)
|
||||||
itemStr = defLine.string[defLine.start(0):defLine.end(0)]
|
itemStr = defLine.string[defLine.start(0):defLine.end(0)]
|
||||||
|
itemStr = itemStr.replace("\n", "").replace("\r", "").replace(",\\", ",").replace(" ", "") # remove line continuations and spaces from outline view
|
||||||
|
|
||||||
if indent == 0:
|
if indent == 0:
|
||||||
parentItem = rootItem
|
parentItem = rootItem
|
||||||
@@ -467,6 +481,9 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
|
|
||||||
|
|
||||||
def OnUpdate(self, sender = None, hint = None):
|
def OnUpdate(self, sender = None, hint = None):
|
||||||
|
if wx.lib.docview.View.OnUpdate(self, sender, hint):
|
||||||
|
return
|
||||||
|
|
||||||
if hint == "ViewStuff":
|
if hint == "ViewStuff":
|
||||||
self.GetCtrl().SetViewDefaults()
|
self.GetCtrl().SetViewDefaults()
|
||||||
elif hint == "Font":
|
elif hint == "Font":
|
||||||
@@ -474,6 +491,7 @@ class CodeView(STCTextEditor.TextView):
|
|||||||
self.GetCtrl().SetFont(font)
|
self.GetCtrl().SetFont(font)
|
||||||
self.GetCtrl().SetFontColor(color)
|
self.GetCtrl().SetFontColor(color)
|
||||||
else:
|
else:
|
||||||
|
import DebuggerService
|
||||||
dbg_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
dbg_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
||||||
if dbg_service:
|
if dbg_service:
|
||||||
dbg_service.SetCurrentBreakpointMarkers(self)
|
dbg_service.SetCurrentBreakpointMarkers(self)
|
||||||
@@ -623,7 +641,7 @@ 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, clearTab=True):
|
||||||
STCTextEditor.TextCtrl.__init__(self, parent, id, style)
|
STCTextEditor.TextCtrl.__init__(self, parent, id, style)
|
||||||
|
|
||||||
self.UsePopUp(False)
|
self.UsePopUp(False)
|
||||||
@@ -635,7 +653,6 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
self.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL)
|
self.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL)
|
||||||
self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
|
self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
|
||||||
self.SetMarginSensitive(2, True)
|
self.SetMarginSensitive(2, True)
|
||||||
self.SetMarginWidth(2, 12)
|
|
||||||
|
|
||||||
self.SetMarginSensitive(1, False)
|
self.SetMarginSensitive(1, False)
|
||||||
self.SetMarginMask(1, 0x4)
|
self.SetMarginMask(1, 0x4)
|
||||||
@@ -657,7 +674,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
# Define the breakpoint marker
|
# Define the breakpoint marker
|
||||||
self.MarkerDefine(CodeCtrl.BREAKPOINT_MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, (255,0,0))
|
self.MarkerDefine(CodeCtrl.BREAKPOINT_MARKER_NUM, wx.stc.STC_MARK_CIRCLE, wx.BLACK, (255,0,0))
|
||||||
|
|
||||||
if _WINDOWS: # should test to see if menu item exists, if it does, add this workaround
|
if _WINDOWS and clearTab: # 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, self.GetId(), self.OnMarginClick)
|
wx.stc.EVT_STC_MARGINCLICK(self, self.GetId(), self.OnMarginClick)
|
||||||
@@ -693,7 +710,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
item = wx.MenuItem(menu, TOGGLEBREAKPOINT_ID, _("Toggle Breakpoint"))
|
item = wx.MenuItem(menu, TOGGLEBREAKPOINT_ID, _("Toggle Breakpoint"))
|
||||||
menu.AppendItem(item)
|
menu.AppendItem(item)
|
||||||
self.Bind(wx.EVT_MENU, self.OnPopToggleMarker, id=TOGGLEMARKER_ID)
|
self.Bind(wx.EVT_MENU, self.OnPopToggleMarker, id=TOGGLEMARKER_ID)
|
||||||
item = wx.MenuItem(menu, TOGGLEMARKER_ID, _("Toggle Marker"))
|
item = wx.MenuItem(menu, TOGGLEMARKER_ID, _("Toggle Bookmark"))
|
||||||
menu.AppendItem(item)
|
menu.AppendItem(item)
|
||||||
menu.AppendSeparator()
|
menu.AppendSeparator()
|
||||||
|
|
||||||
@@ -715,6 +732,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
|
|
||||||
def OnPopToggleBP(self, event):
|
def OnPopToggleBP(self, event):
|
||||||
""" Toggle break point on right click line, not current line """
|
""" Toggle break point on right click line, not current line """
|
||||||
|
import DebuggerService
|
||||||
wx.GetApp().GetService(DebuggerService.DebuggerService).OnToggleBreakpoint(event, line=self._rightClickLine)
|
wx.GetApp().GetService(DebuggerService.DebuggerService).OnToggleBreakpoint(event, line=self._rightClickLine)
|
||||||
|
|
||||||
|
|
||||||
@@ -859,6 +877,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
|||||||
|
|
||||||
elif evt.GetMargin() == 0:
|
elif evt.GetMargin() == 0:
|
||||||
#This is used to toggle breakpoints via the debugger service.
|
#This is used to toggle breakpoints via the debugger service.
|
||||||
|
import DebuggerService
|
||||||
db_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
db_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
||||||
if db_service:
|
if db_service:
|
||||||
db_service.OnToggleBreakpoint(evt, line=self.LineFromPosition(evt.GetPosition()))
|
db_service.OnToggleBreakpoint(evt, line=self.LineFromPosition(evt.GetPosition()))
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Created: 5/23/05
|
# Created: 5/23/05
|
||||||
# CVS-ID: $ID:$
|
# CVS-ID: $ID:$
|
||||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||||
# License: wxWindows License
|
# License: wxWindows License
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -17,27 +17,22 @@ import ProjectEditor
|
|||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import activegrid.util.xmlutils as xmlutils
|
import activegrid.util.xmlutils as xmlutils
|
||||||
|
|
||||||
_ = wx.GetTranslation
|
_ = wx.GetTranslation
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Constants
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
SPACE = 10
|
SPACE = 10
|
||||||
HALF_SPACE = 5
|
HALF_SPACE = 5
|
||||||
|
|
||||||
|
|
||||||
EXTENSIONS_CONFIG_STRING = "Extensions"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Redo extensions menu on OK, or provide alert that it won't happen until restart
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Classes
|
# Classes
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
class Extension:
|
class Extension:
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, menuItemName=None):
|
def __init__(self, menuItemName=None):
|
||||||
self.menuItemName = menuItemName
|
self.menuItemName = menuItemName
|
||||||
@@ -48,7 +43,7 @@ class Extension:
|
|||||||
self.commandPostArgs = ''
|
self.commandPostArgs = ''
|
||||||
self.fileExt = None
|
self.fileExt = None
|
||||||
self.opOnSelectedFile = True
|
self.opOnSelectedFile = True
|
||||||
|
|
||||||
|
|
||||||
class ExtensionService(wx.lib.pydocview.DocService):
|
class ExtensionService(wx.lib.pydocview.DocService):
|
||||||
|
|
||||||
@@ -60,8 +55,8 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
def __getExtensionKeyName(extensionName):
|
def __getExtensionKeyName(extensionName):
|
||||||
return "%s/%s" % (ExtensionService.EXTENSIONS_KEY, extensionName)
|
return "%s/%s" % (ExtensionService.EXTENSIONS_KEY, extensionName)
|
||||||
|
|
||||||
|
|
||||||
__getExtensionKeyName = staticmethod(__getExtensionKeyName)
|
__getExtensionKeyName = staticmethod(__getExtensionKeyName)
|
||||||
|
|
||||||
|
|
||||||
@@ -79,7 +74,7 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
|||||||
cont, value, index = config.GetNextEntry(index)
|
cont, value, index = config.GetNextEntry(index)
|
||||||
finally:
|
finally:
|
||||||
config.SetPath(path)
|
config.SetPath(path)
|
||||||
|
|
||||||
for extensionName in extensionNames:
|
for extensionName in extensionNames:
|
||||||
extensionData = config.Read(self.__getExtensionKeyName(extensionName))
|
extensionData = config.Read(self.__getExtensionKeyName(extensionName))
|
||||||
if extensionData:
|
if extensionData:
|
||||||
@@ -112,10 +107,10 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
|||||||
toolsMenu = menuBar.GetMenu(toolsMenuIndex)
|
toolsMenu = menuBar.GetMenu(toolsMenuIndex)
|
||||||
else:
|
else:
|
||||||
toolsMenu = wx.Menu()
|
toolsMenu = wx.Menu()
|
||||||
|
|
||||||
if self._extensions:
|
if self._extensions:
|
||||||
if toolsMenu.GetMenuItems():
|
if toolsMenu.GetMenuItems():
|
||||||
toolsMenu.AppendSeparator()
|
toolsMenu.AppendSeparator()
|
||||||
for ext in self._extensions:
|
for ext in self._extensions:
|
||||||
# Append a tool menu item for each extension
|
# Append a tool menu item for each extension
|
||||||
ext.id = wx.NewId()
|
ext.id = wx.NewId()
|
||||||
@@ -192,7 +187,7 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
|||||||
if extension.commandPostArgs:
|
if extension.commandPostArgs:
|
||||||
cmds.append(extension.commandPostArgs)
|
cmds.append(extension.commandPostArgs)
|
||||||
os.spawnv(os.P_NOWAIT, extension.command, cmds)
|
os.spawnv(os.P_NOWAIT, extension.command, cmds)
|
||||||
|
|
||||||
else:
|
else:
|
||||||
cmd = extension.command
|
cmd = extension.command
|
||||||
if extension.commandPreArgs:
|
if extension.commandPreArgs:
|
||||||
@@ -207,24 +202,24 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
|||||||
view.AddLines(line)
|
view.AddLines(line)
|
||||||
view.GetControl().EnsureCaretVisible()
|
view.GetControl().EnsureCaretVisible()
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
|
|
||||||
class ExtensionOptionsPanel(wx.Panel):
|
class ExtensionOptionsPanel(wx.Panel):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, id):
|
def __init__(self, parent, id):
|
||||||
wx.Panel.__init__(self, parent, id)
|
wx.Panel.__init__(self, parent, id)
|
||||||
|
|
||||||
extOptionsPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
|
extOptionsPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
extOptionsPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
extOptionsPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
|
||||||
extCtrlSizer = wx.BoxSizer(wx.VERTICAL)
|
extCtrlSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
extCtrlSizer.Add(wx.StaticText(self, -1, _("External Tools:")), 0, wx.BOTTOM, HALF_SPACE)
|
extCtrlSizer.Add(wx.StaticText(self, -1, _("External Tools:")), 0, wx.BOTTOM, HALF_SPACE)
|
||||||
self._extListBox = wx.ListBox(self, -1, size=(-1,160), style=wx.LB_SINGLE)
|
self._extListBox = wx.ListBox(self, -1, style=wx.LB_SINGLE)
|
||||||
self.Bind(wx.EVT_LISTBOX, self.OnListBoxSelect, self._extListBox)
|
self.Bind(wx.EVT_LISTBOX, self.OnListBoxSelect, self._extListBox)
|
||||||
extCtrlSizer.Add(self._extListBox, 1, wx.BOTTOM | wx.EXPAND, SPACE)
|
extCtrlSizer.Add(self._extListBox, 1, wx.BOTTOM | wx.EXPAND, SPACE)
|
||||||
buttonSizer = wx.GridSizer(cols=2, vgap=5, hgap=10)
|
buttonSizer = wx.GridSizer(cols=2, vgap=HALF_SPACE, hgap=HALF_SPACE)
|
||||||
self._moveUpButton = wx.Button(self, -1, _("Move Up"))
|
self._moveUpButton = wx.Button(self, -1, _("Move Up"))
|
||||||
self.Bind(wx.EVT_BUTTON, self.OnMoveUp, self._moveUpButton)
|
self.Bind(wx.EVT_BUTTON, self.OnMoveUp, self._moveUpButton)
|
||||||
buttonSizer.Add(self._moveUpButton, 1, wx.EXPAND)
|
buttonSizer.Add(self._moveUpButton, 1, wx.EXPAND)
|
||||||
@@ -243,21 +238,21 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
self._extDetailPanel = wx.Panel(self)
|
self._extDetailPanel = wx.Panel(self)
|
||||||
staticBox = wx.StaticBox(self, label=_("Selected External Tool"))
|
staticBox = wx.StaticBox(self, label=_("Selected External Tool"))
|
||||||
staticBoxSizer = wx.StaticBoxSizer(staticBox, wx.VERTICAL)
|
staticBoxSizer = wx.StaticBoxSizer(staticBox, wx.VERTICAL)
|
||||||
|
|
||||||
extDetailSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=3)
|
extDetailSizer = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
|
||||||
extDetailSizer.AddGrowableCol(1,1)
|
extDetailSizer.AddGrowableCol(1,1)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._menuItemNameTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._menuItemNameTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
extDetailSizer.Add(self._menuItemNameTextCtrl, 0, wx.EXPAND)
|
extDetailSizer.Add(self._menuItemNameTextCtrl, 0, wx.EXPAND)
|
||||||
self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
|
self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Description:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Description:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._menuItemDescTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._menuItemDescTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
extDetailSizer.Add(self._menuItemDescTextCtrl, 0, wx.EXPAND)
|
extDetailSizer.Add(self._menuItemDescTextCtrl, 0, wx.EXPAND)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Path:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Path:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._commandTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._commandTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
findFileButton = wx.Button(self._extDetailPanel, -1, _("Browse..."))
|
findFileButton = wx.Button(self._extDetailPanel, -1, _("Browse..."))
|
||||||
def OnBrowseButton(event):
|
def OnBrowseButton(event):
|
||||||
fileDlg = wx.FileDialog(self, _("Choose an Executable:"), style=wx.OPEN|wx.FILE_MUST_EXIST|wx.HIDE_READONLY|wx.CHANGE_DIR)
|
fileDlg = wx.FileDialog(self, _("Choose an Executable:"), style=wx.OPEN|wx.FILE_MUST_EXIST|wx.HIDE_READONLY|wx.CHANGE_DIR)
|
||||||
@@ -276,26 +271,26 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
hsizer.Add(findFileButton, 0, wx.LEFT, HALF_SPACE)
|
hsizer.Add(findFileButton, 0, wx.LEFT, HALF_SPACE)
|
||||||
extDetailSizer.Add(hsizer, 0, wx.EXPAND)
|
extDetailSizer.Add(hsizer, 0, wx.EXPAND)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Args:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Args:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._commandPreArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._commandPreArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
extDetailSizer.Add(self._commandPreArgsTextCtrl, 0, wx.EXPAND)
|
extDetailSizer.Add(self._commandPreArgsTextCtrl, 0, wx.EXPAND)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Args:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Args:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._commandPostArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._commandPostArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
extDetailSizer.Add(self._commandPostArgsTextCtrl, 0, wx.EXPAND)
|
extDetailSizer.Add(self._commandPostArgsTextCtrl, 0, wx.EXPAND)
|
||||||
|
|
||||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions:")))
|
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||||
self._fileExtTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
self._fileExtTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||||
self._fileExtTextCtrl.SetToolTipString(_("""For example: "txt, text" (comma separated) or "*" for all files"""))
|
self._fileExtTextCtrl.SetToolTipString(_("""For example: "txt, text" (comma separated) or "*" for all files"""))
|
||||||
extDetailSizer.Add(self._fileExtTextCtrl, 0, wx.EXPAND)
|
extDetailSizer.Add(self._fileExtTextCtrl, 0, wx.EXPAND)
|
||||||
|
|
||||||
self._selFileCtrl = wx.CheckBox(self._extDetailPanel, -1, _("Operate on Selected File"))
|
self._selFileCtrl = wx.CheckBox(self._extDetailPanel, -1, _("Operate on Selected File"))
|
||||||
extDetailSizer.Add(self._selFileCtrl)
|
extDetailSizer.Add(self._selFileCtrl, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, SPACE)
|
||||||
self._selFileCtrl.SetToolTipString(_("If focus is in the project, instead of operating on the project file, operate on the selected file."))
|
self._selFileCtrl.SetToolTipString(_("If focus is in the project, instead of operating on the project file, operate on the selected file."))
|
||||||
|
|
||||||
self._extDetailPanel.SetSizer(extDetailSizer)
|
self._extDetailPanel.SetSizer(extDetailSizer)
|
||||||
staticBoxSizer.Add(self._extDetailPanel, 1, wx.ALL|wx.EXPAND, SPACE)
|
staticBoxSizer.Add(self._extDetailPanel, 1, wx.ALL|wx.EXPAND, SPACE)
|
||||||
|
|
||||||
extOptionsPanelSizer.Add(staticBoxSizer, 1, wx.LEFT|wx.EXPAND, SPACE)
|
extOptionsPanelSizer.Add(staticBoxSizer, 1, wx.LEFT|wx.EXPAND, SPACE)
|
||||||
|
|
||||||
extOptionsPanelBorderSizer.Add(extOptionsPanelSizer, 1, wx.ALL|wx.EXPAND, SPACE)
|
extOptionsPanelBorderSizer.Add(extOptionsPanelSizer, 1, wx.ALL|wx.EXPAND, SPACE)
|
||||||
@@ -306,8 +301,8 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
self.OnListBoxSelect()
|
self.OnListBoxSelect()
|
||||||
|
|
||||||
self.Layout()
|
self.Layout()
|
||||||
|
|
||||||
parent.AddPage(self, _("External Tools"))
|
parent.AddPage(self, _("External Tools"))
|
||||||
|
|
||||||
|
|
||||||
def OnOK(self, optionsDialog):
|
def OnOK(self, optionsDialog):
|
||||||
@@ -323,7 +318,7 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
msgTitle,
|
msgTitle,
|
||||||
wx.OK | wx.ICON_INFORMATION,
|
wx.OK | wx.ICON_INFORMATION,
|
||||||
self.GetParent())
|
self.GetParent())
|
||||||
|
|
||||||
|
|
||||||
def PopulateItems(self):
|
def PopulateItems(self):
|
||||||
extensionsService = wx.GetApp().GetService(ExtensionService)
|
extensionsService = wx.GetApp().GetService(ExtensionService)
|
||||||
@@ -335,7 +330,7 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
self._currentItem = None
|
self._currentItem = None
|
||||||
self._currentItemIndex = -1
|
self._currentItemIndex = -1
|
||||||
return len(self._extensions)
|
return len(self._extensions)
|
||||||
|
|
||||||
|
|
||||||
def OnListBoxSelect(self, event=None):
|
def OnListBoxSelect(self, event=None):
|
||||||
self.SaveCurrentItem()
|
self.SaveCurrentItem()
|
||||||
@@ -370,7 +365,7 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
else:
|
else:
|
||||||
extension.fileExt = fileExt.split(',')
|
extension.fileExt = fileExt.split(',')
|
||||||
extension.opOnSelectedFile = self._selFileCtrl.GetValue()
|
extension.opOnSelectedFile = self._selFileCtrl.GetValue()
|
||||||
|
|
||||||
|
|
||||||
def LoadItem(self, extension):
|
def LoadItem(self, extension):
|
||||||
if extension:
|
if extension:
|
||||||
@@ -401,8 +396,8 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
self._fileExtTextCtrl.SetValue('')
|
self._fileExtTextCtrl.SetValue('')
|
||||||
self._selFileCtrl.SetValue(True)
|
self._selFileCtrl.SetValue(True)
|
||||||
self._extDetailPanel.Enable(False)
|
self._extDetailPanel.Enable(False)
|
||||||
|
|
||||||
|
|
||||||
def OnAdd(self, event):
|
def OnAdd(self, event):
|
||||||
self.SaveCurrentItem()
|
self.SaveCurrentItem()
|
||||||
name = _("Untitled")
|
name = _("Untitled")
|
||||||
@@ -417,11 +412,11 @@ class ExtensionOptionsPanel(wx.Panel):
|
|||||||
self.OnListBoxSelect()
|
self.OnListBoxSelect()
|
||||||
self._menuItemNameTextCtrl.SetFocus()
|
self._menuItemNameTextCtrl.SetFocus()
|
||||||
self._menuItemNameTextCtrl.SetSelection(-1, -1)
|
self._menuItemNameTextCtrl.SetSelection(-1, -1)
|
||||||
|
|
||||||
|
|
||||||
def OnDelete(self, event):
|
def OnDelete(self, event):
|
||||||
self._extListBox.Delete(self._currentItemIndex)
|
self._extListBox.Delete(self._currentItemIndex)
|
||||||
self._extensions.remove(self._currentItem)
|
self._extensions.remove(self._currentItem)
|
||||||
self._currentItemIndex = min(self._currentItemIndex, self._extListBox.GetCount() - 1)
|
self._currentItemIndex = min(self._currentItemIndex, self._extListBox.GetCount() - 1)
|
||||||
if self._currentItemIndex > -1:
|
if self._currentItemIndex > -1:
|
||||||
self._extListBox.SetSelection(self._currentItemIndex)
|
self._extListBox.SetSelection(self._currentItemIndex)
|
||||||
|
@@ -27,6 +27,7 @@ _ = wx.GetTranslation
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
FILENAME_MARKER = _("Found in file: ")
|
FILENAME_MARKER = _("Found in file: ")
|
||||||
PROJECT_MARKER = _("Searching project: ")
|
PROJECT_MARKER = _("Searching project: ")
|
||||||
|
FILE_MARKER = _("Searching file: ")
|
||||||
FIND_MATCHDIR = "FindMatchDir"
|
FIND_MATCHDIR = "FindMatchDir"
|
||||||
FIND_MATCHDIRSUBFOLDERS = "FindMatchDirSubfolders"
|
FIND_MATCHDIRSUBFOLDERS = "FindMatchDirSubfolders"
|
||||||
|
|
||||||
@@ -39,6 +40,7 @@ class FindInDirService(FindService.FindService):
|
|||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Constants
|
# Constants
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
FINDFILE_ID = wx.NewId() # for bringing up Find in File dialog box
|
||||||
FINDALL_ID = wx.NewId() # for bringing up Find All dialog box
|
FINDALL_ID = wx.NewId() # for bringing up Find All dialog box
|
||||||
FINDDIR_ID = wx.NewId() # for bringing up Find Dir dialog box
|
FINDDIR_ID = wx.NewId() # for bringing up Find Dir dialog box
|
||||||
|
|
||||||
@@ -47,29 +49,39 @@ class FindInDirService(FindService.FindService):
|
|||||||
FindService.FindService.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
|
FindService.FindService.InstallControls(self, frame, menuBar, toolBar, statusBar, document)
|
||||||
|
|
||||||
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
||||||
|
wx.EVT_MENU(frame, FindInDirService.FINDFILE_ID, self.ProcessEvent)
|
||||||
|
wx.EVT_UPDATE_UI(frame, FindInDirService.FINDFILE_ID, self.ProcessUpdateUIEvent)
|
||||||
|
editMenu.Append(FindInDirService.FINDFILE_ID, _("Find in File...\tCtrl+Shift+F"), _("Searches for the specified text in the current file"))
|
||||||
wx.EVT_MENU(frame, FindInDirService.FINDALL_ID, self.ProcessEvent)
|
wx.EVT_MENU(frame, FindInDirService.FINDALL_ID, self.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, FindInDirService.FINDALL_ID, self.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, FindInDirService.FINDALL_ID, self.ProcessUpdateUIEvent)
|
||||||
editMenu.Append(FindInDirService.FINDALL_ID, _("Find in Project...\tCtrl+Shift+F"), _("Searches for the specified text in all the files in the project"))
|
editMenu.Append(FindInDirService.FINDALL_ID, _("Find in Project...\tCtrl+Shift+P"), _("Searches for the specified text in all the files in the project"))
|
||||||
wx.EVT_MENU(frame, FindInDirService.FINDDIR_ID, self.ProcessEvent)
|
wx.EVT_MENU(frame, FindInDirService.FINDDIR_ID, self.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, FindInDirService.FINDDIR_ID, self.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, FindInDirService.FINDDIR_ID, self.ProcessUpdateUIEvent)
|
||||||
editMenu.Append(FindInDirService.FINDDIR_ID, _("Find in Directory..."), _("Searches for the specified text in all the files in the directory"))
|
editMenu.Append(FindInDirService.FINDDIR_ID, _("Find in Directory...\tCtrl+Shift+D"), _("Searches for the specified text in all the files in the directory"))
|
||||||
|
|
||||||
|
|
||||||
def ProcessEvent(self, event):
|
def ProcessEvent(self, event):
|
||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
if id == FindInDirService.FINDALL_ID:
|
if id == FindInDirService.FINDFILE_ID:
|
||||||
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
self.ShowFindAllDialog(view.GetCtrl().GetSelectedText())
|
self.ShowFindInFileDialog(view.GetCtrl().GetSelectedText())
|
||||||
else:
|
else:
|
||||||
self.ShowFindAllDialog()
|
self.ShowFindInFileDialog()
|
||||||
|
return True
|
||||||
|
elif id == FindInDirService.FINDALL_ID:
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
|
self.ShowFindInProjectDialog(view.GetCtrl().GetSelectedText())
|
||||||
|
else:
|
||||||
|
self.ShowFindInProjectDialog()
|
||||||
return True
|
return True
|
||||||
elif id == FindInDirService.FINDDIR_ID:
|
elif id == FindInDirService.FINDDIR_ID:
|
||||||
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
self.ShowFindDirDialog(view.GetCtrl().GetSelectedText())
|
self.ShowFindInDirDialog(view.GetCtrl().GetSelectedText())
|
||||||
else:
|
else:
|
||||||
self.ShowFindDirDialog()
|
self.ShowFindInDirDialog()
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return FindService.FindService.ProcessEvent(self, event)
|
return FindService.FindService.ProcessEvent(self, event)
|
||||||
@@ -77,7 +89,14 @@ class FindInDirService(FindService.FindService):
|
|||||||
|
|
||||||
def ProcessUpdateUIEvent(self, event):
|
def ProcessUpdateUIEvent(self, event):
|
||||||
id = event.GetId()
|
id = event.GetId()
|
||||||
if id == FindInDirService.FINDALL_ID:
|
if id == FindInDirService.FINDFILE_ID:
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if view and view.GetDocument() and not isinstance(view.GetDocument(), ProjectEditor.ProjectDocument): # don't search project model
|
||||||
|
event.Enable(True)
|
||||||
|
else:
|
||||||
|
event.Enable(False)
|
||||||
|
return True
|
||||||
|
elif id == FindInDirService.FINDALL_ID:
|
||||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||||
if projectService.GetFilesFromCurrentProject():
|
if projectService.GetFilesFromCurrentProject():
|
||||||
event.Enable(True)
|
event.Enable(True)
|
||||||
@@ -90,7 +109,7 @@ class FindInDirService(FindService.FindService):
|
|||||||
return FindService.FindService.ProcessUpdateUIEvent(self, event)
|
return FindService.FindService.ProcessUpdateUIEvent(self, event)
|
||||||
|
|
||||||
|
|
||||||
def ShowFindDirDialog(self, findString=None):
|
def ShowFindInDirDialog(self, findString=None):
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Directory"), size= (320,200))
|
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Directory"), size= (320,200))
|
||||||
@@ -105,7 +124,7 @@ class FindInDirService(FindService.FindService):
|
|||||||
findDirButton = wx.Button(frame, -1, _("Browse..."))
|
findDirButton = wx.Button(frame, -1, _("Browse..."))
|
||||||
lineSizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
lineSizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||||
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
|
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
|
||||||
|
|
||||||
def OnBrowseButton(event):
|
def OnBrowseButton(event):
|
||||||
dlg = wx.DirDialog(frame, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
|
dlg = wx.DirDialog(frame, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
|
||||||
dir = dirCtrl.GetValue()
|
dir = dirCtrl.GetValue()
|
||||||
@@ -126,10 +145,10 @@ class FindInDirService(FindService.FindService):
|
|||||||
lineSizer = wx.BoxSizer(wx.VERTICAL) # let the line expand horizontally without vertical expansion
|
lineSizer = wx.BoxSizer(wx.VERTICAL) # let the line expand horizontally without vertical expansion
|
||||||
lineSizer.Add(wx.StaticLine(frame, -1, size = (10,-1)), 0, flag=wx.EXPAND)
|
lineSizer.Add(wx.StaticLine(frame, -1, size = (10,-1)), 0, flag=wx.EXPAND)
|
||||||
contentSizer.Add(lineSizer, flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM, border=HALF_SPACE)
|
contentSizer.Add(lineSizer, flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM, border=HALF_SPACE)
|
||||||
|
|
||||||
if wx.Platform == "__WXMAC__":
|
if wx.Platform == "__WXMAC__":
|
||||||
contentSizer.Add((-1, 10), 0, wx.EXPAND)
|
contentSizer.Add((-1, 10), 0, wx.EXPAND)
|
||||||
|
|
||||||
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
|
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
|
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
|
||||||
if not findString:
|
if not findString:
|
||||||
@@ -192,13 +211,13 @@ class FindInDirService(FindService.FindService):
|
|||||||
status = frame.ShowModal()
|
status = frame.ShowModal()
|
||||||
else:
|
else:
|
||||||
passedCheck = True
|
passedCheck = True
|
||||||
|
|
||||||
|
|
||||||
# save user choice state for this and other Find Dialog Boxes
|
# save user choice state for this and other Find Dialog Boxes
|
||||||
dirString = dirCtrl.GetValue()
|
dirString = dirCtrl.GetValue()
|
||||||
searchSubfolders = subfolderCtrl.IsChecked()
|
searchSubfolders = subfolderCtrl.IsChecked()
|
||||||
self.SaveFindDirConfig(dirString, searchSubfolders)
|
self.SaveFindInDirConfig(dirString, searchSubfolders)
|
||||||
|
|
||||||
findString = findCtrl.GetValue()
|
findString = findCtrl.GetValue()
|
||||||
matchCase = matchCaseCtrl.IsChecked()
|
matchCase = matchCaseCtrl.IsChecked()
|
||||||
wholeWord = wholeWordCtrl.IsChecked()
|
wholeWord = wholeWordCtrl.IsChecked()
|
||||||
@@ -206,52 +225,23 @@ class FindInDirService(FindService.FindService):
|
|||||||
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
||||||
|
|
||||||
frame.Destroy()
|
frame.Destroy()
|
||||||
if status == wx.ID_OK:
|
if status == wx.ID_OK:
|
||||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||||
messageService.ShowWindow()
|
messageService.ShowWindow()
|
||||||
|
|
||||||
view = messageService.GetView()
|
view = messageService.GetView()
|
||||||
if view:
|
if view:
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
view.ClearLines()
|
|
||||||
view.SetCallback(self.OnJumpToFoundLine)
|
|
||||||
|
|
||||||
view.AddLines(_("Searching for '%s' in '%s'\n\n") % (findString, dirString))
|
|
||||||
|
|
||||||
if os.path.isfile(dirString):
|
try:
|
||||||
try:
|
view.ClearLines()
|
||||||
docFile = file(dirString, 'r')
|
view.SetCallback(self.OnJumpToFoundLine)
|
||||||
lineNum = 1
|
|
||||||
needToDisplayFilename = True
|
view.AddLines(_("Searching for '%s' in '%s'\n\n") % (findString, dirString))
|
||||||
line = docFile.readline()
|
|
||||||
while line:
|
if os.path.isfile(dirString):
|
||||||
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
try:
|
||||||
if count != -1:
|
docFile = file(dirString, 'r')
|
||||||
if needToDisplayFilename:
|
|
||||||
view.AddLines(FILENAME_MARKER + dirString + "\n")
|
|
||||||
needToDisplayFilename = False
|
|
||||||
line = repr(lineNum).zfill(4) + ":" + line
|
|
||||||
view.AddLines(line)
|
|
||||||
line = docFile.readline()
|
|
||||||
lineNum += 1
|
|
||||||
if not needToDisplayFilename:
|
|
||||||
view.AddLines("\n")
|
|
||||||
except IOError, (code, message):
|
|
||||||
print _("Warning, unable to read file: '%s'. %s") % (dirString, message)
|
|
||||||
else:
|
|
||||||
# do search in files on disk
|
|
||||||
for root, dirs, files in os.walk(dirString):
|
|
||||||
if not searchSubfolders and root != dirString:
|
|
||||||
break
|
|
||||||
|
|
||||||
for name in files:
|
|
||||||
filename = os.path.join(root, name)
|
|
||||||
try:
|
|
||||||
docFile = file(filename, 'r')
|
|
||||||
except IOError, (code, message):
|
|
||||||
print _("Warning, unable to read file: '%s'. %s") % (filename, message)
|
|
||||||
continue
|
|
||||||
|
|
||||||
lineNum = 1
|
lineNum = 1
|
||||||
needToDisplayFilename = True
|
needToDisplayFilename = True
|
||||||
line = docFile.readline()
|
line = docFile.readline()
|
||||||
@@ -259,7 +249,7 @@ class FindInDirService(FindService.FindService):
|
|||||||
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
||||||
if count != -1:
|
if count != -1:
|
||||||
if needToDisplayFilename:
|
if needToDisplayFilename:
|
||||||
view.AddLines(FILENAME_MARKER + filename + "\n")
|
view.AddLines(FILENAME_MARKER + dirString + "\n")
|
||||||
needToDisplayFilename = False
|
needToDisplayFilename = False
|
||||||
line = repr(lineNum).zfill(4) + ":" + line
|
line = repr(lineNum).zfill(4) + ":" + line
|
||||||
view.AddLines(line)
|
view.AddLines(line)
|
||||||
@@ -267,27 +257,186 @@ class FindInDirService(FindService.FindService):
|
|||||||
lineNum += 1
|
lineNum += 1
|
||||||
if not needToDisplayFilename:
|
if not needToDisplayFilename:
|
||||||
view.AddLines("\n")
|
view.AddLines("\n")
|
||||||
|
except IOError, (code, message):
|
||||||
view.AddLines(_("Search completed."))
|
print _("Warning, unable to read file: '%s'. %s") % (dirString, message)
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
else:
|
||||||
|
# do search in files on disk
|
||||||
|
for root, dirs, files in os.walk(dirString):
|
||||||
|
if not searchSubfolders and root != dirString:
|
||||||
|
break
|
||||||
|
|
||||||
|
for name in files:
|
||||||
|
filename = os.path.join(root, name)
|
||||||
|
try:
|
||||||
|
docFile = file(filename, 'r')
|
||||||
|
except IOError, (code, message):
|
||||||
|
print _("Warning, unable to read file: '%s'. %s") % (filename, message)
|
||||||
|
continue
|
||||||
|
|
||||||
|
lineNum = 1
|
||||||
|
needToDisplayFilename = True
|
||||||
|
line = docFile.readline()
|
||||||
|
while line:
|
||||||
|
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
||||||
|
if count != -1:
|
||||||
|
if needToDisplayFilename:
|
||||||
|
view.AddLines(FILENAME_MARKER + filename + "\n")
|
||||||
|
needToDisplayFilename = False
|
||||||
|
line = repr(lineNum).zfill(4) + ":" + line
|
||||||
|
view.AddLines(line)
|
||||||
|
line = docFile.readline()
|
||||||
|
lineNum += 1
|
||||||
|
if not needToDisplayFilename:
|
||||||
|
view.AddLines("\n")
|
||||||
|
|
||||||
|
view.AddLines(_("Search completed."))
|
||||||
|
|
||||||
|
finally:
|
||||||
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def SaveFindDirConfig(self, dirString, searchSubfolders):
|
|
||||||
|
def SaveFindInDirConfig(self, dirString, searchSubfolders):
|
||||||
""" Save search dir patterns and flags to registry.
|
""" Save search dir patterns and flags to registry.
|
||||||
|
|
||||||
dirString = search directory
|
dirString = search directory
|
||||||
searchSubfolders = Search subfolders
|
searchSubfolders = Search subfolders
|
||||||
"""
|
"""
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
config.Write(FIND_MATCHDIR, dirString)
|
config.Write(FIND_MATCHDIR, dirString)
|
||||||
config.WriteInt(FIND_MATCHDIRSUBFOLDERS, searchSubfolders)
|
config.WriteInt(FIND_MATCHDIRSUBFOLDERS, searchSubfolders)
|
||||||
|
|
||||||
|
|
||||||
def ShowFindAllDialog(self, findString=None):
|
|
||||||
|
def DoFindIn(self, findString, matchCase, wholeWord, regExpr, currFileOnly=False, jumpToFound=False):
|
||||||
|
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||||
|
if not messageService:
|
||||||
|
return
|
||||||
|
|
||||||
|
messageService.ShowWindow()
|
||||||
|
|
||||||
|
view = messageService.GetView()
|
||||||
|
if not view:
|
||||||
|
return
|
||||||
|
|
||||||
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
|
|
||||||
|
try:
|
||||||
|
#Switch to messages tab.
|
||||||
|
view.GetControl().GetParent().SetSelection(0)
|
||||||
|
view.ClearLines()
|
||||||
|
view.SetCallback(self.OnJumpToFoundLine)
|
||||||
|
|
||||||
|
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||||
|
|
||||||
|
if wx.GetApp().GetDocumentManager().GetCurrentView():
|
||||||
|
currDoc = wx.GetApp().GetDocumentManager().GetCurrentView().GetDocument()
|
||||||
|
else:
|
||||||
|
currDoc = None
|
||||||
|
if currFileOnly:
|
||||||
|
if currDoc:
|
||||||
|
projectFilenames = [currDoc.GetFilename()]
|
||||||
|
view.AddLines(FILE_MARKER + currDoc.GetFilename() + "\n\n")
|
||||||
|
else:
|
||||||
|
projectFilenames = []
|
||||||
|
else:
|
||||||
|
projectFilenames = projectService.GetFilesFromCurrentProject()
|
||||||
|
|
||||||
|
projView = projectService.GetView()
|
||||||
|
if projView:
|
||||||
|
projName = wx.lib.docview.FileNameFromPath(projView.GetDocument().GetFilename())
|
||||||
|
view.AddLines(PROJECT_MARKER + projName + "\n\n")
|
||||||
|
|
||||||
|
firstDef = -1
|
||||||
|
|
||||||
|
# do search in open files first, open files may have been modified and different from disk because it hasn't been saved
|
||||||
|
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||||
|
openDocsInProject = filter(lambda openDoc: openDoc.GetFilename() in projectFilenames, openDocs)
|
||||||
|
if currDoc and currDoc in openDocsInProject:
|
||||||
|
# make sure current document is searched first.
|
||||||
|
openDocsInProject.remove(currDoc)
|
||||||
|
openDocsInProject.insert(0, currDoc)
|
||||||
|
for openDoc in openDocsInProject:
|
||||||
|
if isinstance(openDoc, ProjectEditor.ProjectDocument): # don't search project model
|
||||||
|
continue
|
||||||
|
|
||||||
|
openDocView = openDoc.GetFirstView()
|
||||||
|
# some views don't have a in memory text object to search through such as the PM and the DM
|
||||||
|
# even if they do have a non-text searchable object, how do we display it in the message window?
|
||||||
|
if not hasattr(openDocView, "GetValue"):
|
||||||
|
continue
|
||||||
|
text = openDocView.GetValue()
|
||||||
|
|
||||||
|
lineNum = 1
|
||||||
|
needToDisplayFilename = True
|
||||||
|
start = 0
|
||||||
|
end = 0
|
||||||
|
count = 0
|
||||||
|
while count != -1:
|
||||||
|
count, foundStart, foundEnd, newText = self.DoFind(findString, None, text, start, end, True, matchCase, wholeWord, regExpr)
|
||||||
|
if count != -1:
|
||||||
|
if needToDisplayFilename:
|
||||||
|
view.AddLines(FILENAME_MARKER + openDoc.GetFilename() + "\n")
|
||||||
|
needToDisplayFilename = False
|
||||||
|
|
||||||
|
lineNum = openDocView.LineFromPosition(foundStart)
|
||||||
|
line = repr(lineNum).zfill(4) + ":" + openDocView.GetLine(lineNum)
|
||||||
|
view.AddLines(line)
|
||||||
|
if firstDef == -1:
|
||||||
|
firstDef = view.GetControl().GetCurrentLine() - 1
|
||||||
|
|
||||||
|
start = text.find("\n", foundStart)
|
||||||
|
if start == -1:
|
||||||
|
break
|
||||||
|
end = start
|
||||||
|
if not needToDisplayFilename:
|
||||||
|
view.AddLines("\n")
|
||||||
|
wx.GetApp().Yield(True)
|
||||||
|
openDocNames = map(lambda openDoc: openDoc.GetFilename(), openDocs)
|
||||||
|
|
||||||
|
# do search in closed files, skipping the open ones we already searched
|
||||||
|
filenames = filter(lambda filename: filename not in openDocNames, projectFilenames)
|
||||||
|
for filename in filenames:
|
||||||
|
try:
|
||||||
|
docFile = file(filename, 'r')
|
||||||
|
except IOError, (code, message):
|
||||||
|
print _("Warning, unable to read file: '%s'. %s") % (filename, message)
|
||||||
|
continue
|
||||||
|
|
||||||
|
lineNum = 1
|
||||||
|
needToDisplayFilename = True
|
||||||
|
line = docFile.readline()
|
||||||
|
while line:
|
||||||
|
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
||||||
|
if count != -1:
|
||||||
|
if needToDisplayFilename:
|
||||||
|
view.AddLines(FILENAME_MARKER + filename + "\n")
|
||||||
|
needToDisplayFilename = False
|
||||||
|
line = repr(lineNum).zfill(4) + ":" + line
|
||||||
|
view.AddLines(line)
|
||||||
|
if firstDef == -1:
|
||||||
|
firstDef = view.GetControl().GetCurrentLine() - 1
|
||||||
|
line = docFile.readline()
|
||||||
|
lineNum += 1
|
||||||
|
if not needToDisplayFilename:
|
||||||
|
view.AddLines("\n")
|
||||||
|
wx.GetApp().Yield(True)
|
||||||
|
|
||||||
|
view.AddLines(_("Search for '%s' completed.") % findString)
|
||||||
|
|
||||||
|
if jumpToFound:
|
||||||
|
self.OnJumpToFoundLine(event=None, defLineNum=firstDef)
|
||||||
|
|
||||||
|
finally:
|
||||||
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||||
|
|
||||||
|
def FindInProject(self, findString):
|
||||||
|
self.DoFindIn(findString, matchCase=True, wholeWord=True, regExpr=True, jumpToFound=True)
|
||||||
|
|
||||||
|
|
||||||
|
def ShowFindInProjectDialog(self, findString=None):
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Project"), size= (320,200))
|
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Project"), size= (320,200))
|
||||||
@@ -336,97 +485,80 @@ class FindInDirService(FindService.FindService):
|
|||||||
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
||||||
|
|
||||||
frame.Destroy()
|
frame.Destroy()
|
||||||
|
|
||||||
if status == wx.ID_OK:
|
if status == wx.ID_OK:
|
||||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
self.DoFindIn(findString, matchCase, wholeWord, regExpr)
|
||||||
messageService.ShowWindow()
|
|
||||||
|
|
||||||
view = messageService.GetView()
|
|
||||||
if view:
|
|
||||||
view.ClearLines()
|
|
||||||
view.SetCallback(self.OnJumpToFoundLine)
|
|
||||||
|
|
||||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
|
||||||
projectFilenames = projectService.GetFilesFromCurrentProject()
|
|
||||||
|
|
||||||
projView = projectService.GetView()
|
|
||||||
if projView:
|
|
||||||
projName = wx.lib.docview.FileNameFromPath(projView.GetDocument().GetFilename())
|
|
||||||
view.AddLines(PROJECT_MARKER + projName + "\n\n")
|
|
||||||
|
|
||||||
# do search in open files first, open files may have been modified and different from disk because it hasn't been saved
|
|
||||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
|
||||||
openDocsInProject = filter(lambda openDoc: openDoc.GetFilename() in projectFilenames, openDocs)
|
|
||||||
for openDoc in openDocsInProject:
|
|
||||||
if isinstance(openDoc, ProjectEditor.ProjectDocument): # don't search project model
|
|
||||||
continue
|
|
||||||
|
|
||||||
openDocView = openDoc.GetFirstView()
|
|
||||||
# some views don't have a in memory text object to search through such as the PM and the DM
|
|
||||||
# even if they do have a non-text searchable object, how do we display it in the message window?
|
|
||||||
if not hasattr(openDocView, "GetValue"):
|
|
||||||
continue
|
|
||||||
text = openDocView.GetValue()
|
|
||||||
|
|
||||||
lineNum = 1
|
|
||||||
needToDisplayFilename = True
|
|
||||||
start = 0
|
|
||||||
end = 0
|
|
||||||
count = 0
|
|
||||||
while count != -1:
|
|
||||||
count, foundStart, foundEnd, newText = self.DoFind(findString, None, text, start, end, True, matchCase, wholeWord, regExpr)
|
|
||||||
if count != -1:
|
|
||||||
if needToDisplayFilename:
|
|
||||||
view.AddLines(FILENAME_MARKER + openDoc.GetFilename() + "\n")
|
|
||||||
needToDisplayFilename = False
|
|
||||||
|
|
||||||
lineNum = openDocView.LineFromPosition(foundStart)
|
|
||||||
line = repr(lineNum).zfill(4) + ":" + openDocView.GetLine(lineNum)
|
|
||||||
view.AddLines(line)
|
|
||||||
|
|
||||||
start = text.find("\n", foundStart)
|
|
||||||
if start == -1:
|
|
||||||
break
|
|
||||||
end = start
|
|
||||||
if not needToDisplayFilename:
|
|
||||||
view.AddLines("\n")
|
|
||||||
openDocNames = map(lambda openDoc: openDoc.GetFilename(), openDocs)
|
|
||||||
|
|
||||||
# do search in closed files, skipping the open ones we already searched
|
|
||||||
filenames = filter(lambda filename: filename not in openDocNames, projectFilenames)
|
|
||||||
for filename in filenames:
|
|
||||||
try:
|
|
||||||
docFile = file(filename, 'r')
|
|
||||||
except IOError, (code, message):
|
|
||||||
print _("Warning, unable to read file: '%s'. %s") % (filename, message)
|
|
||||||
continue
|
|
||||||
|
|
||||||
lineNum = 1
|
|
||||||
needToDisplayFilename = True
|
|
||||||
line = docFile.readline()
|
|
||||||
while line:
|
|
||||||
count, foundStart, foundEnd, newText = self.DoFind(findString, None, line, 0, 0, True, matchCase, wholeWord, regExpr)
|
|
||||||
if count != -1:
|
|
||||||
if needToDisplayFilename:
|
|
||||||
view.AddLines(FILENAME_MARKER + filename + "\n")
|
|
||||||
needToDisplayFilename = False
|
|
||||||
line = repr(lineNum).zfill(4) + ":" + line
|
|
||||||
view.AddLines(line)
|
|
||||||
line = docFile.readline()
|
|
||||||
lineNum += 1
|
|
||||||
if not needToDisplayFilename:
|
|
||||||
view.AddLines("\n")
|
|
||||||
|
|
||||||
view.AddLines(_("Search for '%s' completed.") % findString)
|
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def OnJumpToFoundLine(self, event):
|
def ShowFindInFileDialog(self, findString=None):
|
||||||
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
|
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in File"), size= (320,200))
|
||||||
|
borderSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
|
||||||
|
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
|
||||||
|
if not findString:
|
||||||
|
findString = config.Read(FindService.FIND_MATCHPATTERN, "")
|
||||||
|
findCtrl = wx.TextCtrl(frame, -1, findString, size=(200,-1))
|
||||||
|
lineSizer.Add(findCtrl, 0, wx.LEFT, HALF_SPACE)
|
||||||
|
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
|
||||||
|
wholeWordCtrl = wx.CheckBox(frame, -1, _("Match whole word only"))
|
||||||
|
wholeWordCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHWHOLEWORD, False))
|
||||||
|
matchCaseCtrl = wx.CheckBox(frame, -1, _("Match case"))
|
||||||
|
matchCaseCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHCASE, False))
|
||||||
|
regExprCtrl = wx.CheckBox(frame, -1, _("Regular expression"))
|
||||||
|
regExprCtrl.SetValue(config.ReadInt(FindService.FIND_MATCHREGEXPR, False))
|
||||||
|
contentSizer.Add(wholeWordCtrl, 0, wx.BOTTOM, SPACE)
|
||||||
|
contentSizer.Add(matchCaseCtrl, 0, wx.BOTTOM, SPACE)
|
||||||
|
contentSizer.Add(regExprCtrl, 0, wx.BOTTOM, SPACE)
|
||||||
|
borderSizer.Add(contentSizer, 0, wx.TOP | wx.BOTTOM | wx.LEFT, SPACE)
|
||||||
|
|
||||||
|
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
findBtn = wx.Button(frame, wx.ID_OK, _("Find"))
|
||||||
|
findBtn.SetDefault()
|
||||||
|
BTM_SPACE = HALF_SPACE
|
||||||
|
if wx.Platform == "__WXMAC__":
|
||||||
|
BTM_SPACE = SPACE
|
||||||
|
buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||||
|
buttonSizer.Add(wx.Button(frame, wx.ID_CANCEL), 0)
|
||||||
|
borderSizer.Add(buttonSizer, 0, wx.ALL, SPACE)
|
||||||
|
|
||||||
|
frame.SetSizer(borderSizer)
|
||||||
|
frame.Fit()
|
||||||
|
|
||||||
|
frame.CenterOnParent()
|
||||||
|
status = frame.ShowModal()
|
||||||
|
|
||||||
|
# save user choice state for this and other Find Dialog Boxes
|
||||||
|
findString = findCtrl.GetValue()
|
||||||
|
matchCase = matchCaseCtrl.IsChecked()
|
||||||
|
wholeWord = wholeWordCtrl.IsChecked()
|
||||||
|
regExpr = regExprCtrl.IsChecked()
|
||||||
|
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
||||||
|
|
||||||
|
frame.Destroy()
|
||||||
|
|
||||||
|
if status == wx.ID_OK:
|
||||||
|
self.DoFindIn(findString, matchCase, wholeWord, regExpr, currFileOnly=True)
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def OnJumpToFoundLine(self, event=None, defLineNum=-1):
|
||||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||||
lineText, pos = messageService.GetView().GetCurrLine()
|
if defLineNum == -1:
|
||||||
if lineText == "\n" or lineText.find(FILENAME_MARKER) != -1 or lineText.find(PROJECT_MARKER) != -1:
|
lineText, pos = messageService.GetView().GetCurrLine()
|
||||||
|
else:
|
||||||
|
lineText = messageService.GetView().GetControl().GetLine(defLineNum)
|
||||||
|
pos = 0
|
||||||
|
|
||||||
|
if lineText == "\n" or lineText.find(FILENAME_MARKER) != -1 or lineText.find(PROJECT_MARKER) != -1 or lineText.find(FILE_MARKER) != -1:
|
||||||
return
|
return
|
||||||
lineEnd = lineText.find(":")
|
lineEnd = lineText.find(":")
|
||||||
if lineEnd == -1:
|
if lineEnd == -1:
|
||||||
@@ -435,7 +567,10 @@ class FindInDirService(FindService.FindService):
|
|||||||
lineNum = int(lineText[0:lineEnd])
|
lineNum = int(lineText[0:lineEnd])
|
||||||
|
|
||||||
text = messageService.GetView().GetText()
|
text = messageService.GetView().GetText()
|
||||||
curPos = messageService.GetView().GetCurrentPos()
|
if defLineNum == -1:
|
||||||
|
curPos = messageService.GetView().GetCurrentPos()
|
||||||
|
else:
|
||||||
|
curPos = messageService.GetView().GetControl().GetLineEndPosition(defLineNum)
|
||||||
|
|
||||||
startPos = text.rfind(FILENAME_MARKER, 0, curPos)
|
startPos = text.rfind(FILENAME_MARKER, 0, curPos)
|
||||||
endPos = text.find("\n", startPos)
|
endPos = text.find("\n", startPos)
|
||||||
@@ -464,5 +599,3 @@ class FindInDirService(FindService.FindService):
|
|||||||
# time, we don't see the selection, it is scrolled off screen
|
# time, we don't see the selection, it is scrolled off screen
|
||||||
foundView.SetSelection(startPos - 1 + len(lineText[lineEnd:].rstrip("\n")), startPos)
|
foundView.SetSelection(startPos - 1 + len(lineText[lineEnd:].rstrip("\n")), startPos)
|
||||||
wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(foundView, position=startPos)
|
wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(foundView, position=startPos)
|
||||||
|
|
||||||
|
|
||||||
|
@@ -119,7 +119,7 @@ class HtmlCtrl(CodeEditor.CodeCtrl):
|
|||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self):
|
def SetViewDefaults(self):
|
||||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = True, hasTabs = True)
|
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetFontAndColorFromConfig(self):
|
def GetFontAndColorFromConfig(self):
|
||||||
@@ -156,7 +156,7 @@ class HtmlCtrl(CodeEditor.CodeCtrl):
|
|||||||
class HtmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
class HtmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||||
|
|
||||||
def __init__(self, parent, id):
|
def __init__(self, parent, id):
|
||||||
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Html", label = "HTML", hasWordWrap = True, hasTabs = True)
|
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Html", label = "HTML", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetIcon(self):
|
def GetIcon(self):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -36,16 +36,16 @@ class MarkerService(wx.lib.pydocview.DocService):
|
|||||||
|
|
||||||
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
||||||
editMenu.AppendSeparator()
|
editMenu.AppendSeparator()
|
||||||
editMenu.Append(MarkerService.MARKERTOGGLE_ID, _("Toggle &Marker\tCtrl+M"), _("Toggles a jump marker to text line"))
|
editMenu.Append(MarkerService.MARKERTOGGLE_ID, _("Toggle &Bookmark\tCtrl+M"), _("Toggles a bookmark at text line"))
|
||||||
wx.EVT_MENU(frame, MarkerService.MARKERTOGGLE_ID, frame.ProcessEvent)
|
wx.EVT_MENU(frame, MarkerService.MARKERTOGGLE_ID, frame.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERTOGGLE_ID, frame.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERTOGGLE_ID, frame.ProcessUpdateUIEvent)
|
||||||
editMenu.Append(MarkerService.MARKERDELALL_ID, _("Clear Markers"), _("Removes all jump markers from selected file"))
|
editMenu.Append(MarkerService.MARKERDELALL_ID, _("Clear Bookmarks"), _("Removes all jump bookmarks from selected file"))
|
||||||
wx.EVT_MENU(frame, MarkerService.MARKERDELALL_ID, frame.ProcessEvent)
|
wx.EVT_MENU(frame, MarkerService.MARKERDELALL_ID, frame.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERDELALL_ID, frame.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERDELALL_ID, frame.ProcessUpdateUIEvent)
|
||||||
editMenu.Append(MarkerService.MARKERNEXT_ID, _("Marker Next\tF4"), _("Moves to next marker in selected file"))
|
editMenu.Append(MarkerService.MARKERNEXT_ID, _("Bookmark Next\tF4"), _("Moves to next bookmark in selected file"))
|
||||||
wx.EVT_MENU(frame, MarkerService.MARKERNEXT_ID, frame.ProcessEvent)
|
wx.EVT_MENU(frame, MarkerService.MARKERNEXT_ID, frame.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERNEXT_ID, frame.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERNEXT_ID, frame.ProcessUpdateUIEvent)
|
||||||
editMenu.Append(MarkerService.MARKERPREV_ID, _("Marker Previous\tShift+F4"), _("Moves to previous marker in selected file"))
|
editMenu.Append(MarkerService.MARKERPREV_ID, _("Bookmark Previous\tShift+F4"), _("Moves to previous bookmark in selected file"))
|
||||||
wx.EVT_MENU(frame, MarkerService.MARKERPREV_ID, frame.ProcessEvent)
|
wx.EVT_MENU(frame, MarkerService.MARKERPREV_ID, frame.ProcessEvent)
|
||||||
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERPREV_ID, frame.ProcessUpdateUIEvent)
|
wx.EVT_UPDATE_UI(frame, MarkerService.MARKERPREV_ID, frame.ProcessUpdateUIEvent)
|
||||||
|
|
||||||
|
@@ -124,6 +124,7 @@ class MessageView(Service.ServiceView):
|
|||||||
|
|
||||||
|
|
||||||
def AddLines(self, text):
|
def AddLines(self, text):
|
||||||
|
self.GetControl().SetCurrentPos(self.GetControl().GetTextLength())
|
||||||
self.GetControl().SetReadOnly(False)
|
self.GetControl().SetReadOnly(False)
|
||||||
self.GetControl().AddText(text)
|
self.GetControl().AddText(text)
|
||||||
self.GetControl().SetReadOnly(True)
|
self.GetControl().SetReadOnly(True)
|
||||||
|
@@ -147,7 +147,11 @@ class OutlineView(Service.ServiceView):
|
|||||||
return
|
return
|
||||||
|
|
||||||
treeCtrl = self.GetControl()
|
treeCtrl = self.GetControl()
|
||||||
|
|
||||||
parentItem = treeCtrl.GetRootItem()
|
parentItem = treeCtrl.GetRootItem()
|
||||||
|
if not parentItem:
|
||||||
|
return
|
||||||
|
|
||||||
if expanded[0] != treeCtrl.GetItemText(parentItem):
|
if expanded[0] != treeCtrl.GetItemText(parentItem):
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -157,8 +161,7 @@ class OutlineView(Service.ServiceView):
|
|||||||
treeCtrl.Expand(child)
|
treeCtrl.Expand(child)
|
||||||
(child, cookie) = treeCtrl.GetNextChild(parentItem, cookie)
|
(child, cookie) = treeCtrl.GetNextChild(parentItem, cookie)
|
||||||
|
|
||||||
if parentItem:
|
treeCtrl.EnsureVisible(parentItem)
|
||||||
treeCtrl.EnsureVisible(parentItem)
|
|
||||||
|
|
||||||
|
|
||||||
class OutlineTreeCtrl(wx.TreeCtrl):
|
class OutlineTreeCtrl(wx.TreeCtrl):
|
||||||
@@ -267,7 +270,7 @@ class OutlineTreeCtrl(wx.TreeCtrl):
|
|||||||
|
|
||||||
if self.ItemHasChildren(item):
|
if self.ItemHasChildren(item):
|
||||||
child, cookie = self.GetFirstChild(item)
|
child, cookie = self.GetFirstChild(item)
|
||||||
while child and child.IsOk():
|
while child.IsOk():
|
||||||
self.FindDistanceToTreeItems(child, position, distances, items)
|
self.FindDistanceToTreeItems(child, position, distances, items)
|
||||||
child, cookie = self.GetNextChild(item, cookie)
|
child, cookie = self.GetNextChild(item, cookie)
|
||||||
return False
|
return False
|
||||||
|
2105
wxPython/samples/ide/activegrid/tool/PHPDebugger.py
Normal file
2105
wxPython/samples/ide/activegrid/tool/PHPDebugger.py
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,6 +17,10 @@ import CodeEditor
|
|||||||
import OutlineService
|
import OutlineService
|
||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
|
import FindInDirService
|
||||||
|
import activegrid.util.appdirs as appdirs
|
||||||
|
import activegrid.util.sysutils as sysutils
|
||||||
|
_ = wx.GetTranslation
|
||||||
|
|
||||||
|
|
||||||
class PHPDocument(CodeEditor.CodeDocument):
|
class PHPDocument(CodeEditor.CodeDocument):
|
||||||
@@ -153,18 +157,52 @@ 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_HTML)
|
||||||
self.SetStyleBits(7)
|
self.SetStyleBits(7)
|
||||||
self.SetKeyWords(4, string.join(PHPKEYWORDS))
|
self.SetKeyWords(4, string.join(PHPKEYWORDS))
|
||||||
self.SetProperty("fold.html", "1")
|
self.SetProperty("fold.html", "1")
|
||||||
|
|
||||||
|
|
||||||
|
def CreatePopupMenu(self):
|
||||||
|
FINDCLASS_ID = wx.NewId()
|
||||||
|
FINDDEF_ID = wx.NewId()
|
||||||
|
|
||||||
|
menu = CodeEditor.CodeCtrl.CreatePopupMenu(self)
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnPopFindDefinition, id=FINDDEF_ID)
|
||||||
|
menu.Insert(1, FINDDEF_ID, _("Find 'function'"))
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnPopFindClass, id=FINDCLASS_ID)
|
||||||
|
menu.Insert(2, FINDCLASS_ID, _("Find 'class'"))
|
||||||
|
|
||||||
|
return menu
|
||||||
|
|
||||||
|
|
||||||
|
def OnPopFindDefinition(self, event):
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
|
pattern = view.GetCtrl().GetSelectedText().strip()
|
||||||
|
if pattern:
|
||||||
|
searchPattern = "function\s+%s" % pattern
|
||||||
|
wx.GetApp().GetService(FindInDirService.FindInDirService).FindInProject(searchPattern)
|
||||||
|
|
||||||
|
|
||||||
|
def OnPopFindClass(self, event):
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
|
definition = "class\s+%s"
|
||||||
|
pattern = view.GetCtrl().GetSelectedText().strip()
|
||||||
|
if pattern:
|
||||||
|
searchPattern = definition % pattern
|
||||||
|
wx.GetApp().GetService(FindInDirService.FindInDirService).FindInProject(searchPattern)
|
||||||
|
|
||||||
|
|
||||||
def CanWordWrap(self):
|
def CanWordWrap(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self):
|
def SetViewDefaults(self):
|
||||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "PHP", hasWordWrap = True, hasTabs = True)
|
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "PHP", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetFontAndColorFromConfig(self):
|
def GetFontAndColorFromConfig(self):
|
||||||
@@ -216,8 +254,110 @@ class PHPCtrl(CodeEditor.CodeCtrl):
|
|||||||
class PHPOptionsPanel(STCTextEditor.TextOptionsPanel):
|
class PHPOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||||
|
|
||||||
def __init__(self, parent, id):
|
def __init__(self, parent, id):
|
||||||
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "PHP", label = "PHP", hasWordWrap = True, hasTabs = True)
|
wx.Panel.__init__(self, parent, id)
|
||||||
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
|
|
||||||
|
config = wx.ConfigBase_Get()
|
||||||
|
|
||||||
|
pathLabel = wx.StaticText(self, -1, _("PHP Executable Path:"))
|
||||||
|
path = config.Read("ActiveGridPHPLocation")
|
||||||
|
self._pathTextCtrl = wx.TextCtrl(self, -1, path, size = (150, -1))
|
||||||
|
self._pathTextCtrl.SetToolTipString(self._pathTextCtrl.GetValue())
|
||||||
|
self._pathTextCtrl.SetInsertionPointEnd()
|
||||||
|
choosePathButton = wx.Button(self, -1, _("Browse..."))
|
||||||
|
pathSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
HALF_SPACE = 5
|
||||||
|
SPACE = 10
|
||||||
|
pathSizer.Add(pathLabel, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP, HALF_SPACE)
|
||||||
|
pathSizer.Add(self._pathTextCtrl, 1, wx.EXPAND|wx.LEFT|wx.TOP, HALF_SPACE)
|
||||||
|
pathSizer.Add(choosePathButton, 0, wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT|wx.TOP, HALF_SPACE)
|
||||||
|
wx.EVT_BUTTON(self, choosePathButton.GetId(), self.OnChoosePath)
|
||||||
|
mainSizer.Add(pathSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
|
||||||
|
|
||||||
|
iniLabel = wx.StaticText(self, -1, _("php.ini Path:"))
|
||||||
|
ini = config.Read("ActiveGridPHPINILocation")
|
||||||
|
if not ini:
|
||||||
|
if sysutils.isRelease():
|
||||||
|
ini = os.path.normpath(os.path.join(appdirs.getSystemDir(), "php.ini"))
|
||||||
|
else:
|
||||||
|
tmp = self._pathTextCtrl.GetValue().strip()
|
||||||
|
if tmp and len(tmp) > 0:
|
||||||
|
ini = os.path.normpath(os.path.join(os.path.dirname(tmp), "php.ini"))
|
||||||
|
|
||||||
|
self._iniTextCtrl = wx.TextCtrl(self, -1, ini, size = (150, -1))
|
||||||
|
self._iniTextCtrl.SetToolTipString(self._iniTextCtrl.GetValue())
|
||||||
|
self._iniTextCtrl.SetInsertionPointEnd()
|
||||||
|
chooseIniButton = wx.Button(self, -1, _("Browse..."))
|
||||||
|
iniSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
|
HALF_SPACE = 5
|
||||||
|
SPACE = 10
|
||||||
|
iniSizer.Add(iniLabel, 0, wx.ALIGN_CENTER_VERTICAL|wx.LEFT|wx.TOP, HALF_SPACE)
|
||||||
|
iniSizer.Add(self._iniTextCtrl, 1, wx.EXPAND|wx.LEFT|wx.TOP, HALF_SPACE)
|
||||||
|
iniSizer.Add(chooseIniButton, 0, wx.ALIGN_RIGHT|wx.LEFT|wx.RIGHT|wx.TOP, HALF_SPACE)
|
||||||
|
wx.EVT_BUTTON(self, chooseIniButton.GetId(), self.OnChooseIni)
|
||||||
|
mainSizer.Add(iniSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
|
||||||
|
|
||||||
|
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "PHP", label = "PHP", hasWordWrap = True, hasTabs = True, addPage=False, hasFolding=False)
|
||||||
|
#STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "PHP", label = "PHP", hasWordWrap = True, hasTabs = True)
|
||||||
|
mainSizer.Add(self._otherOptions, 0, wx.EXPAND|wx.BOTTOM, SPACE)
|
||||||
|
|
||||||
|
self.SetSizer(mainSizer)
|
||||||
|
parent.AddPage(self, _("PHP"))
|
||||||
|
|
||||||
|
def OnChoosePath(self, event):
|
||||||
|
defaultDir = os.path.dirname(self._pathTextCtrl.GetValue().strip())
|
||||||
|
defaultFile = os.path.basename(self._pathTextCtrl.GetValue().strip())
|
||||||
|
if wx.Platform == '__WXMSW__':
|
||||||
|
wildcard = _("Executable (*.exe)|*.exe|All|*.*")
|
||||||
|
if not defaultFile:
|
||||||
|
defaultFile = "php-cgi.exe"
|
||||||
|
else:
|
||||||
|
wildcard = _("*")
|
||||||
|
dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
|
||||||
|
_("Select a File"),
|
||||||
|
defaultDir=defaultDir,
|
||||||
|
defaultFile=defaultFile,
|
||||||
|
wildcard=wildcard,
|
||||||
|
style=wx.OPEN|wx.FILE_MUST_EXIST|wx.HIDE_READONLY)
|
||||||
|
# dlg.CenterOnParent() # wxBug: caused crash with wx.FileDialog
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
path = dlg.GetPath()
|
||||||
|
if path:
|
||||||
|
self._pathTextCtrl.SetValue(path)
|
||||||
|
self._pathTextCtrl.SetToolTipString(self._pathTextCtrl.GetValue())
|
||||||
|
self._pathTextCtrl.SetInsertionPointEnd()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def OnChooseIni(self, event):
|
||||||
|
defaultDir = os.path.dirname(self._iniTextCtrl.GetValue().strip())
|
||||||
|
defaultFile = os.path.basename(self._iniTextCtrl.GetValue().strip())
|
||||||
|
if wx.Platform == '__WXMSW__':
|
||||||
|
wildcard = _("Ini (*.ini)|*.ini|All|*.*")
|
||||||
|
if not defaultFile:
|
||||||
|
defaultFile = "php.ini"
|
||||||
|
else:
|
||||||
|
wildcard = _("*")
|
||||||
|
dlg = wx.FileDialog(wx.GetApp().GetTopWindow(),
|
||||||
|
_("Select a File"),
|
||||||
|
defaultDir=defaultDir,
|
||||||
|
defaultFile=defaultFile,
|
||||||
|
wildcard=wildcard,
|
||||||
|
style=wx.OPEN|wx.FILE_MUST_EXIST|wx.HIDE_READONLY)
|
||||||
|
# dlg.CenterOnParent() # wxBug: caused crash with wx.FileDialog
|
||||||
|
if dlg.ShowModal() == wx.ID_OK:
|
||||||
|
ini = dlg.GetPath()
|
||||||
|
if ini:
|
||||||
|
self._iniTextCtrl.SetValue(ini)
|
||||||
|
self._iniTextCtrl.SetToolTipString(self._iniTextCtrl.GetValue())
|
||||||
|
self._iniTextCtrl.SetInsertionPointEnd()
|
||||||
|
dlg.Destroy()
|
||||||
|
|
||||||
|
def OnOK(self, optionsDialog):
|
||||||
|
config = wx.ConfigBase_Get()
|
||||||
|
config.Write("ActiveGridPHPLocation", self._pathTextCtrl.GetValue().strip())
|
||||||
|
config.Write("ActiveGridPHPINILocation", self._iniTextCtrl.GetValue().strip())
|
||||||
|
|
||||||
|
self._otherOptions.OnOK(optionsDialog)
|
||||||
|
|
||||||
def GetIcon(self):
|
def GetIcon(self):
|
||||||
return getPHPIcon()
|
return getPHPIcon()
|
||||||
|
@@ -73,7 +73,7 @@ class PerlCtrl(CodeEditor.CodeCtrl):
|
|||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self):
|
def SetViewDefaults(self):
|
||||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Perl", hasWordWrap = True, hasTabs = True)
|
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Perl", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetFontAndColorFromConfig(self):
|
def GetFontAndColorFromConfig(self):
|
||||||
@@ -130,7 +130,7 @@ class PerlCtrl(CodeEditor.CodeCtrl):
|
|||||||
class PerlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
class PerlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||||
|
|
||||||
def __init__(self, parent, id):
|
def __init__(self, parent, id):
|
||||||
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Perl", label = "Perl", hasWordWrap = True, hasTabs = True)
|
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Perl", label = "Perl", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetIcon(self):
|
def GetIcon(self):
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,7 @@ import keyword # for GetAutoCompleteKeywordList
|
|||||||
import sys # for GetAutoCompleteKeywordList
|
import sys # for GetAutoCompleteKeywordList
|
||||||
import MessageService # for OnCheckCode
|
import MessageService # for OnCheckCode
|
||||||
import OutlineService
|
import OutlineService
|
||||||
|
import FindInDirService
|
||||||
from UICommon import CaseInsensitiveCompare
|
from UICommon import CaseInsensitiveCompare
|
||||||
try:
|
try:
|
||||||
import checker # for pychecker
|
import checker # for pychecker
|
||||||
@@ -143,11 +144,13 @@ class PythonView(CodeEditor.CodeView):
|
|||||||
# Set cursor to Wait cursor
|
# Set cursor to Wait cursor
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||||
|
|
||||||
# This takes a while for involved code
|
try:
|
||||||
checker.checkSyntax(self.GetDocument().GetFilename(), view)
|
# This takes a while for involved code
|
||||||
|
checker.checkSyntax(self.GetDocument().GetFilename(), view)
|
||||||
|
|
||||||
# Set cursor to Default cursor
|
finally:
|
||||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
# Set cursor to Default cursor
|
||||||
|
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||||
|
|
||||||
|
|
||||||
def OnJumpToFoundLine(self, event):
|
def OnJumpToFoundLine(self, event):
|
||||||
@@ -369,8 +372,42 @@ class PythonCtrl(CodeEditor.CodeCtrl):
|
|||||||
self.SetKeyWords(0, string.join(keyword.kwlist))
|
self.SetKeyWords(0, string.join(keyword.kwlist))
|
||||||
|
|
||||||
|
|
||||||
|
def CreatePopupMenu(self):
|
||||||
|
FINDCLASS_ID = wx.NewId()
|
||||||
|
FINDDEF_ID = wx.NewId()
|
||||||
|
|
||||||
|
menu = CodeEditor.CodeCtrl.CreatePopupMenu(self)
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnPopFindDefinition, id=FINDDEF_ID)
|
||||||
|
menu.Insert(1, FINDDEF_ID, _("Find 'def'"))
|
||||||
|
|
||||||
|
self.Bind(wx.EVT_MENU, self.OnPopFindClass, id=FINDCLASS_ID)
|
||||||
|
menu.Insert(2, FINDCLASS_ID, _("Find 'class'"))
|
||||||
|
|
||||||
|
return menu
|
||||||
|
|
||||||
|
|
||||||
|
def OnPopFindDefinition(self, event):
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
|
pattern = view.GetCtrl().GetSelectedText().strip()
|
||||||
|
if pattern:
|
||||||
|
searchPattern = "def\s+%s" % pattern
|
||||||
|
wx.GetApp().GetService(FindInDirService.FindInDirService).FindInProject(searchPattern)
|
||||||
|
|
||||||
|
|
||||||
|
def OnPopFindClass(self, event):
|
||||||
|
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||||
|
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||||
|
definition = "class\s+%s"
|
||||||
|
pattern = view.GetCtrl().GetSelectedText().strip()
|
||||||
|
if pattern:
|
||||||
|
searchPattern = definition % pattern
|
||||||
|
wx.GetApp().GetService(FindInDirService.FindInDirService).FindInProject(searchPattern)
|
||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self):
|
def SetViewDefaults(self):
|
||||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Python", hasWordWrap = True, hasTabs = True)
|
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix="Python", hasWordWrap=True, hasTabs=True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetFontAndColorFromConfig(self):
|
def GetFontAndColorFromConfig(self):
|
||||||
@@ -567,7 +604,7 @@ class PythonOptionsPanel(wx.Panel):
|
|||||||
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
mainSizer = wx.BoxSizer(wx.VERTICAL)
|
||||||
mainSizer.Add(pathSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
|
mainSizer.Add(pathSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
|
||||||
|
|
||||||
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "Python", label = "Python", hasWordWrap = True, hasTabs = True, addPage=False)
|
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "Python", label = "Python", hasWordWrap = True, hasTabs = True, addPage=False, hasFolding=True)
|
||||||
mainSizer.Add(self._otherOptions, 0, wx.EXPAND|wx.BOTTOM, SPACE)
|
mainSizer.Add(self._otherOptions, 0, wx.EXPAND|wx.BOTTOM, SPACE)
|
||||||
self.SetSizer(mainSizer)
|
self.SetSizer(mainSizer)
|
||||||
parent.AddPage(self, _("Python"))
|
parent.AddPage(self, _("Python"))
|
||||||
@@ -577,7 +614,7 @@ class PythonOptionsPanel(wx.Panel):
|
|||||||
defaultDir = os.path.dirname(self._pathTextCtrl.GetValue().strip())
|
defaultDir = os.path.dirname(self._pathTextCtrl.GetValue().strip())
|
||||||
defaultFile = os.path.basename(self._pathTextCtrl.GetValue().strip())
|
defaultFile = os.path.basename(self._pathTextCtrl.GetValue().strip())
|
||||||
if _WINDOWS:
|
if _WINDOWS:
|
||||||
wildcard = _("Executable (*.exe)|*.exe|All (*.*)|*.*")
|
wildcard = _("Executable (*.exe)|*.exe|All|*.*")
|
||||||
if not defaultFile:
|
if not defaultFile:
|
||||||
defaultFile = "python.exe"
|
defaultFile = "python.exe"
|
||||||
else:
|
else:
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Created: 8/10/03
|
# Created: 8/10/03
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc.
|
# Copyright: (c) 2003-2006 ActiveGrid, Inc.
|
||||||
# License: wxWindows License
|
# License: wxWindows License
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -47,9 +47,15 @@ TEXT_STATUS_BAR_ID = wx.NewId()
|
|||||||
class TextDocument(wx.lib.docview.Document):
|
class TextDocument(wx.lib.docview.Document):
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
wx.lib.docview.Document .__init__(self)
|
||||||
|
self._inModify = False
|
||||||
|
|
||||||
|
|
||||||
def SaveObject(self, fileObject):
|
def SaveObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
fileObject.write(view.GetValue())
|
fileObject.write(view.GetValue())
|
||||||
|
view.SetModifyFalse()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
@@ -57,24 +63,31 @@ class TextDocument(wx.lib.docview.Document):
|
|||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
data = fileObject.read()
|
data = fileObject.read()
|
||||||
view.SetValue(data)
|
view.SetValue(data)
|
||||||
|
view.SetModifyFalse()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def IsModified(self):
|
def IsModified(self):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
if view:
|
if view:
|
||||||
return wx.lib.docview.Document.IsModified(self) or view.IsModified()
|
return view.IsModified()
|
||||||
else:
|
return False
|
||||||
return wx.lib.docview.Document.IsModified(self)
|
|
||||||
|
|
||||||
|
|
||||||
def Modify(self, mod):
|
def Modify(self, modify):
|
||||||
|
if self._inModify:
|
||||||
|
return
|
||||||
|
self._inModify = True
|
||||||
|
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
wx.lib.docview.Document.Modify(self, mod)
|
if not modify and view:
|
||||||
if not mod and view:
|
|
||||||
view.SetModifyFalse()
|
view.SetModifyFalse()
|
||||||
|
|
||||||
|
wx.lib.docview.Document.Modify(self, modify) # this must called be after the SetModifyFalse call above.
|
||||||
|
|
||||||
|
self._inModify = False
|
||||||
|
|
||||||
|
|
||||||
def OnCreateCommandProcessor(self):
|
def OnCreateCommandProcessor(self):
|
||||||
# Don't create a command processor, it has its own
|
# Don't create a command processor, it has its own
|
||||||
pass
|
pass
|
||||||
@@ -142,6 +155,8 @@ class TextView(wx.lib.docview.View):
|
|||||||
self._dynSash._view = self
|
self._dynSash._view = self
|
||||||
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
||||||
wx.EVT_LEFT_DOWN(self._textEditor, self.OnLeftClick)
|
wx.EVT_LEFT_DOWN(self._textEditor, self.OnLeftClick)
|
||||||
|
self._textEditor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModify)
|
||||||
|
|
||||||
self._CreateSizer(frame)
|
self._CreateSizer(frame)
|
||||||
self.Activate()
|
self.Activate()
|
||||||
frame.Show(True)
|
frame.Show(True)
|
||||||
@@ -149,6 +164,10 @@ class TextView(wx.lib.docview.View):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def OnModify(self, event):
|
||||||
|
self.GetDocument().Modify(self._textEditor.GetModify())
|
||||||
|
|
||||||
|
|
||||||
def _CreateSizer(self, frame):
|
def _CreateSizer(self, frame):
|
||||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
sizer.Add(self._dynSash, 1, wx.EXPAND)
|
sizer.Add(self._dynSash, 1, wx.EXPAND)
|
||||||
@@ -161,6 +180,9 @@ class TextView(wx.lib.docview.View):
|
|||||||
|
|
||||||
|
|
||||||
def OnUpdate(self, sender = None, hint = None):
|
def OnUpdate(self, sender = None, hint = None):
|
||||||
|
if wx.lib.docview.View.OnUpdate(self, sender, hint):
|
||||||
|
return
|
||||||
|
|
||||||
if hint == "ViewStuff":
|
if hint == "ViewStuff":
|
||||||
self.GetCtrl().SetViewDefaults()
|
self.GetCtrl().SetViewDefaults()
|
||||||
elif hint == "Font":
|
elif hint == "Font":
|
||||||
@@ -571,9 +593,11 @@ class TextView(wx.lib.docview.View):
|
|||||||
def EnsureVisible(self, line):
|
def EnsureVisible(self, line):
|
||||||
self.GetCtrl().EnsureVisible(line-1) # line numbering for editor is 0 based, we are 1 based.
|
self.GetCtrl().EnsureVisible(line-1) # line numbering for editor is 0 based, we are 1 based.
|
||||||
|
|
||||||
|
|
||||||
def EnsureVisibleEnforcePolicy(self, line):
|
def EnsureVisibleEnforcePolicy(self, line):
|
||||||
self.GetCtrl().EnsureVisibleEnforcePolicy(line-1) # line numbering for editor is 0 based, we are 1 based.
|
self.GetCtrl().EnsureVisibleEnforcePolicy(line-1) # line numbering for editor is 0 based, we are 1 based.
|
||||||
|
|
||||||
|
|
||||||
def LineFromPosition(self, pos):
|
def LineFromPosition(self, pos):
|
||||||
return self.GetCtrl().LineFromPosition(pos)+1 # line numbering for editor is 0 based, we are 1 based.
|
return self.GetCtrl().LineFromPosition(pos)+1 # line numbering for editor is 0 based, we are 1 based.
|
||||||
|
|
||||||
@@ -813,11 +837,12 @@ class TextStatusBar(wx.StatusBar):
|
|||||||
class TextOptionsPanel(wx.Panel):
|
class TextOptionsPanel(wx.Panel):
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, parent, id, configPrefix = "Text", label = "Text", hasWordWrap = True, hasTabs = False, addPage=True):
|
def __init__(self, parent, id, configPrefix = "Text", label = "Text", hasWordWrap = True, hasTabs = False, addPage=True, hasFolding=False):
|
||||||
wx.Panel.__init__(self, parent, id)
|
wx.Panel.__init__(self, parent, id)
|
||||||
self._configPrefix = configPrefix
|
self._configPrefix = configPrefix
|
||||||
self._hasWordWrap = hasWordWrap
|
self._hasWordWrap = hasWordWrap
|
||||||
self._hasTabs = hasTabs
|
self._hasTabs = hasTabs
|
||||||
|
self._hasFolding = hasFolding
|
||||||
SPACE = 10
|
SPACE = 10
|
||||||
HALF_SPACE = 5
|
HALF_SPACE = 5
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
@@ -854,6 +879,9 @@ class TextOptionsPanel(wx.Panel):
|
|||||||
self._viewRightEdgeCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewRightEdge", False))
|
self._viewRightEdgeCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewRightEdge", False))
|
||||||
self._viewLineNumbersCheckBox = wx.CheckBox(self, -1, _("Show line numbers"))
|
self._viewLineNumbersCheckBox = wx.CheckBox(self, -1, _("Show line numbers"))
|
||||||
self._viewLineNumbersCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True))
|
self._viewLineNumbersCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True))
|
||||||
|
if self._hasFolding:
|
||||||
|
self._viewFoldingCheckBox = wx.CheckBox(self, -1, _("Show folding"))
|
||||||
|
self._viewFoldingCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewFolding", True))
|
||||||
if self._hasTabs:
|
if self._hasTabs:
|
||||||
self._hasTabsCheckBox = wx.CheckBox(self, -1, _("Use spaces instead of tabs"))
|
self._hasTabsCheckBox = wx.CheckBox(self, -1, _("Use spaces instead of tabs"))
|
||||||
self._hasTabsCheckBox.SetValue(not wx.ConfigBase_Get().ReadInt(self._configPrefix + "EditorUseTabs", False))
|
self._hasTabsCheckBox.SetValue(not wx.ConfigBase_Get().ReadInt(self._configPrefix + "EditorUseTabs", False))
|
||||||
@@ -874,6 +902,8 @@ class TextOptionsPanel(wx.Panel):
|
|||||||
textPanelSizer.Add(self._viewIndentationGuideCheckBox, 0, wx.ALL, HALF_SPACE)
|
textPanelSizer.Add(self._viewIndentationGuideCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||||
textPanelSizer.Add(self._viewRightEdgeCheckBox, 0, wx.ALL, HALF_SPACE)
|
textPanelSizer.Add(self._viewRightEdgeCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||||
textPanelSizer.Add(self._viewLineNumbersCheckBox, 0, wx.ALL, HALF_SPACE)
|
textPanelSizer.Add(self._viewLineNumbersCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||||
|
if self._hasFolding:
|
||||||
|
textPanelSizer.Add(self._viewFoldingCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||||
if self._hasTabs:
|
if self._hasTabs:
|
||||||
textPanelSizer.Add(self._hasTabsCheckBox, 0, wx.ALL, HALF_SPACE)
|
textPanelSizer.Add(self._hasTabsCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||||
textIndentWidthSizer = wx.BoxSizer(wx.HORIZONTAL)
|
textIndentWidthSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||||
@@ -947,6 +977,9 @@ class TextOptionsPanel(wx.Panel):
|
|||||||
config.WriteInt(self._configPrefix + "EditorViewRightEdge", self._viewRightEdgeCheckBox.GetValue())
|
config.WriteInt(self._configPrefix + "EditorViewRightEdge", self._viewRightEdgeCheckBox.GetValue())
|
||||||
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True) != self._viewLineNumbersCheckBox.GetValue()
|
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True) != self._viewLineNumbersCheckBox.GetValue()
|
||||||
config.WriteInt(self._configPrefix + "EditorViewLineNumbers", self._viewLineNumbersCheckBox.GetValue())
|
config.WriteInt(self._configPrefix + "EditorViewLineNumbers", self._viewLineNumbersCheckBox.GetValue())
|
||||||
|
if self._hasFolding:
|
||||||
|
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewFolding", True) != self._viewFoldingCheckBox.GetValue()
|
||||||
|
config.WriteInt(self._configPrefix + "EditorViewFolding", self._viewFoldingCheckBox.GetValue())
|
||||||
if self._hasWordWrap:
|
if self._hasWordWrap:
|
||||||
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorWordWrap", False) != self._wordWrapCheckBox.GetValue()
|
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorWordWrap", False) != self._wordWrapCheckBox.GetValue()
|
||||||
config.WriteInt(self._configPrefix + "EditorWordWrap", self._wordWrapCheckBox.GetValue())
|
config.WriteInt(self._configPrefix + "EditorWordWrap", self._wordWrapCheckBox.GetValue())
|
||||||
@@ -1062,13 +1095,15 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
event.Skip()
|
event.Skip()
|
||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self, configPrefix = "Text", hasWordWrap = True, hasTabs = False):
|
def SetViewDefaults(self, configPrefix="Text", hasWordWrap=True, hasTabs=False, hasFolding=False):
|
||||||
config = wx.ConfigBase_Get()
|
config = wx.ConfigBase_Get()
|
||||||
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
|
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
|
||||||
self.SetViewEOL(config.ReadInt(configPrefix + "EditorViewEOL", False))
|
self.SetViewEOL(config.ReadInt(configPrefix + "EditorViewEOL", False))
|
||||||
self.SetIndentationGuides(config.ReadInt(configPrefix + "EditorViewIndentationGuides", False))
|
self.SetIndentationGuides(config.ReadInt(configPrefix + "EditorViewIndentationGuides", False))
|
||||||
self.SetViewRightEdge(config.ReadInt(configPrefix + "EditorViewRightEdge", False))
|
self.SetViewRightEdge(config.ReadInt(configPrefix + "EditorViewRightEdge", False))
|
||||||
self.SetViewLineNumbers(config.ReadInt(configPrefix + "EditorViewLineNumbers", True))
|
self.SetViewLineNumbers(config.ReadInt(configPrefix + "EditorViewLineNumbers", True))
|
||||||
|
if hasFolding:
|
||||||
|
self.SetViewFolding(config.ReadInt(configPrefix + "EditorViewFolding", True))
|
||||||
if hasWordWrap:
|
if hasWordWrap:
|
||||||
self.SetWordWrap(config.ReadInt(configPrefix + "EditorWordWrap", False))
|
self.SetWordWrap(config.ReadInt(configPrefix + "EditorWordWrap", False))
|
||||||
if hasTabs: # These methods do not exist in STCTextEditor and are meant for subclasses
|
if hasTabs: # These methods do not exist in STCTextEditor and are meant for subclasses
|
||||||
@@ -1237,6 +1272,17 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
|||||||
self.SetMarginWidth(1, 0)
|
self.SetMarginWidth(1, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def GetViewFolding(self):
|
||||||
|
return self.GetMarginWidth(2) > 0
|
||||||
|
|
||||||
|
|
||||||
|
def SetViewFolding(self, viewFolding = True):
|
||||||
|
if viewFolding:
|
||||||
|
self.SetMarginWidth(2, 12)
|
||||||
|
else:
|
||||||
|
self.SetMarginWidth(2, 0)
|
||||||
|
|
||||||
|
|
||||||
def CanWordWrap(self):
|
def CanWordWrap(self):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Created: 3/10/05
|
# Created: 3/10/05
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||||
# License: wxWindows License
|
# License: wxWindows License
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -15,12 +15,14 @@ import os.path
|
|||||||
import wx
|
import wx
|
||||||
import string
|
import string
|
||||||
import ProjectEditor
|
import ProjectEditor
|
||||||
import activegrid.util.sysutils as sysutils
|
|
||||||
import activegrid.util.strutils as strutils
|
|
||||||
import activegrid.util.appdirs as appdirs
|
import activegrid.util.appdirs as appdirs
|
||||||
|
import activegrid.util.fileutils as fileutils
|
||||||
|
import activegrid.util.strutils as strutils
|
||||||
|
import activegrid.util.sysutils as sysutils
|
||||||
|
import activegrid.util.xmlutils as xmlutils
|
||||||
_ = wx.GetTranslation
|
_ = wx.GetTranslation
|
||||||
|
|
||||||
def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False):
|
def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory:"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False, useDirDialog=False):
|
||||||
|
|
||||||
if not choiceDirs:
|
if not choiceDirs:
|
||||||
choiceDirs = []
|
choiceDirs = []
|
||||||
@@ -61,8 +63,8 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
|
|||||||
|
|
||||||
if os.getcwd() not in choiceDirs:
|
if os.getcwd() not in choiceDirs:
|
||||||
choiceDirs.append(os.getcwd())
|
choiceDirs.append(os.getcwd())
|
||||||
if appdirs.documents_folder not in choiceDirs:
|
if appdirs.getSystemDir() not in choiceDirs:
|
||||||
choiceDirs.append(appdirs.documents_folder)
|
choiceDirs.append(appdirs.getSystemDir())
|
||||||
|
|
||||||
if not startingDirectory:
|
if not startingDirectory:
|
||||||
startingDirectory = os.getcwd()
|
startingDirectory = os.getcwd()
|
||||||
@@ -85,12 +87,18 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
|
|||||||
else:
|
else:
|
||||||
name = _("%s.%s") % (nameCtrlValue, fileExtension)
|
name = _("%s.%s") % (nameCtrlValue, fileExtension)
|
||||||
|
|
||||||
dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
|
if not useDirDialog:
|
||||||
|
dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
|
||||||
defaultDir = dirControl.GetValue().strip(),
|
defaultDir = dirControl.GetValue().strip(),
|
||||||
defaultFile = name,
|
defaultFile = name,
|
||||||
wildcard= "*.%s" % fileExtension,
|
wildcard= "*.%s" % fileExtension,
|
||||||
style=wx.SAVE|wx.CHANGE_DIR)
|
style=wx.SAVE|wx.CHANGE_DIR)
|
||||||
|
else:
|
||||||
|
dlg = wx.DirDialog(wx.GetApp().GetTopWindow(),
|
||||||
|
_("Choose a directory:"),
|
||||||
|
defaultPath=dirControl.GetValue().strip(),
|
||||||
|
style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
|
||||||
|
|
||||||
if dlg.ShowModal() != wx.ID_OK:
|
if dlg.ShowModal() != wx.ID_OK:
|
||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
return
|
return
|
||||||
@@ -98,49 +106,78 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
|
|||||||
dlg.Destroy()
|
dlg.Destroy()
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
dir, filename = os.path.split(path)
|
if not useDirDialog:
|
||||||
if dirControl.FindString(dir) == wx.NOT_FOUND:
|
dir, filename = os.path.split(path)
|
||||||
dirControl.Insert(dir, 0)
|
if dirControl.FindString(dir) == wx.NOT_FOUND:
|
||||||
dirControl.SetValue(dir)
|
dirControl.Insert(dir, 0)
|
||||||
dirControl.SetToolTipString(dir)
|
dirControl.SetValue(dir)
|
||||||
nameControl.SetValue(filename)
|
dirControl.SetToolTipString(dir)
|
||||||
|
nameControl.SetValue(filename)
|
||||||
|
else:
|
||||||
|
dirControl.SetValue(path)
|
||||||
|
dirControl.SetToolTipString(path)
|
||||||
|
|
||||||
parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
|
parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
|
||||||
|
|
||||||
def Validate(allowOverwriteOnPrompt=False, infoString='', noFirstCharDigit=False):
|
def Validate(allowOverwriteOnPrompt=False, infoString='', validClassName=False, ignoreFileConflicts=False):
|
||||||
projName = nameControl.GetValue().strip()
|
projName = nameControl.GetValue().strip()
|
||||||
if projName == "":
|
if projName == "":
|
||||||
wx.MessageBox(_("Please provide a %sfile name.") % infoString, _("Provide a File Name"))
|
wx.MessageBox(_("Please provide a %sfile name.") % infoString, _("Provide a File Name"))
|
||||||
return False
|
return False
|
||||||
if noFirstCharDigit and projName[0].isdigit():
|
|
||||||
wx.MessageBox(_("File name cannot start with a number. Please enter a different name."), _("Invalid File Name"))
|
|
||||||
return False
|
|
||||||
if projName.find(' ') != -1:
|
if projName.find(' ') != -1:
|
||||||
wx.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString, _("Spaces in File Name"))
|
wx.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString, _("Spaces in File Name"))
|
||||||
return False
|
return False
|
||||||
if not os.path.exists(dirControl.GetValue()):
|
if validClassName:
|
||||||
wx.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString, _("Provide a Valid Directory"))
|
if projName[0].isdigit():
|
||||||
|
wx.MessageBox(_("File name cannot start with a number. Please enter a different name."), _("Invalid File Name"))
|
||||||
|
return False
|
||||||
|
if projName.endswith(".agp"):
|
||||||
|
projName2 = projName[:-4]
|
||||||
|
else:
|
||||||
|
projName2 = projName
|
||||||
|
if not projName2.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ending '.agp'.
|
||||||
|
wx.MessageBox(_("Name must be alphanumeric ('_' allowed). Please enter a valid name."), _("Project Name"))
|
||||||
|
return False
|
||||||
|
|
||||||
|
dirName = dirControl.GetValue().strip()
|
||||||
|
if dirName == "":
|
||||||
|
wx.MessageBox(_("No directory. Please provide a directory."), _("Provide a Directory"))
|
||||||
return False
|
return False
|
||||||
|
if os.sep == "\\" and dirName.find("/") != -1:
|
||||||
filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(projName, "." + fileExtension))
|
wx.MessageBox(_("Wrong delimiter '/' found in directory path. Use '%s' as delimiter.") % os.sep, _("Provide a Valid Directory"))
|
||||||
if os.path.exists(filePath):
|
return False
|
||||||
if allowOverwriteOnPrompt:
|
if not os.path.exists(dirName):
|
||||||
res = wx.MessageBox(_("That %sfile already exists. Would you like to overwrite it.") % infoString, "File Exists", style=wx.YES_NO|wx.NO_DEFAULT)
|
wx.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString, _("Provide a Valid Directory"))
|
||||||
return (res == wx.YES)
|
return False
|
||||||
else:
|
if not ignoreFileConflicts:
|
||||||
wx.MessageBox(_("That %sfile already exists. Please choose a different name.") % infoString, "File Exists")
|
filePath = os.path.join(dirName, MakeNameEndInExtension(projName, "." + fileExtension))
|
||||||
return False
|
if os.path.exists(filePath):
|
||||||
|
if allowOverwriteOnPrompt:
|
||||||
|
res = wx.MessageBox(_("That %sfile already exists. Would you like to overwrite it.") % infoString, "File Exists", style=wx.YES_NO|wx.NO_DEFAULT)
|
||||||
|
return (res == wx.YES)
|
||||||
|
else:
|
||||||
|
wx.MessageBox(_("That %sfile already exists. Please choose a different name.") % infoString, "File Exists")
|
||||||
|
return False
|
||||||
|
|
||||||
return True
|
return True
|
||||||
HALF_SPACE = 5
|
HALF_SPACE = 5
|
||||||
flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
|
flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
|
||||||
flexGridSizer.AddGrowableCol(1,1)
|
flexGridSizer.AddGrowableCol(1,1)
|
||||||
flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
if not useDirDialog:
|
||||||
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
||||||
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
|
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||||
|
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
|
||||||
|
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
||||||
|
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||||
|
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
|
||||||
|
else:
|
||||||
|
flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
||||||
|
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||||
|
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
|
||||||
|
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
||||||
|
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||||
|
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
|
||||||
|
|
||||||
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
|
||||||
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
|
||||||
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
|
|
||||||
if returnAll:
|
if returnAll:
|
||||||
return nameControl, dirControl, flexGridSizer, Validate, allControls
|
return nameControl, dirControl, flexGridSizer, Validate, allControls
|
||||||
else:
|
else:
|
||||||
@@ -188,8 +225,8 @@ def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirecto
|
|||||||
|
|
||||||
if os.getcwd() not in choiceDirs:
|
if os.getcwd() not in choiceDirs:
|
||||||
choiceDirs.append(os.getcwd())
|
choiceDirs.append(os.getcwd())
|
||||||
if appdirs.documents_folder not in choiceDirs:
|
if appdirs.getSystemDir() not in choiceDirs:
|
||||||
choiceDirs.append(appdirs.documents_folder)
|
choiceDirs.append(appdirs.getSystemDir())
|
||||||
|
|
||||||
|
|
||||||
if not startingDirectory:
|
if not startingDirectory:
|
||||||
@@ -221,6 +258,9 @@ def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirecto
|
|||||||
if dirName == "":
|
if dirName == "":
|
||||||
wx.MessageBox(_("Please provide a directory."), _("Provide a Directory"))
|
wx.MessageBox(_("Please provide a directory."), _("Provide a Directory"))
|
||||||
return False
|
return False
|
||||||
|
if os.sep == "\\" and dirName.find("/") != -1:
|
||||||
|
wx.MessageBox(_("Wrong delimiter '/' found in directory path. Use '%s' as delimiter.") % os.sep, _("Provide a Valid Directory"))
|
||||||
|
return False
|
||||||
if not os.path.exists(dirName):
|
if not os.path.exists(dirName):
|
||||||
wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
|
wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
|
||||||
return False
|
return False
|
||||||
@@ -241,17 +281,25 @@ def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectory
|
|||||||
fileLabelText = wx.StaticText(parent, -1, fileLabel)
|
fileLabelText = wx.StaticText(parent, -1, fileLabel)
|
||||||
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
|
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
|
||||||
|
|
||||||
def Validate(allowOverwriteOnPrompt=False, noFirstCharDigit=False):
|
def Validate(allowOverwriteOnPrompt=False, validClassName=False):
|
||||||
projName = nameControl.GetValue().strip()
|
projName = nameControl.GetValue().strip()
|
||||||
if projName == "":
|
if projName == "":
|
||||||
wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name"))
|
wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name"))
|
||||||
return False
|
return False
|
||||||
if noFirstCharDigit and projName[0].isdigit():
|
|
||||||
wx.MessageBox(_("Name cannot start with a number. Please enter a valid name."), _("Project Name"))
|
|
||||||
return False
|
|
||||||
if projName.find(' ') != -1:
|
if projName.find(' ') != -1:
|
||||||
wx.MessageBox(_("Spaces in name. Name cannot have spaces.") % infoString, _("Project Name"))
|
wx.MessageBox(_("Spaces in name. Name cannot have spaces."), _("Project Name"))
|
||||||
return False
|
return False
|
||||||
|
if validClassName:
|
||||||
|
if projName[0].isdigit():
|
||||||
|
wx.MessageBox(_("Name cannot start with a number. Please enter a valid name."), _("Project Name"))
|
||||||
|
return False
|
||||||
|
if projName.endswith(".agp"):
|
||||||
|
projName2 = projName[:-4]
|
||||||
|
else:
|
||||||
|
projName2 = projName
|
||||||
|
if not projName2.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ending '.agp'.
|
||||||
|
wx.MessageBox(_("Name must be alphanumeric ('_' allowed). Please enter a valid name."), _("Project Name"))
|
||||||
|
return False
|
||||||
path = os.path.join(startingDirectoryControl.GetValue().strip(), projName)
|
path = os.path.join(startingDirectoryControl.GetValue().strip(), projName)
|
||||||
if os.path.exists(path):
|
if os.path.exists(path):
|
||||||
if os.path.isdir(path):
|
if os.path.isdir(path):
|
||||||
@@ -280,6 +328,29 @@ def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectory
|
|||||||
return nameControl, flexGridSizer, Validate
|
return nameControl, flexGridSizer, Validate
|
||||||
|
|
||||||
|
|
||||||
|
def ValidateName(name, ext=None, hint="name"):
|
||||||
|
""" Returns an error string if there is something wrong with the name.
|
||||||
|
Otherwise it returns None
|
||||||
|
"""
|
||||||
|
if name == "":
|
||||||
|
return _("Blank %s. Please enter a valid %s.") % (hint, hint)
|
||||||
|
|
||||||
|
if name.find(' ') != -1:
|
||||||
|
return _("Spaces in %s. %s cannot have spaces.") % (hint, hint.title())
|
||||||
|
|
||||||
|
if name[0].isdigit():
|
||||||
|
return _("%s cannot start with a number. Please enter a valid %s.") % (hint.title(), hint)
|
||||||
|
|
||||||
|
if ext and name.endswith(ext): # strip extension if provided
|
||||||
|
lenExt = len(ext)
|
||||||
|
name = name[:-lenExt]
|
||||||
|
|
||||||
|
if not name.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ext ending.
|
||||||
|
return _("%s must be alphanumeric ('_' allowed). Please enter a valid %s.") % (hint.title(), hint)
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
def GetCurrentProject():
|
def GetCurrentProject():
|
||||||
projectDocument = None
|
projectDocument = None
|
||||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||||
@@ -330,6 +401,16 @@ def GetPythonExecPath():
|
|||||||
return pythonExecPath
|
return pythonExecPath
|
||||||
|
|
||||||
|
|
||||||
|
def GetPHPExecPath():
|
||||||
|
PHPExecPath = wx.ConfigBase_Get().Read("ActiveGridPHPLocation")
|
||||||
|
return PHPExecPath
|
||||||
|
|
||||||
|
|
||||||
|
def GetPHPINIPath():
|
||||||
|
PHPINIPath = wx.ConfigBase_Get().Read("ActiveGridPHPINILocation")
|
||||||
|
return PHPINIPath
|
||||||
|
|
||||||
|
|
||||||
def _DoRemoveRecursive(path, skipFile=None, skipped=False):
|
def _DoRemoveRecursive(path, skipFile=None, skipped=False):
|
||||||
if path == skipFile:
|
if path == skipFile:
|
||||||
skipped = True
|
skipped = True
|
||||||
@@ -362,16 +443,62 @@ def CaseInsensitiveCompare(s1, s2):
|
|||||||
|
|
||||||
def GetAnnotation(model, elementName):
|
def GetAnnotation(model, elementName):
|
||||||
""" Get an object's annotation used for tooltips """
|
""" Get an object's annotation used for tooltips """
|
||||||
if hasattr(model, "__xsdcomplextype__"):
|
if hasattr(model, "_complexType"):
|
||||||
|
ct = model._complexType
|
||||||
|
elif hasattr(model, "__xsdcomplextype__"):
|
||||||
ct = model.__xsdcomplextype__
|
ct = model.__xsdcomplextype__
|
||||||
if ct:
|
else:
|
||||||
el = ct.findElement(elementName)
|
ct = None
|
||||||
if el and el.annotation:
|
|
||||||
return el.annotation
|
if ct:
|
||||||
|
el = ct.findElement(elementName)
|
||||||
|
if el and el.annotation:
|
||||||
|
return el.annotation
|
||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
|
||||||
|
def GetDisplayName(doc, name):
|
||||||
|
if name:
|
||||||
|
appDocMgr = doc.GetAppDocMgr()
|
||||||
|
if appDocMgr:
|
||||||
|
name = appDocMgr.toDisplayTypeName(name)
|
||||||
|
else:
|
||||||
|
namespace, name = xmlutils.splitType(name)
|
||||||
|
if namespace and hasattr(doc.GetModel(), "getXmlNamespaces"):
|
||||||
|
for xmlkey, xmlval in doc.GetModel().getXmlNamespaces().iteritems():
|
||||||
|
if xmlval == namespace:
|
||||||
|
name = "%s:%s" % (xmlkey, name)
|
||||||
|
break
|
||||||
|
|
||||||
|
if name:
|
||||||
|
import activegrid.model.schema as schemalib
|
||||||
|
baseTypeName = schemalib.mapXsdType(name)
|
||||||
|
if baseTypeName:
|
||||||
|
name = baseTypeName
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
|
def GetInternalName(doc, name):
|
||||||
|
if name:
|
||||||
|
appDocMgr = doc.GetAppDocMgr()
|
||||||
|
if appDocMgr:
|
||||||
|
name = appDocMgr.toInternalTypeName(name)
|
||||||
|
else:
|
||||||
|
namespace, name = xmlutils.splitType(name)
|
||||||
|
if namespace and hasattr(doc.GetModel(), "getXmlNamespaces"):
|
||||||
|
for xmlkey, xmlval in doc.GetModel().getXmlNamespaces().iteritems():
|
||||||
|
if xmlkey == namespace:
|
||||||
|
name = "%s:%s" % (xmlval, name)
|
||||||
|
break
|
||||||
|
|
||||||
|
import activegrid.model.schema as schemalib
|
||||||
|
name = schemalib.mapAGType(name)
|
||||||
|
|
||||||
|
return name
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Methods for finding application level info
|
# Methods for finding application level info
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
@@ -435,7 +562,8 @@ def GetAppDocMgrForDoc(doc):
|
|||||||
|
|
||||||
|
|
||||||
def GetAppInfoLanguage(doc=None):
|
def GetAppInfoLanguage(doc=None):
|
||||||
from activegrid.server.deployment import LANGUAGE_DEFAULT
|
from activegrid.server.projectmodel import LANGUAGE_DEFAULT
|
||||||
|
|
||||||
if doc:
|
if doc:
|
||||||
language = doc.GetAppInfo().language
|
language = doc.GetAppInfo().language
|
||||||
else:
|
else:
|
||||||
@@ -449,3 +577,159 @@ def GetAppInfoLanguage(doc=None):
|
|||||||
doc.GetAppInfo().language = language # once it is selected, it must be set.
|
doc.GetAppInfo().language = language # once it is selected, it must be set.
|
||||||
|
|
||||||
return language
|
return language
|
||||||
|
|
||||||
|
def AddWsdlAgToProjectFromWsdlRegistration(wsdlRegistration):
|
||||||
|
"""Add wsdl ag for registry entry."""
|
||||||
|
|
||||||
|
wsdlPath = wsdlRegistration.path
|
||||||
|
rootPath = None
|
||||||
|
serviceRefName = wsdlRegistration.name
|
||||||
|
|
||||||
|
agwsDoc = _InitWsdlAg(wsdlPath, rootPath, serviceRefName)
|
||||||
|
|
||||||
|
if (agwsDoc == None):
|
||||||
|
return
|
||||||
|
|
||||||
|
serviceRef = agwsDoc.GetModel()
|
||||||
|
|
||||||
|
serviceRef.serviceType = wsdlRegistration.type
|
||||||
|
|
||||||
|
import activegrid.server.deployment as deployment
|
||||||
|
|
||||||
|
if (serviceRef.serviceType == deployment.SERVICE_LOCAL):
|
||||||
|
serviceRef.localService = deployment.LocalService(
|
||||||
|
wsdlRegistration.codeFile)
|
||||||
|
|
||||||
|
elif (serviceRef.serviceType == deployment.SERVICE_DATABASE):
|
||||||
|
serviceRef.databaseService = deployment.DatabaseService(
|
||||||
|
wsdlRegistration.datasourceName)
|
||||||
|
|
||||||
|
elif (serviceRef.serviceType == deployment.SERVICE_SOAP):
|
||||||
|
pass
|
||||||
|
|
||||||
|
elif (serviceRef.serviceType == deployment.SERVICE_RSS):
|
||||||
|
serviceRef.rssService = deployment.RssService(wsdlRegistration.feedUrl)
|
||||||
|
|
||||||
|
elif (serviceRef.serviceType == deployment.SERVICE_REST):
|
||||||
|
serviceRef.restService = deployment.RestService(
|
||||||
|
wsdlRegistration.baseUrl)
|
||||||
|
else:
|
||||||
|
raise AssertionError("Unknown service type")
|
||||||
|
|
||||||
|
_AddToProject(agwsDoc, addWsdl=True)
|
||||||
|
|
||||||
|
|
||||||
|
def AddWsdlAgToProject(wsdlPath, rootPath=fileutils.AG_SYSTEM_STATIC_VAR_REF,
|
||||||
|
serviceRefName=None, className=None, serviceType=None,
|
||||||
|
dataSourceName=None):
|
||||||
|
"""
|
||||||
|
wsdlPath: path to wsdl from rootPath. If wsdlPath is absolute, rootPath
|
||||||
|
is ignored. rootPath is also ignored when rootPath is set to None.
|
||||||
|
rootPath: defaults to ${AG_SYSTEM_STATIC}.
|
||||||
|
serviceRefName: If None, it will be set to the wsdl file name without
|
||||||
|
the .wsdl file extension.
|
||||||
|
className: if not None, will be used for the the wsdlag's ClassName.
|
||||||
|
serviceType: defaults to local.
|
||||||
|
dataSourceName: if serviceType is deployment.DATABASE, the ds must be
|
||||||
|
provided.
|
||||||
|
"""
|
||||||
|
import WsdlAgEditor
|
||||||
|
import XFormWizard
|
||||||
|
import activegrid.model.basedocmgr as basedocmgr
|
||||||
|
import activegrid.server.deployment as deployment
|
||||||
|
|
||||||
|
if (serviceType == None):
|
||||||
|
serviceType = deployment.SERVICE_LOCAL
|
||||||
|
|
||||||
|
|
||||||
|
agwsDoc = _InitWsdlAg(wsdlPath, rootPath, serviceRefName)
|
||||||
|
|
||||||
|
if (agwsDoc == None):
|
||||||
|
return
|
||||||
|
|
||||||
|
serviceRef = agwsDoc.GetModel()
|
||||||
|
|
||||||
|
serviceRef.serviceType = serviceType
|
||||||
|
|
||||||
|
if (serviceType == deployment.SERVICE_DATABASE and dataSourceName != None):
|
||||||
|
serviceRef.databaseService = deployment.DatabaseService(dataSourceName)
|
||||||
|
else:
|
||||||
|
serviceRef.localService = deployment.LocalService(className=className)
|
||||||
|
|
||||||
|
_AddToProject(agwsDoc)
|
||||||
|
|
||||||
|
|
||||||
|
def _AddToProject(agwsDoc, addWsdl=False):
|
||||||
|
import activegrid.model.basedocmgr as basedocmgr
|
||||||
|
projectDoc = GetCurrentProject()
|
||||||
|
agwsDoc.OnSaveDocument(agwsDoc.GetFilename())
|
||||||
|
|
||||||
|
files = [agwsDoc.fileName]
|
||||||
|
types = [basedocmgr.FILE_TYPE_SERVICE]
|
||||||
|
names = [agwsDoc.GetModel().name]
|
||||||
|
if (addWsdl):
|
||||||
|
m = agwsDoc.GetModel()
|
||||||
|
wsdlName = os.path.splitext(os.path.basename(m.filePath))[0]
|
||||||
|
appDocMgr = projectDoc.GetAppDocMgr()
|
||||||
|
if (appDocMgr.findService(wsdlName) == None):
|
||||||
|
m = agwsDoc.GetModel()
|
||||||
|
files.append(m.filePath)
|
||||||
|
types.append(None)
|
||||||
|
names.append(wsdlName)
|
||||||
|
|
||||||
|
ProjectEditor.ProjectAddFilesCommand(projectDoc, files, types=types,
|
||||||
|
names=names).Do()
|
||||||
|
|
||||||
|
|
||||||
|
def _InitWsdlAg(wsdlPath, rootPath=fileutils.AG_SYSTEM_STATIC_VAR_REF,
|
||||||
|
serviceRefName=None):
|
||||||
|
|
||||||
|
projectDoc = GetCurrentProject()
|
||||||
|
appDocMgr = projectDoc.GetAppDocMgr()
|
||||||
|
|
||||||
|
if (serviceRefName == None):
|
||||||
|
serviceRefName = os.path.splitext(os.path.basename(wsdlPath))[0]
|
||||||
|
|
||||||
|
if (appDocMgr.findServiceRef(serviceRefName) != None):
|
||||||
|
return None
|
||||||
|
|
||||||
|
import WsdlAgEditor
|
||||||
|
import XFormWizard
|
||||||
|
import activegrid.server.deployment as deployment
|
||||||
|
|
||||||
|
template = XFormWizard.GetTemplate(WsdlAgEditor.WsdlAgDocument)
|
||||||
|
ext = template.GetDefaultExtension()
|
||||||
|
fullPath = os.path.join(appDocMgr.homeDir, serviceRefName + ext)
|
||||||
|
|
||||||
|
agwsDoc = template.CreateDocument(
|
||||||
|
fullPath, flags=(wx.lib.docview.DOC_NO_VIEW|wx.lib.docview.DOC_NEW|
|
||||||
|
wx.lib.docview.DOC_OPEN_ONCE))
|
||||||
|
|
||||||
|
serviceRef = agwsDoc.GetModel()
|
||||||
|
serviceRef.name = serviceRefName
|
||||||
|
|
||||||
|
if (rootPath == None or os.path.isabs(wsdlPath)):
|
||||||
|
serviceRef.filePath = wsdlPath
|
||||||
|
else:
|
||||||
|
# make sure to use forward slashes for the path to the .wsdl
|
||||||
|
wsdlPath = wsdlPath.replace("\\", "/")
|
||||||
|
|
||||||
|
if not wsdlPath.startswith("/"):
|
||||||
|
wsdlPath = "/%s" % wsdlPath
|
||||||
|
serviceRef.filePath = "%s%s" % (rootPath, wsdlPath)
|
||||||
|
|
||||||
|
agwsDoc.fileName = fullPath
|
||||||
|
|
||||||
|
return agwsDoc
|
||||||
|
|
||||||
|
|
||||||
|
def GetSchemaName(schema):
|
||||||
|
return os.path.basename(schema.fileName)
|
||||||
|
|
||||||
|
|
||||||
|
class AGChoice(wx.Choice):
|
||||||
|
"""Extension to wx.Choice that fixes linux bug where first item of choices
|
||||||
|
passed into ctor would be visible, but not selected."""
|
||||||
|
def __init__(self, parent, id, choices=[]):
|
||||||
|
super(AGChoice, self).__init__(parent=parent, id=id)
|
||||||
|
self.AppendItems(choices)
|
||||||
|
File diff suppressed because it is too large
Load Diff
@@ -78,7 +78,7 @@ class XmlCtrl(CodeEditor.CodeCtrl):
|
|||||||
|
|
||||||
|
|
||||||
def SetViewDefaults(self):
|
def SetViewDefaults(self):
|
||||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Xml", hasWordWrap = True, hasTabs = True)
|
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Xml", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetFontAndColorFromConfig(self):
|
def GetFontAndColorFromConfig(self):
|
||||||
@@ -115,7 +115,7 @@ class XmlCtrl(CodeEditor.CodeCtrl):
|
|||||||
class XmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
class XmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||||
|
|
||||||
def __init__(self, parent, id):
|
def __init__(self, parent, id):
|
||||||
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Xml", label = "XML", hasWordWrap = True, hasTabs = True)
|
STCTextEditor.TextOptionsPanel.__init__(self, parent, id, configPrefix = "Xml", label = "XML", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||||
|
|
||||||
|
|
||||||
def GetIcon(self):
|
def GetIcon(self):
|
||||||
|
BIN
wxPython/samples/ide/activegrid/tool/bmp_source/activegrid.ico
Normal file
BIN
wxPython/samples/ide/activegrid/tool/bmp_source/activegrid.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 170 KiB |
@@ -1,7 +1,7 @@
|
|||||||
|
Middle-Mouse-Click on the tab for an open file will close the file.
|
||||||
Ctrl-Space in any editor does code completion.
|
Ctrl-Space in any editor does code completion.
|
||||||
Right-clicking on something in the 'Thing' column of the debugger's frame tab may allow you to introspect it for more information.
|
|
||||||
Right-Mouse-Click in Outline window allows you to change display sorting.
|
Right-Mouse-Click in Outline window allows you to change display sorting.
|
||||||
In an editor, you can add line markers via Ctrl-M and jump to the next marker with F4 or previous marker with Shift-F4.
|
In an editor, you can add line markers via Ctrl-M and jump to the next marker with F4 or previous marker with Shift-F4.
|
||||||
In an editor. you can use the numpad + and - keys to toggle folding.
|
In an editor. you can use the numpad + and - keys to toggle folding.
|
||||||
In 'Find in Directory', if you specify a file, it will display all matches in the Message Window.
|
Breakpoints for the debugger can be set while the process is running.
|
||||||
Breakpoints for the debugger can be set while the process is running
|
A split window can be closed by dragging the sash to one of its borders.
|
@@ -407,7 +407,13 @@ _SaferCreateProcess(appName=%r,
|
|||||||
elif env:
|
elif env:
|
||||||
uenv = {}
|
uenv = {}
|
||||||
for key, val in env.items():
|
for key, val in env.items():
|
||||||
uenv[unicode(key)] = unicode(val)
|
try:
|
||||||
|
uenv[unicode(key)] = unicode(val) # default encoding
|
||||||
|
except UnicodeError:
|
||||||
|
try:
|
||||||
|
uenv[unicode(key, 'iso-8859-1')] = unicode(val, 'iso-8859-1') # backup encoding
|
||||||
|
except UnicodeError:
|
||||||
|
log.warn('Skipping environment variable "%s" in execution process: unable to convert to unicode using either the default encoding or ISO-8859-1' % (key))
|
||||||
env = uenv
|
env = uenv
|
||||||
hProcess, hThread, processId, threadId\
|
hProcess, hThread, processId, threadId\
|
||||||
= win32process.CreateProcess(appName, cmd, processSA,
|
= win32process.CreateProcess(appName, cmd, processSA,
|
||||||
|
@@ -14,7 +14,16 @@ import copy
|
|||||||
import os
|
import os
|
||||||
import os.path
|
import os.path
|
||||||
import activegrid.util.xmlutils as xmlutils
|
import activegrid.util.xmlutils as xmlutils
|
||||||
from IDE import ACTIVEGRID_BASE_IDE
|
import activegrid.util.aglogging as aglogging
|
||||||
|
|
||||||
|
# REVIEW 07-Mar-06 stoens@activegrid.com -- Ideally move the pieces required
|
||||||
|
# to generate the .dpl file out of this module so there's no dependency on wx,
|
||||||
|
# instead of doing this try/catch (IDE drags in wx).
|
||||||
|
try:
|
||||||
|
from IDE import ACTIVEGRID_BASE_IDE
|
||||||
|
except:
|
||||||
|
ACTIVEGRID_BASE_IDE = False
|
||||||
|
|
||||||
if not ACTIVEGRID_BASE_IDE:
|
if not ACTIVEGRID_BASE_IDE:
|
||||||
import activegrid.model.basedocmgr as basedocmgr
|
import activegrid.model.basedocmgr as basedocmgr
|
||||||
import AppInfo
|
import AppInfo
|
||||||
@@ -27,64 +36,6 @@ if not ACTIVEGRID_BASE_IDE:
|
|||||||
PROJECT_VERSION_050730 = '10'
|
PROJECT_VERSION_050730 = '10'
|
||||||
PROJECT_VERSION_050826 = '11'
|
PROJECT_VERSION_050826 = '11'
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
# XML Marshalling Methods
|
|
||||||
#----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
def load(fileObject):
|
|
||||||
version = xmlutils.getAgVersion(fileObject.name)
|
|
||||||
# most current versions on top
|
|
||||||
if version == PROJECT_VERSION_050826:
|
|
||||||
fileObject.seek(0)
|
|
||||||
if ACTIVEGRID_BASE_IDE:
|
|
||||||
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
|
|
||||||
else:
|
|
||||||
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
|
|
||||||
project = xmlutils.load(fileObject.name, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
|
|
||||||
elif version == PROJECT_VERSION_050730:
|
|
||||||
fileObject.seek(0)
|
|
||||||
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
|
|
||||||
project = project.upgradeVersion()
|
|
||||||
else:
|
|
||||||
# assume it is old version without version number
|
|
||||||
fileObject.seek(0)
|
|
||||||
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
|
|
||||||
if project:
|
|
||||||
project = project.upgradeVersion()
|
|
||||||
else:
|
|
||||||
print "Project, unknown version:", version
|
|
||||||
return None
|
|
||||||
|
|
||||||
if project:
|
|
||||||
project._projectDir = os.path.dirname(fileObject.name)
|
|
||||||
project.RelativeToAbsPath()
|
|
||||||
|
|
||||||
return project
|
|
||||||
|
|
||||||
|
|
||||||
def save(fileObject, project, productionDeployment=False):
|
|
||||||
if not project._projectDir:
|
|
||||||
project._projectDir = os.path.dirname(fileObject.name)
|
|
||||||
project.AbsToRelativePath() # temporarily change it to relative paths for saving
|
|
||||||
if ACTIVEGRID_BASE_IDE:
|
|
||||||
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
|
|
||||||
else:
|
|
||||||
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
|
|
||||||
|
|
||||||
savedHomeDir = project.homeDir
|
|
||||||
if productionDeployment:
|
|
||||||
# for deployments, we don't want an abs path in homeDir since that
|
|
||||||
# would tie the app to the current filesystem. So unset it.
|
|
||||||
project.homeDir = None
|
|
||||||
|
|
||||||
xmlutils.save(fileObject.name, project, prettyPrint=True, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
|
|
||||||
|
|
||||||
if productionDeployment:
|
|
||||||
project.homeDir = savedHomeDir
|
|
||||||
|
|
||||||
project.RelativeToAbsPath() # swap it back to absolute path
|
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# Classes
|
# Classes
|
||||||
@@ -93,7 +44,7 @@ def save(fileObject, project, productionDeployment=False):
|
|||||||
class BaseProject(object):
|
class BaseProject(object):
|
||||||
|
|
||||||
__xmlname__ = "project"
|
__xmlname__ = "project"
|
||||||
__xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback')
|
__xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback', '_cacheEnabled')
|
||||||
__xmlattributes__ = ("_homeDir", "version")
|
__xmlattributes__ = ("_homeDir", "version")
|
||||||
__xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" }
|
__xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" }
|
||||||
__xmlflattensequence__ = { "_files":("file",) }
|
__xmlflattensequence__ = { "_files":("file",) }
|
||||||
@@ -107,9 +58,15 @@ class BaseProject(object):
|
|||||||
self._files = []
|
self._files = []
|
||||||
self._projectDir = None # default for homeDir, set on load
|
self._projectDir = None # default for homeDir, set on load
|
||||||
self._homeDir = None # user set homeDir for use in calculating relative path
|
self._homeDir = None # user set homeDir for use in calculating relative path
|
||||||
|
self._cacheEnabled = 0
|
||||||
if not ACTIVEGRID_BASE_IDE:
|
if not ACTIVEGRID_BASE_IDE:
|
||||||
self._appInfo = AppInfo.AppInfo()
|
self._appInfo = AppInfo.AppInfo()
|
||||||
|
|
||||||
|
|
||||||
|
def initialize(self):
|
||||||
|
for file in self._files:
|
||||||
|
file._parentProj = self
|
||||||
|
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
clone = Project()
|
clone = Project()
|
||||||
@@ -117,18 +74,13 @@ class BaseProject(object):
|
|||||||
clone._projectDir = self._projectDir
|
clone._projectDir = self._projectDir
|
||||||
clone._homeDir = self._homeDir
|
clone._homeDir = self._homeDir
|
||||||
if not ACTIVEGRID_BASE_IDE:
|
if not ACTIVEGRID_BASE_IDE:
|
||||||
clone._appInfo = self._appInfo
|
clone._appInfo = copy.copy(self._appInfo)
|
||||||
return clone
|
return clone
|
||||||
|
|
||||||
|
|
||||||
def initialize(self):
|
|
||||||
""" Required method for xmlmarshaller """
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def GetAppInfo(self):
|
def GetAppInfo(self):
|
||||||
return self._appInfo
|
return self._appInfo
|
||||||
|
|
||||||
|
|
||||||
def AddFile(self, filePath=None, logicalFolder=None, type=None, name=None, file=None):
|
def AddFile(self, filePath=None, logicalFolder=None, type=None, name=None, file=None):
|
||||||
""" Usage: self.AddFile(filePath, logicalFolder, type, name) # used for initial generation of object
|
""" Usage: self.AddFile(filePath, logicalFolder, type, name) # used for initial generation of object
|
||||||
@@ -138,7 +90,7 @@ class BaseProject(object):
|
|||||||
if file:
|
if file:
|
||||||
self._files.append(file)
|
self._files.append(file)
|
||||||
else:
|
else:
|
||||||
self._files.append(ProjectFile(filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
|
self._files.append(ProjectFile(self, filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
|
||||||
|
|
||||||
|
|
||||||
def RemoveFile(self, file):
|
def RemoveFile(self, file):
|
||||||
@@ -150,7 +102,7 @@ class BaseProject(object):
|
|||||||
for file in self._files:
|
for file in self._files:
|
||||||
if file.filePath == filePath:
|
if file.filePath == filePath:
|
||||||
return file
|
return file
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -160,6 +112,10 @@ class BaseProject(object):
|
|||||||
|
|
||||||
filePaths = property(_GetFilePaths)
|
filePaths = property(_GetFilePaths)
|
||||||
|
|
||||||
|
def _GetProjectFiles(self):
|
||||||
|
return self._files
|
||||||
|
projectFiles = property(_GetProjectFiles)
|
||||||
|
|
||||||
|
|
||||||
def _GetLogicalFolders(self):
|
def _GetLogicalFolders(self):
|
||||||
folders = []
|
folders = []
|
||||||
@@ -170,7 +126,7 @@ class BaseProject(object):
|
|||||||
|
|
||||||
|
|
||||||
logicalFolders = property(_GetLogicalFolders)
|
logicalFolders = property(_GetLogicalFolders)
|
||||||
|
|
||||||
|
|
||||||
def _GetPhysicalFolders(self):
|
def _GetPhysicalFolders(self):
|
||||||
physicalFolders = []
|
physicalFolders = []
|
||||||
@@ -189,11 +145,11 @@ class BaseProject(object):
|
|||||||
return self._homeDir
|
return self._homeDir
|
||||||
else:
|
else:
|
||||||
return self._projectDir
|
return self._projectDir
|
||||||
|
|
||||||
|
|
||||||
def _SetHomeDir(self, parentPath):
|
def _SetHomeDir(self, parentPath):
|
||||||
self._homeDir = parentPath
|
self._homeDir = parentPath
|
||||||
|
|
||||||
|
|
||||||
def _IsDefaultHomeDir(self):
|
def _IsDefaultHomeDir(self):
|
||||||
return (self._homeDir == None)
|
return (self._homeDir == None)
|
||||||
@@ -212,7 +168,7 @@ class BaseProject(object):
|
|||||||
if relFolder and relFolder not in relativeFolders:
|
if relFolder and relFolder not in relativeFolders:
|
||||||
relativeFolders.append(relFolder)
|
relativeFolders.append(relFolder)
|
||||||
return relativeFolders
|
return relativeFolders
|
||||||
|
|
||||||
|
|
||||||
def AbsToRelativePath(self):
|
def AbsToRelativePath(self):
|
||||||
for file in self._files:
|
for file in self._files:
|
||||||
@@ -224,6 +180,33 @@ class BaseProject(object):
|
|||||||
file.RelativeToAbsPath(self.homeDir)
|
file.RelativeToAbsPath(self.homeDir)
|
||||||
|
|
||||||
|
|
||||||
|
def _SetCache(self, enable):
|
||||||
|
"""
|
||||||
|
Only turn this on if your operation assumes files on disk won't change.
|
||||||
|
Once your operation is done, turn this back off.
|
||||||
|
Nested enables are allowed, only the last disable will disable the cache.
|
||||||
|
|
||||||
|
This bypasses the IsDocumentModificationDateCorrect call because the modification date check is too costly, it hits the disk and takes too long.
|
||||||
|
"""
|
||||||
|
if enable:
|
||||||
|
if self._cacheEnabled == 0:
|
||||||
|
# clear old cache, don't want to accidentally return stale value
|
||||||
|
for file in self._files:
|
||||||
|
file.ClearCache()
|
||||||
|
|
||||||
|
self._cacheEnabled += 1
|
||||||
|
else:
|
||||||
|
self._cacheEnabled -= 1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def _GetCache(self):
|
||||||
|
return (self._cacheEnabled > 0)
|
||||||
|
|
||||||
|
|
||||||
|
cacheEnabled = property(_GetCache, _SetCache)
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
# BaseDocumentMgr methods
|
# BaseDocumentMgr methods
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
@@ -231,7 +214,7 @@ class BaseProject(object):
|
|||||||
|
|
||||||
def fullPath(self, fileName):
|
def fullPath(self, fileName):
|
||||||
fileName = super(BaseProject, self).fullPath(fileName)
|
fileName = super(BaseProject, self).fullPath(fileName)
|
||||||
|
|
||||||
if os.path.isabs(fileName):
|
if os.path.isabs(fileName):
|
||||||
absPath = fileName
|
absPath = fileName
|
||||||
elif self.homeDir:
|
elif self.homeDir:
|
||||||
@@ -242,7 +225,7 @@ class BaseProject(object):
|
|||||||
|
|
||||||
|
|
||||||
def documentRefFactory(self, name, fileType, filePath):
|
def documentRefFactory(self, name, fileType, filePath):
|
||||||
return ProjectFile(filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
|
return ProjectFile(self, filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
|
||||||
|
|
||||||
|
|
||||||
def findAllRefs(self):
|
def findAllRefs(self):
|
||||||
@@ -256,8 +239,8 @@ class BaseProject(object):
|
|||||||
if not xformdir:
|
if not xformdir:
|
||||||
xformdir = self.homeDir
|
xformdir = self.homeDir
|
||||||
return xformdir
|
return xformdir
|
||||||
|
|
||||||
|
|
||||||
def setRefs(self, files):
|
def setRefs(self, files):
|
||||||
self._files = files
|
self._files = files
|
||||||
|
|
||||||
@@ -295,16 +278,17 @@ if ACTIVEGRID_BASE_IDE:
|
|||||||
else:
|
else:
|
||||||
class Project(BaseProject, basedocmgr.BaseDocumentMgr):
|
class Project(BaseProject, basedocmgr.BaseDocumentMgr):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class ProjectFile(object):
|
class ProjectFile(object):
|
||||||
__xmlname__ = "file"
|
__xmlname__ = "file"
|
||||||
__xmlexclude__ = ('_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
|
__xmlexclude__ = ('_parentProj', '_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
|
||||||
__xmlattributes__ = ["filePath", "logicalFolder", "type", "name"]
|
__xmlattributes__ = ["filePath", "logicalFolder", "type", "name"]
|
||||||
__xmldefaultnamespace__ = xmlutils.AG_NS_URL
|
__xmldefaultnamespace__ = xmlutils.AG_NS_URL
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
|
def __init__(self, parent=None, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
|
||||||
|
self._parentProj = parent
|
||||||
self.filePath = filePath
|
self.filePath = filePath
|
||||||
self.logicalFolder = logicalFolder
|
self.logicalFolder = logicalFolder
|
||||||
self.type = type
|
self.type = type
|
||||||
@@ -316,35 +300,44 @@ class ProjectFile(object):
|
|||||||
|
|
||||||
|
|
||||||
def _GetDocumentModel(self):
|
def _GetDocumentModel(self):
|
||||||
# possible bug is if document gets replaced outside of IDE, where we'll return previous doc.
|
if (self._docCallbackCacheReturnValue
|
||||||
# originally added a timestamp check but that increased the time again to 4x
|
and (self._parentProj.cacheEnabled or self._docCallbackCacheReturnValue.IsDocumentModificationDateCorrect())):
|
||||||
if self._docModelCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
|
|
||||||
return self._docModelCallbackCacheReturnValue
|
return self._docModelCallbackCacheReturnValue
|
||||||
|
|
||||||
if self._getDocCallback:
|
if self._getDocCallback:
|
||||||
self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
|
self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
|
||||||
return self._docModelCallbackCacheReturnValue
|
return self._docModelCallbackCacheReturnValue
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
document = property(_GetDocumentModel)
|
document = property(_GetDocumentModel)
|
||||||
|
|
||||||
|
|
||||||
def _GetDocument(self):
|
def _GetDocument(self):
|
||||||
# Hack, just return the IDE document wrapper that corresponds to the runtime document model
|
# Return the IDE document wrapper that corresponds to the runtime document model
|
||||||
# callers should have called ".document" before calling ".ideDocument"
|
if (self._docCallbackCacheReturnValue
|
||||||
if self._docCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
|
and (self._parentProj.cacheEnabled or self._docCallbackCacheReturnValue.IsDocumentModificationDateCorrect())):
|
||||||
return self._docCallbackCacheReturnValue
|
return self._docCallbackCacheReturnValue
|
||||||
|
|
||||||
|
if self._getDocCallback:
|
||||||
|
self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
|
||||||
|
return self._docCallbackCacheReturnValue
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
ideDocument = property(_GetDocument)
|
ideDocument = property(_GetDocument)
|
||||||
|
|
||||||
|
|
||||||
|
def ClearCache(self):
|
||||||
|
self._docCallbackCacheReturnValue = None
|
||||||
|
self._docModelCallbackCacheReturnValue = None
|
||||||
|
|
||||||
|
|
||||||
def _typeEnumeration(self):
|
def _typeEnumeration(self):
|
||||||
return basedocmgr.FILE_TYPE_LIST
|
return basedocmgr.FILE_TYPE_LIST
|
||||||
|
|
||||||
|
|
||||||
def _GetPhysicalFolder(self):
|
def _GetPhysicalFolder(self):
|
||||||
dir = None
|
dir = None
|
||||||
@@ -356,7 +349,7 @@ class ProjectFile(object):
|
|||||||
|
|
||||||
|
|
||||||
physicalFolder = property(_GetPhysicalFolder)
|
physicalFolder = property(_GetPhysicalFolder)
|
||||||
|
|
||||||
|
|
||||||
def GetRelativeFolder(self, parentPath):
|
def GetRelativeFolder(self, parentPath):
|
||||||
parentPathLen = len(parentPath)
|
parentPathLen = len(parentPath)
|
||||||
@@ -364,7 +357,7 @@ class ProjectFile(object):
|
|||||||
dir = None
|
dir = None
|
||||||
if self.filePath:
|
if self.filePath:
|
||||||
dir = os.path.dirname(self.filePath)
|
dir = os.path.dirname(self.filePath)
|
||||||
if dir.startswith(parentPath):
|
if dir.startswith(parentPath + os.sep):
|
||||||
dir = "." + dir[parentPathLen:] # convert to relative path
|
dir = "." + dir[parentPathLen:] # convert to relative path
|
||||||
if os.sep != '/':
|
if os.sep != '/':
|
||||||
dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
||||||
@@ -375,7 +368,7 @@ class ProjectFile(object):
|
|||||||
""" Used to convert path to relative path for saving (disk format) """
|
""" Used to convert path to relative path for saving (disk format) """
|
||||||
parentPathLen = len(parentPath)
|
parentPathLen = len(parentPath)
|
||||||
|
|
||||||
if self.filePath.startswith(parentPath):
|
if self.filePath.startswith(parentPath + os.sep):
|
||||||
self.filePath = "." + self.filePath[parentPathLen:] # convert to relative path
|
self.filePath = "." + self.filePath[parentPathLen:] # convert to relative path
|
||||||
if os.sep != '/':
|
if os.sep != '/':
|
||||||
self.filePath = self.filePath.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
self.filePath = self.filePath.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
||||||
@@ -385,8 +378,8 @@ class ProjectFile(object):
|
|||||||
|
|
||||||
def RelativeToAbsPath(self, parentPath):
|
def RelativeToAbsPath(self, parentPath):
|
||||||
""" Used to convert path to absolute path (for any necessary disk access) """
|
""" Used to convert path to absolute path (for any necessary disk access) """
|
||||||
if self.filePath.startswith("."): # relative to project file
|
if self.filePath.startswith("./"): # relative to project file
|
||||||
self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath))
|
self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath)) # also converts '/' to os.sep
|
||||||
|
|
||||||
|
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
@@ -399,21 +392,29 @@ class ProjectFile(object):
|
|||||||
import wx.lib.docview
|
import wx.lib.docview
|
||||||
if not self._doc:
|
if not self._doc:
|
||||||
docMgr = wx.GetApp().GetDocumentManager()
|
docMgr = wx.GetApp().GetDocumentManager()
|
||||||
|
|
||||||
doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW)
|
try:
|
||||||
if (doc == None): # already open
|
doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW)
|
||||||
docs = docMgr.GetDocuments()
|
if (doc == None): # already open
|
||||||
for d in docs:
|
docs = docMgr.GetDocuments()
|
||||||
if d.GetFilename() == self.filePath:
|
for d in docs:
|
||||||
doc = d
|
if d.GetFilename() == self.filePath:
|
||||||
break
|
doc = d
|
||||||
self._doc = doc
|
break
|
||||||
|
self._doc = doc
|
||||||
|
except Exception,e:
|
||||||
|
aglogging.reportException(e, stacktrace=True)
|
||||||
|
|
||||||
return self._doc
|
return self._doc
|
||||||
|
|
||||||
|
|
||||||
def _GetLocalServiceProcessName(self):
|
def _GetLocalServiceProcessName(self):
|
||||||
# HACK: temporary solution to getting process name from wsdlag file.
|
# HACK: temporary solution to getting process name from wsdlag file.
|
||||||
return self._GetDoc().GetModel().processName
|
doc = self._GetDoc()
|
||||||
|
if doc:
|
||||||
|
return doc.GetModel().processName
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
processName = property(_GetLocalServiceProcessName)
|
processName = property(_GetLocalServiceProcessName)
|
||||||
@@ -458,33 +459,39 @@ class ProjectFile(object):
|
|||||||
localServiceClassName = property(_GetLocalServiceClassName, _SetLocalServiceClassName)
|
localServiceClassName = property(_GetLocalServiceClassName, _SetLocalServiceClassName)
|
||||||
|
|
||||||
|
|
||||||
|
def getServiceParameter(self, message, part):
|
||||||
|
return self._GetDoc().GetModel().getServiceParameter(message, part)
|
||||||
|
|
||||||
|
|
||||||
# only activate this code if we programatically need to access these values
|
# only activate this code if we programatically need to access these values
|
||||||
## def _GetRssServiceBaseURL(self):
|
## def _GetRssServiceBaseURL(self):
|
||||||
## return self._GetDoc().GetModel().rssServiceBaseURL
|
## return self._GetDoc().GetModel().rssServiceBaseURL
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## def _SetRssServiceBaseURL(self, baseURL):
|
## def _SetRssServiceBaseURL(self, baseURL):
|
||||||
## self._GetDoc().GetModel().rssServiceBaseURL = baseURL
|
## self._GetDoc().GetModel().rssServiceBaseURL = baseURL
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL)
|
## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL)
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## def _GetRssServiceRssVersion(self):
|
## def _GetRssServiceRssVersion(self):
|
||||||
## return self._GetDoc().GetModel().rssServiceRssVersion
|
## return self._GetDoc().GetModel().rssServiceRssVersion
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## def _SetRssServiceRssVersion(self, rssVersion):
|
## def _SetRssServiceRssVersion(self, rssVersion):
|
||||||
## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion
|
## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion
|
||||||
##
|
##
|
||||||
##
|
##
|
||||||
## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion)
|
## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion)
|
||||||
|
|
||||||
|
|
||||||
def _GetServiceRefServiceType(self):
|
def _GetServiceRefServiceType(self):
|
||||||
# HACK: temporary solution to getting service type from wsdlag file.
|
# HACK: temporary solution to getting service type from wsdlag file.
|
||||||
model = self._GetDoc().GetModel()
|
doc = self._GetDoc()
|
||||||
|
if not doc:
|
||||||
|
return None
|
||||||
|
model = doc.GetModel()
|
||||||
if hasattr(model, 'serviceType'):
|
if hasattr(model, 'serviceType'):
|
||||||
return model.serviceType
|
return model.serviceType
|
||||||
else:
|
else:
|
||||||
@@ -494,25 +501,27 @@ class ProjectFile(object):
|
|||||||
def _SetServiceRefServiceType(self, serviceType):
|
def _SetServiceRefServiceType(self, serviceType):
|
||||||
# HACK: temporary solution to getting service type from wsdlag file.
|
# HACK: temporary solution to getting service type from wsdlag file.
|
||||||
self._GetDoc().GetModel().serviceType = serviceType
|
self._GetDoc().GetModel().serviceType = serviceType
|
||||||
|
|
||||||
|
|
||||||
serviceType = property(_GetServiceRefServiceType, _SetServiceRefServiceType)
|
serviceType = property(_GetServiceRefServiceType, _SetServiceRefServiceType)
|
||||||
|
|
||||||
|
|
||||||
def getExternalPackage(self):
|
def getExternalPackage(self):
|
||||||
# HACK: temporary solution to getting custom code filename from wsdlag file.
|
# HACK: temporary solution to getting custom code filename from wsdlag file.
|
||||||
import activegrid.server.deployment as deploymentlib
|
import activegrid.model.projectmodel as projectmodel
|
||||||
|
import wx
|
||||||
|
import ProjectEditor
|
||||||
|
|
||||||
appInfo = self._GetDoc().GetAppInfo()
|
appInfo = self._GetDoc().GetAppInfo()
|
||||||
|
|
||||||
if appInfo.language == None:
|
if appInfo.language == None:
|
||||||
language = deploymentlib.LANGUAGE_DEFAULT
|
language = wx.ConfigBase_Get().Read(ProjectEditor.APP_LAST_LANGUAGE, projectmodel.LANGUAGE_DEFAULT)
|
||||||
else:
|
else:
|
||||||
language = appInfo.language
|
language = appInfo.language
|
||||||
|
|
||||||
if language == deploymentlib.LANGUAGE_PYTHON:
|
if language == projectmodel.LANGUAGE_PYTHON:
|
||||||
suffix = ".py"
|
suffix = ".py"
|
||||||
elif language == deploymentlib.LANGUAGE_PHP:
|
elif language == projectmodel.LANGUAGE_PHP:
|
||||||
suffix = ".php"
|
suffix = ".php"
|
||||||
pyFilename = self.name + suffix
|
pyFilename = self.name + suffix
|
||||||
return self._GetDoc().GetAppDocMgr().fullPath(pyFilename)
|
return self._GetDoc().GetAppDocMgr().fullPath(pyFilename)
|
||||||
@@ -543,7 +552,63 @@ class Project_10:
|
|||||||
def upgradeVersion(self):
|
def upgradeVersion(self):
|
||||||
currModel = Project()
|
currModel = Project()
|
||||||
for file in self._files:
|
for file in self._files:
|
||||||
currModel._files.append(ProjectFile(file))
|
currModel._files.append(ProjectFile(currModel, file))
|
||||||
return currModel
|
return currModel
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# XML Marshalling Methods
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if ACTIVEGRID_BASE_IDE:
|
||||||
|
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
|
||||||
|
else:
|
||||||
|
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile,
|
||||||
|
"ag:appInfo" : AppInfo.AppInfo,
|
||||||
|
"ag:deploymentDataSource" : AppInfo.DeploymentDataSource,
|
||||||
|
"ag:dataSourceBinding" : AppInfo.DataSourceBinding}
|
||||||
|
|
||||||
|
def load(fileObject):
|
||||||
|
version = xmlutils.getAgVersion(fileObject.name)
|
||||||
|
# most current versions on top
|
||||||
|
if version == PROJECT_VERSION_050826:
|
||||||
|
fileObject.seek(0)
|
||||||
|
project = xmlutils.load(fileObject.name, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES, createGenerics=True)
|
||||||
|
elif version == PROJECT_VERSION_050730:
|
||||||
|
fileObject.seek(0)
|
||||||
|
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10}, createGenerics=True)
|
||||||
|
project = project.upgradeVersion()
|
||||||
|
else:
|
||||||
|
# assume it is old version without version number
|
||||||
|
fileObject.seek(0)
|
||||||
|
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10}, createGenerics=True)
|
||||||
|
if project:
|
||||||
|
project = project.upgradeVersion()
|
||||||
|
else:
|
||||||
|
print "Project, unknown version:", version
|
||||||
|
return None
|
||||||
|
|
||||||
|
if project:
|
||||||
|
project._projectDir = os.path.dirname(fileObject.name)
|
||||||
|
project.RelativeToAbsPath()
|
||||||
|
|
||||||
|
return project
|
||||||
|
|
||||||
|
|
||||||
|
def save(fileObject, project, productionDeployment=False):
|
||||||
|
if not project._projectDir:
|
||||||
|
project._projectDir = os.path.dirname(fileObject.name)
|
||||||
|
project.AbsToRelativePath() # temporarily change it to relative paths for saving
|
||||||
|
savedHomeDir = project.homeDir
|
||||||
|
if productionDeployment:
|
||||||
|
# for deployments, we don't want an abs path in homeDir since that
|
||||||
|
# would tie the app to the current filesystem. So unset it.
|
||||||
|
project.homeDir = None
|
||||||
|
|
||||||
|
xmlutils.save(fileObject.name, project, prettyPrint=True, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
|
||||||
|
|
||||||
|
if productionDeployment:
|
||||||
|
project.homeDir = savedHomeDir
|
||||||
|
|
||||||
|
project.RelativeToAbsPath() # swap it back to absolute path
|
||||||
|
|
||||||
|
@@ -19,6 +19,7 @@ import logging.config
|
|||||||
from activegrid.util.lang import *
|
from activegrid.util.lang import *
|
||||||
import activegrid.util.objutils as objutils
|
import activegrid.util.objutils as objutils
|
||||||
import activegrid.util.sysutils as sysutils
|
import activegrid.util.sysutils as sysutils
|
||||||
|
import activegrid.util.appdirs as appdirs
|
||||||
|
|
||||||
LEVEL_FATAL = logging.FATAL
|
LEVEL_FATAL = logging.FATAL
|
||||||
LEVEL_ERROR = logging.ERROR
|
LEVEL_ERROR = logging.ERROR
|
||||||
@@ -27,38 +28,47 @@ LEVEL_INFO = logging.INFO
|
|||||||
LEVEL_DEBUG = logging.DEBUG
|
LEVEL_DEBUG = logging.DEBUG
|
||||||
|
|
||||||
EXCEPTION_INFO = 'exceptionInfo'
|
EXCEPTION_INFO = 'exceptionInfo'
|
||||||
|
loggingInitialized = False
|
||||||
|
|
||||||
LOG_MODE_IDE = 1
|
LOG_MODE_IDE = 1
|
||||||
LOG_MODE_TESTRUN = 2
|
LOG_MODE_TESTRUN = 2
|
||||||
LOG_MODE_RUN = 3
|
LOG_MODE_RUN = 3
|
||||||
def initLogging(mode):
|
def initLogging(mode, force=False):
|
||||||
configFile = None
|
global ag_debugLogger, loggingInitialized
|
||||||
if (mode == LOG_MODE_IDE):
|
if (force or not loggingInitialized):
|
||||||
configFile = os.getenv("AG_LOGCONFIG_IDE")
|
loggingInitialized = True
|
||||||
elif (mode == LOG_MODE_TESTRUN):
|
configFile = None
|
||||||
configFile = os.getenv("AG_LOGCONFIG_TESTRUN")
|
|
||||||
else:
|
|
||||||
configFile = os.getenv("AG_LOGCONFIG_RUN")
|
|
||||||
if ((configFile == None) or not os.path.exists(configFile)):
|
|
||||||
if (mode == LOG_MODE_IDE):
|
if (mode == LOG_MODE_IDE):
|
||||||
configFile = "IDELog"
|
configFile = os.getenv("AG_LOGCONFIG_IDE")
|
||||||
elif (mode == LOG_MODE_TESTRUN):
|
elif (mode == LOG_MODE_TESTRUN):
|
||||||
configFile = "TestRunLog"
|
configFile = os.getenv("AG_LOGCONFIG_PYTESTRUN")
|
||||||
else:
|
else:
|
||||||
configFile = "RunLog"
|
configFile = os.getenv("AG_LOGCONFIG_RUN")
|
||||||
configFile = sysutils.mainModuleDir + "/py" + configFile + ".ini"
|
if ((configFile == None) or not os.path.exists(configFile)):
|
||||||
if (os.path.exists(configFile)):
|
if (mode == LOG_MODE_IDE):
|
||||||
fileConfig(configFile)
|
configFile = "IDELog"
|
||||||
else:
|
elif (mode == LOG_MODE_TESTRUN):
|
||||||
defaultStream = sys.stderr
|
configFile = "TestRunLog"
|
||||||
if (mode == LOG_MODE_RUN):
|
else:
|
||||||
defaultStream = sys.stdout
|
configFile = "RunLog"
|
||||||
handler = logging.StreamHandler(defaultStream)
|
configFile = os.path.join(appdirs.getSystemDir(appdirs.AG_LOGS_DIR), "py" + configFile + ".ini")
|
||||||
handler.setLevel(logging.INFO)
|
if (os.path.exists(configFile)):
|
||||||
handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s: %(message)s"))
|
print "Using logging configuration file: %s" % configFile
|
||||||
logging.getLogger().addHandler(handler)
|
fileConfig(configFile)
|
||||||
return configFile
|
else:
|
||||||
|
print "*** Cannot find logging configuration file (%s) -- setting default logging level to WARN ***" % (configFile)
|
||||||
|
defaultStream = sys.stderr
|
||||||
|
if (mode == LOG_MODE_RUN):
|
||||||
|
defaultStream = sys.stdout
|
||||||
|
handler = logging.StreamHandler(defaultStream)
|
||||||
|
handler.setLevel(logging.DEBUG)
|
||||||
|
handler.setFormatter(logging.Formatter("%(asctime)s %(name)s %(levelname)s: %(message)s"))
|
||||||
|
logging.getLogger().addHandler(handler)
|
||||||
|
logging.getLogger().setLevel(logging.WARN)
|
||||||
|
ag_debugLogger = logging.getLogger("activegrid.debug")
|
||||||
|
ag_debugLogger.setLevel(logging.DEBUG)
|
||||||
|
return configFile
|
||||||
|
|
||||||
ag_debugLogger = logging.getLogger("activegrid.debug")
|
ag_debugLogger = logging.getLogger("activegrid.debug")
|
||||||
|
|
||||||
def log(logger, level, msg, *params):
|
def log(logger, level, msg, *params):
|
||||||
@@ -181,21 +191,18 @@ def addExceptionInfo(e, key, value):
|
|||||||
if not e.exceptionInfo.has_key(key): # Never overwrite exception info since we assume earlier info is more specific
|
if not e.exceptionInfo.has_key(key): # Never overwrite exception info since we assume earlier info is more specific
|
||||||
e.exceptionInfo[key] = value
|
e.exceptionInfo[key] = value
|
||||||
|
|
||||||
def reportException(out=None, stacktrace=False, diffable=False, exception=None):
|
def reportException(exception, out=None, stacktrace=False, diffable=False):
|
||||||
exstr = exceptionToString(exception, stacktrace, diffable)
|
exstr = exceptionToString(exception, stacktrace, diffable)
|
||||||
if (out == None):
|
if (out == None):
|
||||||
print exstr
|
print exstr
|
||||||
else:
|
else:
|
||||||
print >> out, exstr
|
print >> out, exstr
|
||||||
|
|
||||||
def exceptionToString(exception=None, stacktrace=False, diffable=False):
|
def exceptionToString(exception, stacktrace=False, diffable=False):
|
||||||
if (exception == None):
|
extype = objutils.typeToString(exception)
|
||||||
extype, val, t = sys.exc_info()
|
val = exception
|
||||||
else:
|
if (stacktrace):
|
||||||
extype = objutils.typeToString(exception)
|
e,v,t = sys.exc_info()
|
||||||
val = exception
|
|
||||||
if (stacktrace):
|
|
||||||
e,v,t = sys.exc_info()
|
|
||||||
if (diffable):
|
if (diffable):
|
||||||
exstr = removeFileRefs(str(val))
|
exstr = removeFileRefs(str(val))
|
||||||
else:
|
else:
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
# Name: appdirs.py
|
# Name: appdirs.py
|
||||||
# Purpose: Utilities for retrieving special application dirs
|
# Purpose: Utilities for retrieving special application dirs
|
||||||
#
|
#
|
||||||
# Author: Kevin Ollivier
|
# Author: Kevin Ollivier, Jeff Norton
|
||||||
#
|
#
|
||||||
# Created: 8/27/05
|
# Created: 8/27/05
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
@@ -10,50 +10,117 @@
|
|||||||
# License: wxWindows License
|
# License: wxWindows License
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
# NOTE: This was made a separate file because it depends upon the
|
from activegrid.util.lang import *
|
||||||
# wx.StandardPaths module, and thus, on wxWidgets, unlike other
|
|
||||||
# utils modules. I wanted to ensure this module is never loaded
|
|
||||||
# from the web server, etc.
|
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
import string
|
import string
|
||||||
import wx
|
import activegrid.util.sysutils as sysutils
|
||||||
|
|
||||||
def isWindows():
|
def _getSystemDir(kind):
|
||||||
return os.name == 'nt'
|
if (kind == AG_LOGS_DIR):
|
||||||
|
return os.path.join(getSystemDir(AG_SYSTEM_DIR) , "logs")
|
||||||
def _generateDocumentsDir():
|
elif (kind == AG_DEMOS_DIR):
|
||||||
path = ""
|
return os.path.join(getSystemDir(AG_SYSTEM_DIR), "demos")
|
||||||
if sys.platform == "win32":
|
else:
|
||||||
from win32com.shell import shell, shellcon
|
path = ""
|
||||||
path=shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
|
if (sysutils.isServer()):
|
||||||
elif sys.platform == "darwin":
|
path = os.getenv("ACTIVEGRID_SERVER_HOME")
|
||||||
import macfs, MACFS
|
if ((path is None) or (len(path) < 1)):
|
||||||
fsspec_disk, fsspec_desktop = macfs.FindFolder( MACFS.kOnSystemDisk, MACFS.kDocumentsFolderType, 0)
|
path = sysutils.mainModuleDir
|
||||||
path = macfs.FSSpec((fsspec_disk, fsspec_desktop, '')).as_pathname()
|
else:
|
||||||
|
path = os.getenv("AG_DOCUMENTS_DIR")
|
||||||
if path == "":
|
if ((path is None) or (len(path) < 1)):
|
||||||
path = os.path.expanduser("~")
|
if sysutils.isWindows():
|
||||||
|
ifDefPy()
|
||||||
return path
|
try:
|
||||||
|
from win32com.shell import shell, shellcon
|
||||||
|
path = shell.SHGetFolderPath(0, shellcon.CSIDL_PERSONAL, None, 0)
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
endIfDef()
|
||||||
|
if ((path is None) or (len(path) < 1)):
|
||||||
|
homedrive = asString(os.getenv("HOMEDRIVE"))
|
||||||
|
homepath = os.getenv("HOMEPATH")
|
||||||
|
## if ((homedrive is not None) and (len(homedrive) > 0) and (homepath is not None) and (len(homepath) > 0)):
|
||||||
|
path = os.path.join(homedrive, homepath, "MYDOCU~1")
|
||||||
|
else:
|
||||||
|
ifDefPy()
|
||||||
|
if sys.platform == "darwin":
|
||||||
|
try:
|
||||||
|
import macfs
|
||||||
|
import MACFS
|
||||||
|
fsspec_disk, fsspec_desktop = macfs.FindFolder(MACFS.kOnSystemDisk, MACFS.kDocumentsFolderType, 0)
|
||||||
|
path = macfs.FSSpec((fsspec_disk, fsspec_desktop, '')).as_pathname()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
endIfDef()
|
||||||
|
|
||||||
|
ifDefPy()
|
||||||
|
if ((path is None) or (len(path) < 1)):
|
||||||
|
path = os.path.expanduser("~")
|
||||||
|
endIfDef()
|
||||||
|
if ((path is None) or (len(path) < 1)):
|
||||||
|
path = "/"
|
||||||
|
path = os.path.join(path, "ActiveGrid")
|
||||||
|
|
||||||
documents_folder = _generateDocumentsDir()
|
return path
|
||||||
|
|
||||||
|
|
||||||
|
AG_SYSTEM_DIR = 0
|
||||||
|
AG_LOGS_DIR = 1
|
||||||
|
AG_DEMOS_DIR = 2
|
||||||
|
|
||||||
|
__systemDir = None
|
||||||
|
__logsDir = None
|
||||||
|
__demosDir = None
|
||||||
|
|
||||||
|
def getSystemDir(kind=0):
|
||||||
|
if (kind == AG_SYSTEM_DIR):
|
||||||
|
global __systemDir
|
||||||
|
if (__systemDir is None):
|
||||||
|
__systemDir = _getSystemDir(kind)
|
||||||
|
return __systemDir
|
||||||
|
elif (kind == AG_LOGS_DIR):
|
||||||
|
global __logsDir
|
||||||
|
if (__logsDir is None):
|
||||||
|
__logsDir = _getSystemDir(kind)
|
||||||
|
return __logsDir
|
||||||
|
elif (kind == AG_DEMOS_DIR):
|
||||||
|
global __demosDir
|
||||||
|
if (__demosDir is None):
|
||||||
|
__demosDir = _getSystemDir(kind)
|
||||||
|
return __demosDir
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
# NOTE: We don't set this at startup because wxStandardPaths needs a running
|
# NOTE: We don't set this at startup because wxStandardPaths needs a running
|
||||||
# application object. This makes sure the wxApp will always be created when
|
# application object. This makes sure the wxApp will always be created when
|
||||||
# we get the folder.
|
# we get the folder.
|
||||||
|
ifDefPy()
|
||||||
def getAppDataFolder():
|
def getAppDataFolder():
|
||||||
# wxStandardPaths requires a running app
|
try:
|
||||||
if wx.GetApp() and wx.Platform != "__WXGTK__":
|
# NOTE: cannot import wx from the server
|
||||||
data_folder = wx.StandardPaths.Get().GetUserDataDir()
|
import wx
|
||||||
if not os.path.exists(data_folder):
|
# wxStandardPaths requires a running app
|
||||||
os.mkdir(data_folder)
|
if wx.GetApp() and wx.Platform != "__WXGTK__":
|
||||||
return data_folder
|
data_folder = wx.StandardPaths.Get().GetUserDataDir()
|
||||||
else:
|
if not os.path.exists(data_folder):
|
||||||
# wxBug: on *nix, it wants to point to ~/.appname, but
|
os.mkdir(data_folder)
|
||||||
# so does wxConfig... For now, redirect this to ~/.appbuilder
|
return data_folder
|
||||||
# when this is fixed, we'll migrate settings to the correct place
|
except:
|
||||||
return os.path.join(os.path.expanduser("~"), ".appbuilder")
|
pass
|
||||||
|
# wxBug: on *nix, it wants to point to ~/.appname, but
|
||||||
|
# so does wxConfig... For now, redirect this to ~/.appbuilder
|
||||||
|
# when this is fixed, we'll migrate settings to the correct place
|
||||||
|
return os.path.join(os.path.expanduser("~"), ".appbuilder")
|
||||||
|
endIfDef()
|
||||||
|
|
||||||
return ""
|
ifDefPy()
|
||||||
|
def createSystemDirs():
|
||||||
|
if (not os.path.exists(getSystemDir())):
|
||||||
|
os.mkdir(getSystemDir())
|
||||||
|
if (not os.path.exists(getSystemDir(AG_LOGS_DIR))):
|
||||||
|
os.mkdir(getSystemDir(AG_LOGS_DIR))
|
||||||
|
if (not os.path.exists(getSystemDir(AG_DEMOS_DIR))):
|
||||||
|
os.mkdir(getSystemDir(AG_DEMOS_DIR))
|
||||||
|
endIfDef()
|
||||||
|
118
wxPython/samples/ide/activegrid/util/datetimeparser.py
Normal file
118
wxPython/samples/ide/activegrid/util/datetimeparser.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: datetimeparser.py
|
||||||
|
#
|
||||||
|
# Purpose: - Instantiate datetime.datetime/date instance from a string
|
||||||
|
# date representation.
|
||||||
|
# Uses dateutil from http://labix.org/python-dateutil.
|
||||||
|
#
|
||||||
|
# - Creates string representation of datetime/date instance.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Author: Simon Toens
|
||||||
|
#
|
||||||
|
# Created: 28-Feb-06
|
||||||
|
# CVS-ID:
|
||||||
|
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||||
|
# License: wxWindows License
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
|
try:
|
||||||
|
import dateutil.parser
|
||||||
|
DATEUTIL_INSTALLED = True
|
||||||
|
except ImportError:
|
||||||
|
DATEUTIL_INSTALLED = False
|
||||||
|
|
||||||
|
ISO_8601_DATE_FORMAT = "%Y-%m-%d"
|
||||||
|
ISO_8601_TIME_FORMAT = "%H:%M:%S"
|
||||||
|
ISO_8601_DATETIME_FORMAT = "%s %s" %(ISO_8601_DATE_FORMAT,
|
||||||
|
ISO_8601_TIME_FORMAT)
|
||||||
|
|
||||||
|
DEFAULT_DATETIME = datetime.datetime(1, 1, 1, 0, 0, 0, 0)
|
||||||
|
|
||||||
|
|
||||||
|
def format(dateobj, formatstr=None):
|
||||||
|
if (formatstr != None and _isDateTimeObject(dateobj)):
|
||||||
|
return dateobj.strftime(str(formatstr))
|
||||||
|
return str(dateobj)
|
||||||
|
|
||||||
|
|
||||||
|
def parse(datestr, formatstr=None, asdate=False, astime=False):
|
||||||
|
"""Instantiates and returns a datetime instance from the datestr datetime
|
||||||
|
representation.
|
||||||
|
|
||||||
|
Optionally, a format string may be used. The format is only loosely
|
||||||
|
interpreted, its only purpose beeing to determine if the year is first
|
||||||
|
or last in datestr, and whether the day is in front or follows the
|
||||||
|
month. If no formatstr is passed in, dateutil tries its best to parse
|
||||||
|
the datestr. The default date format is YYYY-mm-dd HH:SS.
|
||||||
|
|
||||||
|
If asdate is True, returns a date instance instead of a datetime
|
||||||
|
instance, if astime is True, returns a time instance instead of a
|
||||||
|
datetime instance."""
|
||||||
|
|
||||||
|
|
||||||
|
dayfirst, yearfirst = _getDayFirstAndYearFirst(formatstr)
|
||||||
|
|
||||||
|
rtn = None
|
||||||
|
|
||||||
|
try:
|
||||||
|
if DATEUTIL_INSTALLED:
|
||||||
|
rtn = dateutil.parser.parse(str(datestr), fuzzy=True,
|
||||||
|
dayfirst=dayfirst, yearfirst=yearfirst,
|
||||||
|
default=DEFAULT_DATETIME)
|
||||||
|
else:
|
||||||
|
rtn = DEFAULT_DATETIME
|
||||||
|
except:
|
||||||
|
rtn = DEFAULT_DATETIME
|
||||||
|
|
||||||
|
if (asdate and isinstance(rtn, datetime.datetime)):
|
||||||
|
rtn = datetime.date(rtn.year, rtn.month, rtn.day)
|
||||||
|
elif (astime and isinstance(rtn, datetime.datetime)):
|
||||||
|
rtn = datetime.time(rtn.hour, rtn.minute, rtn.second, rtn.microsecond)
|
||||||
|
|
||||||
|
return rtn
|
||||||
|
|
||||||
|
|
||||||
|
def _isDateTimeObject(obj):
|
||||||
|
return (isinstance(obj, datetime.datetime) or
|
||||||
|
isinstance(obj, datetime.date) or
|
||||||
|
isinstance(obj, datetime.time))
|
||||||
|
|
||||||
|
|
||||||
|
def _getDayFirstAndYearFirst(formatstr):
|
||||||
|
dayFirst = False
|
||||||
|
yearFirst = False
|
||||||
|
|
||||||
|
gotYear = False
|
||||||
|
gotMonth = False
|
||||||
|
gotDay = False
|
||||||
|
|
||||||
|
if (formatstr == None):
|
||||||
|
formatstr = ""
|
||||||
|
|
||||||
|
for c in formatstr:
|
||||||
|
if (c.lower() == "y"):
|
||||||
|
if (gotYear):
|
||||||
|
continue
|
||||||
|
if (not gotDay and not gotMonth):
|
||||||
|
yearFirst = True
|
||||||
|
gotYear = True
|
||||||
|
|
||||||
|
elif (c.lower() == "m"):
|
||||||
|
if (gotMonth):
|
||||||
|
continue
|
||||||
|
if (not gotDay):
|
||||||
|
dayFirst = False
|
||||||
|
gotMonth = True
|
||||||
|
|
||||||
|
elif (c.lower() == "d"):
|
||||||
|
if (gotDay):
|
||||||
|
continue
|
||||||
|
if (not gotMonth):
|
||||||
|
dayFirst = True
|
||||||
|
gotDay = True
|
||||||
|
|
||||||
|
|
||||||
|
return dayFirst, yearFirst
|
@@ -19,6 +19,7 @@ import zipfile
|
|||||||
|
|
||||||
import activegrid.util.aglogging as aglogging
|
import activegrid.util.aglogging as aglogging
|
||||||
import activegrid.util.sysutils as sysutils
|
import activegrid.util.sysutils as sysutils
|
||||||
|
import activegrid.util.utillang as utillang
|
||||||
from activegrid.util.lang import *
|
from activegrid.util.lang import *
|
||||||
|
|
||||||
global fileutilsLogger
|
global fileutilsLogger
|
||||||
@@ -31,6 +32,65 @@ fileutilsLogger = logging.getLogger("activegrid.util.fileutils")
|
|||||||
aglogging.setLevelFatal(fileutilsLogger)
|
aglogging.setLevelFatal(fileutilsLogger)
|
||||||
#logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
|
#logging.getLogger().addHandler(logging.StreamHandler(sys.stderr))
|
||||||
|
|
||||||
|
def addRef(varname):
|
||||||
|
return "${%s}" % varname
|
||||||
|
|
||||||
|
AG_SYSTEM_VAR_NAMES = [] # all AG System vars, with ${} syntax
|
||||||
|
|
||||||
|
AG_SYSTEM_VAR = "AG_SYSTEM"
|
||||||
|
AG_SYSTEM_VAR_REF = addRef(AG_SYSTEM_VAR)
|
||||||
|
AG_SYSTEM_VAR_NAMES.append(AG_SYSTEM_VAR_REF)
|
||||||
|
|
||||||
|
AG_SYSTEM_STATIC_VAR = "AG_SYSTEM_STATIC"
|
||||||
|
AG_SYSTEM_STATIC_VAR_REF = addRef(AG_SYSTEM_STATIC_VAR)
|
||||||
|
AG_SYSTEM_VAR_NAMES.append(AG_SYSTEM_STATIC_VAR_REF)
|
||||||
|
|
||||||
|
AG_APP_VAR = "AG_APP"
|
||||||
|
AG_APP_STATIC_VAR = "AG_APP_STATIC"
|
||||||
|
|
||||||
|
# _initAGSystemVars needs to be called to initialize the following two
|
||||||
|
# containers:
|
||||||
|
EXPANDED_AG_SYSTEM_VARS = {} # ${varname} -> value (path)
|
||||||
|
# ${varname}, ordered from longest to shortest path value
|
||||||
|
AG_SYSTEM_VARS_LENGTH_ORDER = []
|
||||||
|
|
||||||
|
def _initAGSystemVars():
|
||||||
|
if (len(EXPANDED_AG_SYSTEM_VARS) > 0):
|
||||||
|
return
|
||||||
|
|
||||||
|
for v in AG_SYSTEM_VAR_NAMES:
|
||||||
|
EXPANDED_AG_SYSTEM_VARS[v] = os.path.abspath(expandVars(v))
|
||||||
|
AG_SYSTEM_VARS_LENGTH_ORDER.append(v)
|
||||||
|
|
||||||
|
AG_SYSTEM_VARS_LENGTH_ORDER.sort(_sortByValLength)
|
||||||
|
|
||||||
|
|
||||||
|
def parameterizePathWithAGSystemVar(inpath):
|
||||||
|
"""Returns parameterized path if path starts with a known AG directory. Otherwise returns path as it was passed in."""
|
||||||
|
_initAGSystemVars()
|
||||||
|
path = inpath
|
||||||
|
if not sysutils.isWindows():
|
||||||
|
# ensure we have forward slashes
|
||||||
|
path = path.replace("\\", "/")
|
||||||
|
|
||||||
|
path = os.path.abspath(path)
|
||||||
|
|
||||||
|
for varname in AG_SYSTEM_VARS_LENGTH_ORDER:
|
||||||
|
varval = EXPANDED_AG_SYSTEM_VARS[varname]
|
||||||
|
if path.startswith(varval):
|
||||||
|
return path.replace(varval, varname)
|
||||||
|
|
||||||
|
return inpath
|
||||||
|
|
||||||
|
def startsWithAgSystemVar(path):
|
||||||
|
"""Returns True if path starts with a known AG system env var, False otherwise."""
|
||||||
|
for varname in AG_SYSTEM_VAR_NAMES:
|
||||||
|
if path.startswith(varname):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
def _sortByValLength(v1, v2):
|
||||||
|
return len(EXPANDED_AG_SYSTEM_VARS[v2]) - len(EXPANDED_AG_SYSTEM_VARS[v1])
|
||||||
|
|
||||||
def makeDirsForFile(filename):
|
def makeDirsForFile(filename):
|
||||||
d = os.path.dirname(filename)
|
d = os.path.dirname(filename)
|
||||||
@@ -44,7 +104,7 @@ def createFile(filename, mode='w'):
|
|||||||
f = file(filename, mode)
|
f = file(filename, mode)
|
||||||
return f
|
return f
|
||||||
|
|
||||||
def compareFiles(file1, file2):
|
def compareFiles(file1, file2, ignore=None):
|
||||||
## result = filecmp.cmp(file1, file2)
|
## result = filecmp.cmp(file1, file2)
|
||||||
## if result:
|
## if result:
|
||||||
## return 0
|
## return 0
|
||||||
@@ -62,6 +122,9 @@ def compareFiles(file1, file2):
|
|||||||
elif (len(line2) == 0):
|
elif (len(line2) == 0):
|
||||||
return -1
|
return -1
|
||||||
elif (line1 != line2):
|
elif (line1 != line2):
|
||||||
|
if (ignore != None):
|
||||||
|
if (line1.startswith(ignore) or line2.startswith(ignore)):
|
||||||
|
continue
|
||||||
line1 = line1.replace(" ", "")
|
line1 = line1.replace(" ", "")
|
||||||
line2 = line2.replace(" ", "")
|
line2 = line2.replace(" ", "")
|
||||||
if (line1 != line2):
|
if (line1 != line2):
|
||||||
@@ -81,7 +144,10 @@ def compareFiles(file1, file2):
|
|||||||
continue
|
continue
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
def expandVars(value):
|
def expandKnownAGVars(value):
|
||||||
|
return expandVars(value, includeEnv=False)
|
||||||
|
|
||||||
|
def expandVars(value, includeEnv=True):
|
||||||
"""Syntax: ${myvar,default="default value"}"""
|
"""Syntax: ${myvar,default="default value"}"""
|
||||||
import activegrid.runtime as runtime
|
import activegrid.runtime as runtime
|
||||||
sx = value.find("${")
|
sx = value.find("${")
|
||||||
@@ -97,16 +163,19 @@ def expandVars(value):
|
|||||||
defaultValue = value[defsx+10:endx-1]
|
defaultValue = value[defsx+10:endx-1]
|
||||||
if (defaultValue == None):
|
if (defaultValue == None):
|
||||||
varname = value[sx+2:endx]
|
varname = value[sx+2:endx]
|
||||||
if (varname == "AG_SYSTEM"):
|
if (varname == AG_SYSTEM_VAR):
|
||||||
varval = runtime.appInfo.getSystemDir()
|
varval = runtime.appInfo.getSystemDir()
|
||||||
elif (varname == "AG_SYSTEM_STATIC"):
|
elif (varname == AG_SYSTEM_STATIC_VAR):
|
||||||
varval = runtime.appInfo.getSystemStaticDir()
|
varval = runtime.appInfo.getSystemStaticDir()
|
||||||
elif (varname == "AG_APP"):
|
elif (varname == AG_APP_VAR):
|
||||||
varval = runtime.appInfo.getAppDir()
|
varval = runtime.appInfo.getAppDir()
|
||||||
elif (varname == "AG_APP_STATIC"):
|
elif (varname == AG_APP_STATIC_VAR):
|
||||||
varval = runtime.appInfo.getAppStaticDir()
|
varval = runtime.appInfo.getAppStaticDir()
|
||||||
else:
|
else:
|
||||||
varval = os.getenv(varname)
|
if (includeEnv):
|
||||||
|
varval = os.getenv(varname)
|
||||||
|
else:
|
||||||
|
varval = None
|
||||||
if ((varval == None) and (defaultValue != None)):
|
if ((varval == None) and (defaultValue != None)):
|
||||||
varval = defaultValue
|
varval = defaultValue
|
||||||
if (varval == None):
|
if (varval == None):
|
||||||
@@ -148,22 +217,21 @@ def convertSourcePath(path, to, otherdir=None):
|
|||||||
return otherdir + path[ix+7:]
|
return otherdir + path[ix+7:]
|
||||||
|
|
||||||
|
|
||||||
def visit(directory, files, extension):
|
def visit(directory, files, extension, maxLevel=None, level=1):
|
||||||
testdirs = os.listdir(directory)
|
testdirs = os.listdir(directory)
|
||||||
for thing in testdirs:
|
for thing in testdirs:
|
||||||
fullpath = os.path.join(directory, thing)
|
fullpath = os.path.join(directory, thing)
|
||||||
if (os.path.isdir(fullpath)):
|
if (os.path.isdir(fullpath) and (maxLevel == None or level < maxLevel)):
|
||||||
visit(fullpath, files, extension)
|
visit(fullpath, files, extension, maxLevel, level+1)
|
||||||
elif thing.endswith(extension):
|
elif thing.endswith(extension):
|
||||||
fullname = os.path.normpath(os.path.join(directory, thing))
|
fullname = os.path.normpath(os.path.join(directory, thing))
|
||||||
if not fullname in files:
|
if not fullname in files:
|
||||||
files.append(fullname)
|
files.append(fullname)
|
||||||
|
|
||||||
def listFilesByExtensionInPath(path=[], extension='.lyt'):
|
def listFilesByExtensionInPath(path=[], extension='.lyt', maxLevel=None):
|
||||||
#Collect input and output arguments into one bunch
|
|
||||||
retval = []
|
retval = []
|
||||||
for directory in path:
|
for directory in path:
|
||||||
visit(directory, retval, extension)
|
visit(directory, retval, extension, maxLevel)
|
||||||
return retval
|
return retval
|
||||||
|
|
||||||
def getFileLastModificationTime(fileName):
|
def getFileLastModificationTime(fileName):
|
||||||
@@ -311,6 +379,21 @@ def remove(file):
|
|||||||
shutil.rmtree(file)
|
shutil.rmtree(file)
|
||||||
endIfDef()
|
endIfDef()
|
||||||
|
|
||||||
|
def getUserTempDir():
|
||||||
|
systemTempDir = utillang.getSystemTempDir()
|
||||||
|
userName = sysutils.getUserName()
|
||||||
|
userNameNoSpace = userName.replace('_','__').replace(' ','_')
|
||||||
|
userTempDir = systemTempDir + os.sep + "activegrid_" + userNameNoSpace
|
||||||
|
return userTempDir
|
||||||
|
|
||||||
|
def createUserTempDir():
|
||||||
|
userTempDir = getUserTempDir()
|
||||||
|
if not os.path.exists(userTempDir):
|
||||||
|
os.makedirs(userTempDir)
|
||||||
|
os.chmod(userTempDir, 0700)
|
||||||
|
|
||||||
|
createUserTempDir()
|
||||||
|
|
||||||
ifDefPy()
|
ifDefPy()
|
||||||
import warnings
|
import warnings
|
||||||
warnings.filterwarnings("ignore", message="tmpnam is a potential security risk to your program")
|
warnings.filterwarnings("ignore", message="tmpnam is a potential security risk to your program")
|
||||||
|
@@ -16,7 +16,8 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import __builtin__
|
import __builtin__
|
||||||
import types
|
import types
|
||||||
import xml.sax.saxutils as saxutils
|
import activegrid.util.utillang as utillang
|
||||||
|
import activegrid.util.datetimeparser as datetimeparser
|
||||||
from types import *
|
from types import *
|
||||||
from activegrid.util.lang import *
|
from activegrid.util.lang import *
|
||||||
|
|
||||||
@@ -65,6 +66,18 @@ def setStaticAttr(obj, attr, value):
|
|||||||
classDesc = obj.__class__
|
classDesc = obj.__class__
|
||||||
setattr(classDesc, attr, value)
|
setattr(classDesc, attr, value)
|
||||||
|
|
||||||
|
def hasAttrFast(obj, name):
|
||||||
|
if hasRawAttr(obj, name):
|
||||||
|
return True
|
||||||
|
if hasattr(obj, '_complexType'):
|
||||||
|
complexType=obj._complexType
|
||||||
|
element=complexType.findElement(name)
|
||||||
|
if element:
|
||||||
|
return True
|
||||||
|
if hasattr(obj, name):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def moduleForName(moduleName):
|
def moduleForName(moduleName):
|
||||||
module = None
|
module = None
|
||||||
pathList = moduleName.split('.')
|
pathList = moduleName.split('.')
|
||||||
@@ -114,15 +127,22 @@ def newInstance(className, objargs=None):
|
|||||||
if ((len(objargs) < 1) or (objargs[0].lower() == "false") or (not objargs[0])):
|
if ((len(objargs) < 1) or (objargs[0].lower() == "false") or (not objargs[0])):
|
||||||
return False
|
return False
|
||||||
return True
|
return True
|
||||||
if className == "str" or className == "unicode": # don"t strip: blanks are significant
|
if className == "str" or className == "unicode": # don't strip: blanks are significant
|
||||||
if len(objargs) > 0:
|
if len(objargs) > 0:
|
||||||
try:
|
try:
|
||||||
return saxutils.unescape(objargs[0]).encode()
|
return utillang.unescape(objargs[0]).encode()
|
||||||
except:
|
except:
|
||||||
return "?"
|
return "?"
|
||||||
else:
|
else:
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
|
if className == "date":
|
||||||
|
return datetimeparser.parse(objargs[0], asdate=True)
|
||||||
|
if className == "datetime":
|
||||||
|
return datetimeparser.parse(objargs[0])
|
||||||
|
if className == "time":
|
||||||
|
return datetimeparser.parse(objargs[0], astime=True)
|
||||||
|
|
||||||
classtype = classForName(className)
|
classtype = classForName(className)
|
||||||
if (classtype == None):
|
if (classtype == None):
|
||||||
raise Exception("Could not find class %s" % className)
|
raise Exception("Could not find class %s" % className)
|
||||||
@@ -135,23 +155,35 @@ def newInstance(className, objargs=None):
|
|||||||
def getClassProperty(classType, propertyName):
|
def getClassProperty(classType, propertyName):
|
||||||
return getattr(classType, propertyName)
|
return getattr(classType, propertyName)
|
||||||
|
|
||||||
def toDiffableRepr(value, exclude=None):
|
def toDiffableRepr(value, maxLevel=None):
|
||||||
if (value == None):
|
if (value == None):
|
||||||
return "None"
|
return "None"
|
||||||
|
if (maxLevel == None):
|
||||||
|
maxLevel = 8
|
||||||
|
maxLevel -= 1
|
||||||
|
if (maxLevel < 0):
|
||||||
|
return typeToString(value, PRINT_OBJ_DIFFABLE)
|
||||||
|
## if ((exclude != None) and not isinstance(value, (basestring, int))):
|
||||||
|
## for v in exclude:
|
||||||
|
## if (v is value):
|
||||||
|
## return "<recursive reference>"
|
||||||
|
## exclude.append(value)
|
||||||
## elif (isinstance(value, ObjectType) and hasattr(value, "__dict__")):
|
## elif (isinstance(value, ObjectType) and hasattr(value, "__dict__")):
|
||||||
## if (exclude == None):
|
## if (exclude == None):
|
||||||
## exclude = []
|
## exclude = []
|
||||||
## s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude))
|
## s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude))
|
||||||
elif (not isinstance(value, (BooleanType, ClassType, ComplexType, DictType, DictionaryType,
|
if (not isinstance(value, (BooleanType, ClassType, ComplexType, DictType, DictionaryType,
|
||||||
FloatType, IntType, ListType, LongType, StringType, TupleType,
|
FloatType, IntType, ListType, LongType, StringType, TupleType,
|
||||||
UnicodeType, BufferType, BuiltinFunctionType, BuiltinMethodType,
|
UnicodeType, BufferType, BuiltinFunctionType, BuiltinMethodType,
|
||||||
CodeType, FrameType, FunctionType, GeneratorType, InstanceType,
|
CodeType, FrameType, FunctionType, GeneratorType, InstanceType,
|
||||||
LambdaType, MethodType, ModuleType, SliceType, TracebackType,
|
LambdaType, MethodType, ModuleType, SliceType, TracebackType,
|
||||||
TypeType, XRangeType))):
|
TypeType, XRangeType))):
|
||||||
if (hasattr(value, "__str__")):
|
if (hasattr(value, "_toDiffableString")):
|
||||||
|
s = value._toDiffableString(maxLevel)
|
||||||
|
elif (hasattr(value, "__str__")):
|
||||||
s = str(value)
|
s = str(value)
|
||||||
elif (hasattr(value, "__dict__")):
|
elif (hasattr(value, "__dict__")):
|
||||||
s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude))
|
s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, maxLevel))
|
||||||
else:
|
else:
|
||||||
s = str(type(value))
|
s = str(type(value))
|
||||||
ix2 = s.find(" object at 0x")
|
ix2 = s.find(" object at 0x")
|
||||||
@@ -173,33 +205,31 @@ def toDiffableRepr(value, exclude=None):
|
|||||||
else:
|
else:
|
||||||
items.append("'%s'" % v)
|
items.append("'%s'" % v)
|
||||||
else:
|
else:
|
||||||
items.append(toDiffableString(v, exclude))
|
items.append(toDiffableString(v, maxLevel))
|
||||||
s = "[" + ", ".join(items) + "]"
|
s = "[" + ", ".join(items) + "]"
|
||||||
elif (isinstance(value, dict)):
|
elif (isinstance(value, dict)):
|
||||||
if (exclude == None):
|
|
||||||
exclude = []
|
|
||||||
items = []
|
items = []
|
||||||
for key, val in value.iteritems():
|
for key, val in value.iteritems():
|
||||||
if (isinstance(val, UnicodeType)):
|
if (isinstance(val, UnicodeType)):
|
||||||
items.append("'%s': u'%s'" % (key, toDiffableString(val, exclude)))
|
items.append("'%s': u'%s'" % (key, toDiffableString(val, maxLevel)))
|
||||||
elif (isinstance(val, basestring)):
|
elif (isinstance(val, basestring)):
|
||||||
items.append("'%s': '%s'" % (key, toDiffableString(val, exclude)))
|
items.append("'%s': '%s'" % (key, toDiffableString(val, maxLevel)))
|
||||||
else:
|
else:
|
||||||
items.append("'%s': %s" % (key, toDiffableString(val, exclude)))
|
items.append("'%s': %s" % (key, toDiffableString(val, maxLevel)))
|
||||||
s = "{" + ", ".join(items) + "}"
|
s = "{" + ", ".join(items) + "}"
|
||||||
else:
|
else:
|
||||||
s = str(value)
|
s = str(value)
|
||||||
return s
|
return s
|
||||||
|
|
||||||
def toDiffableString(value, exclude=None):
|
def toDiffableString(value, maxLevel=None):
|
||||||
if (value == None):
|
## if (value == None):
|
||||||
return "None"
|
## return "None"
|
||||||
if ((exclude != None) and not isinstance(value, (basestring, int))):
|
## if ((exclude != None) and not isinstance(value, (basestring, int))):
|
||||||
for v in exclude:
|
## for v in exclude:
|
||||||
if (v is value):
|
## if (v is value):
|
||||||
return "<recursive reference>"
|
## return "<recursive reference>"
|
||||||
exclude.append(value)
|
## exclude.append(value)
|
||||||
s = toDiffableRepr(value)
|
s = toDiffableRepr(value, maxLevel)
|
||||||
ds = ""
|
ds = ""
|
||||||
i = s.find(" at 0x")
|
i = s.find(" at 0x")
|
||||||
start = 0
|
start = 0
|
||||||
|
380
wxPython/samples/ide/activegrid/util/parser.py
Normal file
380
wxPython/samples/ide/activegrid/util/parser.py
Normal file
@@ -0,0 +1,380 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: parser.py
|
||||||
|
# Purpose: parsing utilities
|
||||||
|
#
|
||||||
|
# Author: Jeff Norton
|
||||||
|
#
|
||||||
|
# Created: 8/9/05
|
||||||
|
# CVS-ID: $Id$
|
||||||
|
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||||
|
# License: wxWindows License
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import re
|
||||||
|
from activegrid.util.lang import *
|
||||||
|
ifDefPy()
|
||||||
|
import string
|
||||||
|
import array
|
||||||
|
endIfDef()
|
||||||
|
|
||||||
|
XPATH_ROOT_VAR = '__rootObj__'
|
||||||
|
GETOBJECTPARTNAMES = ["primaryRef", "ref", "orderings", "limit"]
|
||||||
|
|
||||||
|
class Tokenizer(object):
|
||||||
|
|
||||||
|
TOKEN_IDENT = 1
|
||||||
|
TOKEN_STRING = 2
|
||||||
|
TOKEN_OP = 3
|
||||||
|
TOKEN_WS = 4
|
||||||
|
## TOKEN_PLACEHOLDER = 5
|
||||||
|
|
||||||
|
def __init__(self, text, identStart=None, tokenSep=None, ignoreWhitespace=True):
|
||||||
|
"""
|
||||||
|
Turn a string into individual tokens. Three types of tokens are recognized:
|
||||||
|
TOKEN_IDENT: identifiers (those that start with the identStart pattern)
|
||||||
|
TOKEN_STRING: quoted string
|
||||||
|
TOKEN_OP: everything else
|
||||||
|
Tokens are separated by white space or the tokenSep pattern.
|
||||||
|
Constructor parameters:
|
||||||
|
text: The string to tokenize
|
||||||
|
identStart: A regular expression describing characters which start an identifier
|
||||||
|
The default expression accepts letters, "_", and "/".
|
||||||
|
tokenSep: A regular expression describing the characters which end a token
|
||||||
|
(in addition to whitespace). The default expression accepts
|
||||||
|
anything except alpha-numerics, "_", "/", and ":".
|
||||||
|
Usage:
|
||||||
|
Invoke getNextToken (or next) to get the next token. The instance variables
|
||||||
|
token, and tokenVal will be populated with the current token type (TOKEN_IDENT,
|
||||||
|
TOKEN_STRING, or TOEKN_OP) and value respectively. nextToken and nextTokenVal
|
||||||
|
will also be available for lookahead. The next method is similar to
|
||||||
|
getNextToken but also returns the token value. A value of None signals end
|
||||||
|
of stream.
|
||||||
|
"""
|
||||||
|
self.ignoreWhitespace=ignoreWhitespace
|
||||||
|
ifDefPy()
|
||||||
|
if (isinstance(text, array.array)):
|
||||||
|
text = text.tostring()
|
||||||
|
endIfDef()
|
||||||
|
self.text = asString(text)
|
||||||
|
self.textIndex = 0
|
||||||
|
self.textLen = len(self.text)
|
||||||
|
self.token = None
|
||||||
|
self.tokenVal = None
|
||||||
|
self.nextToken = None
|
||||||
|
self.nextTokenVal = None
|
||||||
|
if (identStart == None):
|
||||||
|
identStart = "[a-zA-Z_/]"
|
||||||
|
if (tokenSep == None):
|
||||||
|
tokenSep = "[^a-zA-Z0-9_/:]"
|
||||||
|
self.identStart = re.compile(identStart)
|
||||||
|
self.tokenSep = re.compile(tokenSep)
|
||||||
|
self.getNextToken() # Prime the pump
|
||||||
|
|
||||||
|
def isEscaped(text, index):
|
||||||
|
if ((index > 0) and (text[index-1] == '\\') and ((index < 2) or (text[index-2] != '\\'))):
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
isEscaped = staticmethod(isEscaped)
|
||||||
|
|
||||||
|
def findClosingQuote(text, index, char):
|
||||||
|
index = index + 1
|
||||||
|
while True:
|
||||||
|
endIndex = text.find(char, index)
|
||||||
|
if (endIndex < 1):
|
||||||
|
return -1
|
||||||
|
if (Tokenizer.isEscaped(text, endIndex)):
|
||||||
|
index = endIndex+1
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
return endIndex + 1
|
||||||
|
findClosingQuote = staticmethod(findClosingQuote)
|
||||||
|
|
||||||
|
def _findClosing(self, char):
|
||||||
|
if (self.textIndex >= self.textLen):
|
||||||
|
raise Exception("The text \"%s\" has an unmatched string starting at %d" % (self.text, self.textIndex))
|
||||||
|
index = Tokenizer.findClosingQuote(self.text, self.textIndex, char)
|
||||||
|
if (index < 0):
|
||||||
|
raise Exception("The text \"%s\" has an unmatched string starting at %d" % (self.text, self.textIndex-1))
|
||||||
|
return index
|
||||||
|
|
||||||
|
def next(self):
|
||||||
|
self.getNextToken()
|
||||||
|
if (self.token == None):
|
||||||
|
raise StopIteration()
|
||||||
|
return self.tokenVal
|
||||||
|
|
||||||
|
def getNextToken(self):
|
||||||
|
self.token = self.nextToken
|
||||||
|
self.tokenVal = self.nextTokenVal
|
||||||
|
while (self.textIndex < self.textLen):
|
||||||
|
c = self.text[self.textIndex]
|
||||||
|
if (c not in string.whitespace):
|
||||||
|
if (c == '"' or c == "'" or c == '`'):
|
||||||
|
endIndex = self._findClosing(c)
|
||||||
|
self.nextToken = self.TOKEN_STRING
|
||||||
|
self.nextTokenVal = self.text[self.textIndex:endIndex]
|
||||||
|
self.textIndex = endIndex
|
||||||
|
return
|
||||||
|
elif (self.identStart.search(c)):
|
||||||
|
endMatch = self.tokenSep.search(self.text, self.textIndex+1)
|
||||||
|
if (endMatch):
|
||||||
|
endIndex = endMatch.start()
|
||||||
|
else:
|
||||||
|
endIndex = self.textLen
|
||||||
|
self.nextToken = self.TOKEN_IDENT
|
||||||
|
self.nextTokenVal = self.text[self.textIndex:endIndex]
|
||||||
|
self.textIndex = endIndex
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
self.nextToken = self.TOKEN_OP
|
||||||
|
endIndex = self.textIndex + 1
|
||||||
|
if (c == '<' or c == '>' or c == '!' or c == '='):
|
||||||
|
if ((endIndex < self.textLen) and (self.text[endIndex] == '=')):
|
||||||
|
endIndex += 1
|
||||||
|
elif ((c == '%') and (endIndex < self.textLen)):
|
||||||
|
c = self.text[endIndex]
|
||||||
|
if (c in ['d', 'i', 'o', 'u', 'x', 'X', 'e', 'E', 'f', 'F', 'g', 'G', 'c', 'r', 's', '%']):
|
||||||
|
endIndex += 1
|
||||||
|
## self.nextToken = self.TOKEN_PLACEHOLDER # Should really be this but no one can handle it yet
|
||||||
|
self.nextTokenVal = self.text[self.textIndex:endIndex]
|
||||||
|
self.textIndex = endIndex
|
||||||
|
return
|
||||||
|
elif not self.ignoreWhitespace:
|
||||||
|
self.nextToken=self.TOKEN_WS
|
||||||
|
self.nextTokenVal=""
|
||||||
|
while c in string.whitespace:
|
||||||
|
self.nextTokenVal+=c
|
||||||
|
self.textIndex+=1
|
||||||
|
if self.textIndex==len(self.text):
|
||||||
|
break
|
||||||
|
c=self.text[self.textIndex]
|
||||||
|
return
|
||||||
|
self.textIndex += 1
|
||||||
|
self.nextToken = None
|
||||||
|
self.nextTokenVal = None
|
||||||
|
|
||||||
|
def isXPathNonVar(var):
|
||||||
|
"""Returns true iff var is a string ("foo" or 'foo') or a number."""
|
||||||
|
if (var.startswith("'") and var.endswith("'")) or \
|
||||||
|
(var.startswith('"') and var.endswith('"')):
|
||||||
|
return True
|
||||||
|
|
||||||
|
# list from XPathToCode, below
|
||||||
|
if var.lower() in ["count", "empty", "true", "false", "null", "and", "or", \
|
||||||
|
"like", "not"]:
|
||||||
|
return True
|
||||||
|
|
||||||
|
try:
|
||||||
|
t=int(var)
|
||||||
|
return True
|
||||||
|
except TypeError, e:
|
||||||
|
pass
|
||||||
|
except ValueError, e:
|
||||||
|
pass
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
def xpathToCode(xpaths, convertBracket=True):
|
||||||
|
if ((xpaths == None) or (len(xpaths) < 1)):
|
||||||
|
return "True"
|
||||||
|
if (not isinstance(xpaths, (list, tuple))):
|
||||||
|
xpaths = [xpaths]
|
||||||
|
result = []
|
||||||
|
for xpath in xpaths:
|
||||||
|
t = Tokenizer(xpath, "[a-zA-Z0-9_/:\.]", "[^a-zA-Z0-9_/:\.]", ignoreWhitespace=False)
|
||||||
|
expr = []
|
||||||
|
lastToken=None
|
||||||
|
while t.nextToken != None:
|
||||||
|
t.getNextToken()
|
||||||
|
if (t.token == Tokenizer.TOKEN_WS):
|
||||||
|
expr.append(" ")
|
||||||
|
elif (t.token == Tokenizer.TOKEN_OP):
|
||||||
|
if (t.tokenVal == "="):
|
||||||
|
expr.append("==")
|
||||||
|
elif (t.tokenVal == "[" and convertBracket):
|
||||||
|
expr.append("(")
|
||||||
|
elif (t.tokenVal == "]" and convertBracket):
|
||||||
|
expr.append(")")
|
||||||
|
else:
|
||||||
|
expr.append(t.tokenVal)
|
||||||
|
elif (t.token == Tokenizer.TOKEN_IDENT):
|
||||||
|
if (t.tokenVal == "and"):
|
||||||
|
expr.append(" and ")
|
||||||
|
elif (t.tokenVal == "or"):
|
||||||
|
expr.append(" or ")
|
||||||
|
elif (t.tokenVal == "not"):
|
||||||
|
expr.append(" not ")
|
||||||
|
elif (t.tokenVal == "like"):
|
||||||
|
# REVIEW stoens@activegrid.com 02-Nov-05 --
|
||||||
|
# This is very limited support for like:
|
||||||
|
# typically like queries look like this: "foo like 'blah%'".
|
||||||
|
# So translate this into "foo.startswith(blah)".
|
||||||
|
# We should use a regular expression to support '%'s in
|
||||||
|
# arbitrary places in the string. After 1.1.
|
||||||
|
if t.nextToken and t.nextTokenVal.endswith("%'"):
|
||||||
|
t.getNextToken() # throw away the "like" token
|
||||||
|
last = len(expr) - 1
|
||||||
|
expr[last] = "%s.startswith(%s')"\
|
||||||
|
% (expr[last], t.tokenVal[:-2])
|
||||||
|
else:
|
||||||
|
# old behavior
|
||||||
|
expr.append(t.tokenVal)
|
||||||
|
|
||||||
|
elif (t.tokenVal == "count"):
|
||||||
|
expr.append("len")
|
||||||
|
elif (t.tokenVal == 'empty'):
|
||||||
|
expr.append('ctx.isEmptyPath')
|
||||||
|
elif (t.tokenVal == 'true'):
|
||||||
|
expr.append(_parseConstantFunction(t, 'True'))
|
||||||
|
elif (t.tokenVal == 'false'):
|
||||||
|
expr.append(_parseConstantFunction(t, 'False'))
|
||||||
|
elif (t.tokenVal == 'null'):
|
||||||
|
expr.append(_parseConstantFunction(t, 'None'))
|
||||||
|
elif (-1!=t.tokenVal.find(':')):
|
||||||
|
serviceDef, args=_parseServiceFunction(t)
|
||||||
|
|
||||||
|
# XXX handle serviceDef, args being None
|
||||||
|
|
||||||
|
for i in range(len(args)):
|
||||||
|
args[i]=xpathToCode(args[i], False)
|
||||||
|
jargs="[%s]" % (",".join(args))
|
||||||
|
|
||||||
|
# XXX should be processmodel.DATASERVICE_PROCESS_NAME, not "dataservice"
|
||||||
|
if serviceDef[0]=='dataservice':
|
||||||
|
expr.append("runtimesupport.invokeDataServiceWrapper(%s, %s, ctx, locals())" % \
|
||||||
|
(serviceDef, jargs))
|
||||||
|
else:
|
||||||
|
expr.append("runtimesupport.invokeServiceWrapper(%s, %s, ctx)" % \
|
||||||
|
(serviceDef, jargs))
|
||||||
|
else:
|
||||||
|
if (lastToken==')' or lastToken==']'):
|
||||||
|
wasFunc=True
|
||||||
|
else:
|
||||||
|
wasFunc=False
|
||||||
|
if (t.tokenVal.startswith('/')) and not wasFunc:
|
||||||
|
expr.append(XPATH_ROOT_VAR)
|
||||||
|
expr.append(t.tokenVal.replace('/','.'))
|
||||||
|
lastToken=t.tokenVal
|
||||||
|
else:
|
||||||
|
expr.append(t.tokenVal)
|
||||||
|
|
||||||
|
|
||||||
|
if (len(expr) == 2 and expr[0]==" "):
|
||||||
|
expr = "".join(expr)
|
||||||
|
result.append(expr)
|
||||||
|
elif (len(expr) > 1):
|
||||||
|
expr = "".join(expr)
|
||||||
|
result.append("(%s)" % expr)
|
||||||
|
elif (len(expr) > 0):
|
||||||
|
result.append(expr[0])
|
||||||
|
|
||||||
|
return " and ".join(result)
|
||||||
|
|
||||||
|
def _parseArgs(t):
|
||||||
|
args=[]
|
||||||
|
argcon=""
|
||||||
|
|
||||||
|
if t.tokenVal!='(':
|
||||||
|
return []
|
||||||
|
if t.nextTokenVal==')':
|
||||||
|
t.getNextToken()
|
||||||
|
return []
|
||||||
|
|
||||||
|
depth=1
|
||||||
|
|
||||||
|
while(depth!=0):
|
||||||
|
if not t.nextToken:
|
||||||
|
raise Exception("parameters list with no closing ) after token: %s" % t.tokenVal)
|
||||||
|
t.getNextToken()
|
||||||
|
|
||||||
|
if t.tokenVal=='(':
|
||||||
|
depth+=1
|
||||||
|
if t.tokenVal==')':
|
||||||
|
depth-=1
|
||||||
|
|
||||||
|
if depth==0 or (depth==1 and t.tokenVal==','):
|
||||||
|
args.append(argcon)
|
||||||
|
argcon=""
|
||||||
|
else:
|
||||||
|
argcon+=t.tokenVal
|
||||||
|
return args
|
||||||
|
|
||||||
|
def _parseServiceFunction(t):
|
||||||
|
"""Parses what appears to be a service function call into serviceDefs and args lists.
|
||||||
|
|
||||||
|
Returns None, None if the serviceFunction appears to be invalid.
|
||||||
|
"""
|
||||||
|
if t.nextTokenVal!='(':
|
||||||
|
return t.tokenVal, None
|
||||||
|
|
||||||
|
serviceDef=t.tokenVal.split(':')
|
||||||
|
t.getNextToken()
|
||||||
|
args=_parseArgs(t)
|
||||||
|
|
||||||
|
return serviceDef, args
|
||||||
|
|
||||||
|
def _parseConstantFunction(t, outputValue):
|
||||||
|
firstVal = t.tokenVal
|
||||||
|
if t.nextTokenVal != '(':
|
||||||
|
return firstVal
|
||||||
|
t.getNextToken()
|
||||||
|
if t.nextTokenVal != ')':
|
||||||
|
return "%s%s" % (firstVal, '(')
|
||||||
|
t.getNextToken()
|
||||||
|
return outputValue
|
||||||
|
|
||||||
|
def parseDSPredicate(ctx, str, vars, valueList=None):
|
||||||
|
from activegrid.util.utillang import evalCode
|
||||||
|
from activegrid.util.utillang import ObjAsDict
|
||||||
|
|
||||||
|
if valueList == None:
|
||||||
|
valueList = []
|
||||||
|
indexVar=0
|
||||||
|
oldIndexVar=0
|
||||||
|
sourceStr=str
|
||||||
|
inlinedPredicate=[]
|
||||||
|
qualifications=[]
|
||||||
|
while True:
|
||||||
|
oldIndexVar = indexVar
|
||||||
|
dollarCurlForm = False
|
||||||
|
quoted = False
|
||||||
|
indexVar = sourceStr.find("bpws:getVariableData", indexVar)
|
||||||
|
if indexVar == -1:
|
||||||
|
indexVar = sourceStr.find("${", oldIndexVar)
|
||||||
|
if indexVar == -1:
|
||||||
|
break
|
||||||
|
dollarCurlForm = True
|
||||||
|
if indexVar > 0 and sourceStr[indexVar-1] in ('"',"'"):
|
||||||
|
quoted = True
|
||||||
|
if not dollarCurlForm:
|
||||||
|
openParen = sourceStr.find("(", indexVar)
|
||||||
|
if openParen == -1:
|
||||||
|
break
|
||||||
|
closeParen = sourceStr.find(")", openParen)
|
||||||
|
if closeParen == -1:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
openParen = indexVar+1
|
||||||
|
closeParen = sourceStr.find("}", openParen)
|
||||||
|
if closeParen == -1:
|
||||||
|
break
|
||||||
|
varRef = sourceStr[openParen+1: closeParen]
|
||||||
|
if varRef.startswith('"') or varRef.startswith("'"):
|
||||||
|
varRef = varRef[1:]
|
||||||
|
if varRef.endswith('"') or varRef.endswith("'"):
|
||||||
|
varRef = varRef[:-1]
|
||||||
|
if isinstance(vars, dict) or isinstance(vars, ObjAsDict):
|
||||||
|
varRefCode = xpathToCode(varRef)
|
||||||
|
value = evalCode(varRefCode, vars)
|
||||||
|
else:
|
||||||
|
value = ctx.evalPath(vars, varRef)
|
||||||
|
inlinedPredicate.append(sourceStr[oldIndexVar:indexVar])
|
||||||
|
if quoted:
|
||||||
|
inlinedPredicate.append("%s" % value)
|
||||||
|
else:
|
||||||
|
inlinedPredicate.append('%s')
|
||||||
|
valueList.append(value)
|
||||||
|
indexVar = closeParen+1
|
||||||
|
inlinedPredicate.append(sourceStr[oldIndexVar:])
|
||||||
|
qualifications.append(''.join(inlinedPredicate))
|
||||||
|
return qualifications, valueList
|
@@ -21,3 +21,91 @@ def caseInsensitiveCompare(s1, s2):
|
|||||||
return -1
|
return -1
|
||||||
else:
|
else:
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
def multiSplit(stringList, tokenList=[" "]):
|
||||||
|
"""Splits strings in stringList by tokens, returns list of string."""
|
||||||
|
if not stringList: return []
|
||||||
|
if isinstance(tokenList, basestring):
|
||||||
|
tokenList = [tokenList]
|
||||||
|
if isinstance(stringList, basestring):
|
||||||
|
stringList = [stringList]
|
||||||
|
rtnList = stringList
|
||||||
|
for token in tokenList:
|
||||||
|
rtnList = rtnList[:]
|
||||||
|
for string in rtnList:
|
||||||
|
if string.find(token) > -1:
|
||||||
|
rtnList.remove(string)
|
||||||
|
names = string.split(token)
|
||||||
|
for name in names:
|
||||||
|
name = name.strip()
|
||||||
|
if name:
|
||||||
|
rtnList.append(name)
|
||||||
|
return rtnList
|
||||||
|
|
||||||
|
QUOTES = ("\"", "'")
|
||||||
|
|
||||||
|
def _findArgStart(argStr):
|
||||||
|
i = -1
|
||||||
|
for c in argStr:
|
||||||
|
i += 1
|
||||||
|
if (c == " "):
|
||||||
|
continue
|
||||||
|
elif (c == ","):
|
||||||
|
continue
|
||||||
|
return i
|
||||||
|
return None
|
||||||
|
|
||||||
|
def _findArgEnd(argStr):
|
||||||
|
quotedArg = True
|
||||||
|
argEndChar = argStr[0]
|
||||||
|
if (not argEndChar in QUOTES):
|
||||||
|
argEndChar = ","
|
||||||
|
quotedArg = False
|
||||||
|
i = -1
|
||||||
|
firstChar = True
|
||||||
|
for c in argStr:
|
||||||
|
i+= 1
|
||||||
|
if (firstChar):
|
||||||
|
firstChar = False
|
||||||
|
if (quotedArg):
|
||||||
|
continue
|
||||||
|
if (c == argEndChar):
|
||||||
|
if (quotedArg):
|
||||||
|
return min(i+1, len(argStr))
|
||||||
|
else:
|
||||||
|
return i
|
||||||
|
return i
|
||||||
|
|
||||||
|
def parseArgs(argStr, stripQuotes=False):
|
||||||
|
"""
|
||||||
|
Given a str representation of method arguments, returns list arguments (as
|
||||||
|
strings).
|
||||||
|
|
||||||
|
Input: "('[a,b]', 'c', 1)" -> Output: ["'[a,b]'", "'c'", "1"].
|
||||||
|
|
||||||
|
If stripQuotes, removes quotes from quoted arg.
|
||||||
|
"""
|
||||||
|
if (argStr.startswith("(")):
|
||||||
|
argStr = argStr[1:]
|
||||||
|
if (argStr.endswith(")")):
|
||||||
|
argStr = argStr[:-1]
|
||||||
|
else:
|
||||||
|
raise AssertionError("Expected argStr to end with ')'")
|
||||||
|
|
||||||
|
rtn = []
|
||||||
|
argsStr = argStr.strip()
|
||||||
|
while (True):
|
||||||
|
startIndex = _findArgStart(argStr)
|
||||||
|
if (startIndex == None):
|
||||||
|
break
|
||||||
|
argStr = argStr[startIndex:]
|
||||||
|
endIndex = _findArgEnd(argStr)
|
||||||
|
if (endIndex == len(argStr) - 1):
|
||||||
|
rtn.append(argStr.strip())
|
||||||
|
break
|
||||||
|
t = argStr[:endIndex].strip()
|
||||||
|
if (stripQuotes and t[0] in QUOTES and t[-1] in QUOTES):
|
||||||
|
t = t[1:-1]
|
||||||
|
rtn.append(t)
|
||||||
|
argStr = argStr[endIndex:]
|
||||||
|
return rtn
|
||||||
|
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
|
|
||||||
# this will be set to true in IDE.py when we are running release builds.
|
# this will be set to true in IDE.py when we are running release builds.
|
||||||
isRelease = False
|
isRelease = False
|
||||||
@@ -26,6 +27,12 @@ isRelease = False
|
|||||||
|
|
||||||
MAINMODULE_DIR = "AG_MAINMODULE_DIR"
|
MAINMODULE_DIR = "AG_MAINMODULE_DIR"
|
||||||
IS_RELEASE = "AG_IS_RELEASE"
|
IS_RELEASE = "AG_IS_RELEASE"
|
||||||
|
IS_COMMERCIAL = "AG_IS_COMMERCIAL"
|
||||||
|
AG_SYSTEM_START_TIME_ENV_NAME = "AG_SYSTEM_START_TIME"
|
||||||
|
|
||||||
|
def isCommercial():
|
||||||
|
|
||||||
|
return os.path.exists(os.path.join(mainModuleDir,"commercial.txt")) or 'true' == (str(os.getenv(IS_COMMERCIAL)).lower())
|
||||||
|
|
||||||
def isRelease():
|
def isRelease():
|
||||||
return 'true' == (str(os.getenv(IS_RELEASE)).lower())
|
return 'true' == (str(os.getenv(IS_RELEASE)).lower())
|
||||||
@@ -39,7 +46,16 @@ def setRelease(value):
|
|||||||
def isWindows():
|
def isWindows():
|
||||||
return os.name == 'nt'
|
return os.name == 'nt'
|
||||||
|
|
||||||
|
__isServer = False
|
||||||
|
|
||||||
|
def setServerMode(isServer):
|
||||||
|
global __isServer
|
||||||
|
__isServer = isServer
|
||||||
|
|
||||||
|
def isServer():
|
||||||
|
global __isServer
|
||||||
|
return __isServer
|
||||||
|
|
||||||
def _generateMainModuleDir():
|
def _generateMainModuleDir():
|
||||||
mainModuleDir = os.getenv(MAINMODULE_DIR)
|
mainModuleDir = os.getenv(MAINMODULE_DIR)
|
||||||
if mainModuleDir: # if environment variable set, return it
|
if mainModuleDir: # if environment variable set, return it
|
||||||
@@ -85,3 +101,16 @@ def getCommandNameForExecPath(execPath):
|
|||||||
return '"%s"' % execPath
|
return '"%s"' % execPath
|
||||||
return execPath
|
return execPath
|
||||||
|
|
||||||
|
def getUserName():
|
||||||
|
if isWindows():
|
||||||
|
return os.getenv('USERNAME')
|
||||||
|
else:
|
||||||
|
# 06-Feb-06 stoens@activegrid.com --
|
||||||
|
# this blows up the linux cc runs with "Inappropriate ioctl for device"
|
||||||
|
#return os.getlogin()
|
||||||
|
return os.getenv('USER')
|
||||||
|
|
||||||
|
def getCurrentTimeAsFloat():
|
||||||
|
return time.time()
|
||||||
|
|
||||||
|
systemStartTime = getCurrentTimeAsFloat()
|
||||||
|
146
wxPython/samples/ide/activegrid/util/utillang.py
Normal file
146
wxPython/samples/ide/activegrid/util/utillang.py
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
#----------------------------------------------------------------------------
|
||||||
|
# Name: utillang.py
|
||||||
|
# Purpose: Provide language specific utilities
|
||||||
|
#
|
||||||
|
# Author: Joel Hare
|
||||||
|
#
|
||||||
|
# Created: 8/23/05
|
||||||
|
# CVS-ID: $Id$
|
||||||
|
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||||
|
# License: wxWindows License
|
||||||
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import UserDict
|
||||||
|
import tempfile
|
||||||
|
import xml.sax.saxutils as saxutils
|
||||||
|
|
||||||
|
import activegrid.util.parser as parser
|
||||||
|
|
||||||
|
PY2WEB_codepages = {
|
||||||
|
'cp1251' : 'CP-1251',
|
||||||
|
'koi8_r' : 'KOI8-R',
|
||||||
|
}
|
||||||
|
|
||||||
|
def evalXPath(xpath, data, specialEntries=None):
|
||||||
|
codeStr = parser.xpathToCode(xpath)
|
||||||
|
return evalCode(codeStr, data, specialEntries)
|
||||||
|
|
||||||
|
def evalCode(codeStr, data, specialEntries=None):
|
||||||
|
if isinstance(data, ObjAsDict):
|
||||||
|
namespace = data
|
||||||
|
elif isinstance(data, dict):
|
||||||
|
namespace = dict(data)
|
||||||
|
else:
|
||||||
|
namespace = ObjAsDict(data)
|
||||||
|
if specialEntries:
|
||||||
|
for key, value in specialEntries.items():
|
||||||
|
namespace.addSpecialEntry(key, value)
|
||||||
|
return eval(codeStr, {}, namespace)
|
||||||
|
|
||||||
|
def deriveCharset():
|
||||||
|
charset = None
|
||||||
|
encodingString = sys.getdefaultencoding()
|
||||||
|
if encodingString != 'ascii':
|
||||||
|
charset = PY2WEB_codepages.get(encodingString.lower())
|
||||||
|
if charset == None:
|
||||||
|
charset = encodingString
|
||||||
|
return charset
|
||||||
|
|
||||||
|
def toUTF8(value):
|
||||||
|
"""
|
||||||
|
Converts all unicode and non-string values to utf-8.
|
||||||
|
This assumes string instances are already encoded in utf-8.
|
||||||
|
Note that us-ascii is a subset of utf-8.
|
||||||
|
"""
|
||||||
|
if isinstance(value, unicode):
|
||||||
|
return value.encode('utf-8')
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
def toUnicode(value):
|
||||||
|
"""
|
||||||
|
Converts all strings non-string values to unicode.
|
||||||
|
This assumes string instances are encoded in utf-8.
|
||||||
|
Note that us-ascii is a subset of utf-8.
|
||||||
|
"""
|
||||||
|
if not isinstance(value, unicode):
|
||||||
|
if not isinstance(value, str):
|
||||||
|
return unicode(value)
|
||||||
|
return unicode(value, 'utf-8')
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def getSystemTempDir():
|
||||||
|
return tempfile.gettempdir()
|
||||||
|
|
||||||
|
def getEnvVar(name, defaultVal=None):
|
||||||
|
if os.environ.has_key(name):
|
||||||
|
return os.environ[name]
|
||||||
|
return defaultVal
|
||||||
|
|
||||||
|
class ObjAsDict(UserDict.DictMixin):
|
||||||
|
"""
|
||||||
|
Passing this to eval as the local variables dictionary allows the
|
||||||
|
evaluated code to access properties in the wrapped object
|
||||||
|
"""
|
||||||
|
def __init__(self, obj):
|
||||||
|
self.obj = obj
|
||||||
|
self.specialEntries = {}
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
try:
|
||||||
|
return getattr(self.obj, key)
|
||||||
|
except AttributeError, e:
|
||||||
|
if self.specialEntries.has_key(key):
|
||||||
|
return self.specialEntries[key]
|
||||||
|
raise KeyError(e.args)
|
||||||
|
def __setitem__(self, key, item): setattr(self.obj, key, item)
|
||||||
|
def __delitem__(self, key): delattr(self.obj, key)
|
||||||
|
def keys(self):
|
||||||
|
ret=[]
|
||||||
|
for i in list(dir(self.obj)+self.specialEntries.keys()):
|
||||||
|
if i=="__doc__" or i=="__module__":
|
||||||
|
pass
|
||||||
|
elif i not in ret:
|
||||||
|
ret.append(i)
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def addSpecialEntry(self, key, value):
|
||||||
|
self.specialEntries[key] = value
|
||||||
|
|
||||||
|
global saxXMLescapeDoubleQuote
|
||||||
|
saxXMLescapeDoubleQuote = {'"':'"'}
|
||||||
|
|
||||||
|
global saxXMLescapesAllQuotes
|
||||||
|
# IE doesn't support ' but it doesn't seem like we should need this escaped at all so I took it out.
|
||||||
|
saxXMLescapesAllQuotes = {'"':'"', "'":"'"}
|
||||||
|
|
||||||
|
global saxXMLunescapes
|
||||||
|
saxXMLunescapes = {'"':'"', "'":"'"}
|
||||||
|
|
||||||
|
def escape(data, extraEscapes=None):
|
||||||
|
"""Escape ', ", &, <, and > in a string of data.
|
||||||
|
|
||||||
|
Basically, everything that saxutils.escape does (and this calls that, at
|
||||||
|
least for now), but with " and ' added as well.
|
||||||
|
|
||||||
|
TODO: make this faster; saxutils.escape() is really slow
|
||||||
|
"""
|
||||||
|
|
||||||
|
global saxXMLescapeDoubleQuote
|
||||||
|
if (extraEscapes == None):
|
||||||
|
extraEscapes = saxXMLescapeDoubleQuote
|
||||||
|
return saxutils.escape(data, extraEscapes)
|
||||||
|
|
||||||
|
def unescape(data):
|
||||||
|
"""Unescape ', ", &, <, and > in a string of data.
|
||||||
|
|
||||||
|
Basically, everything that saxutils.unescape does (and this calls that, at
|
||||||
|
least for now), but with " and ' added as well.
|
||||||
|
|
||||||
|
TODO: make this faster; saxutils.unescape() is really slow
|
||||||
|
"""
|
||||||
|
|
||||||
|
global saxXMLunescapes
|
||||||
|
return saxutils.unescape(data, saxXMLunescapes)
|
@@ -2,7 +2,7 @@
|
|||||||
# Name: xmlmarshaller.py
|
# Name: xmlmarshaller.py
|
||||||
# Purpose:
|
# Purpose:
|
||||||
#
|
#
|
||||||
# Authors: John Spurling, Joel Hare, Alan Mullendore
|
# Authors: John Spurling, Joel Hare, Jeff Norton, Alan Mullendore
|
||||||
#
|
#
|
||||||
# Created: 7/28/04
|
# Created: 7/28/04
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
@@ -16,14 +16,18 @@ import logging
|
|||||||
ifDefPy()
|
ifDefPy()
|
||||||
import xml.sax
|
import xml.sax
|
||||||
import xml.sax.handler
|
import xml.sax.handler
|
||||||
|
import xml.sax.saxutils
|
||||||
|
import datetime
|
||||||
endIfDef()
|
endIfDef()
|
||||||
import xml.sax.saxutils as saxutils
|
import activegrid.util.utillang as utillang
|
||||||
import activegrid.util.objutils as objutils
|
import activegrid.util.objutils as objutils
|
||||||
|
import activegrid.util.sysutils as sysutils
|
||||||
import activegrid.util.aglogging as aglogging
|
import activegrid.util.aglogging as aglogging
|
||||||
|
|
||||||
MODULE_PATH = "__main__"
|
MODULE_PATH = "__main__"
|
||||||
|
|
||||||
## ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
|
## ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
|
||||||
|
##unboundedVal = 2147483647 # value used for maxOccurs == "unbounded"
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Special attributes that we recognize:
|
Special attributes that we recognize:
|
||||||
@@ -109,7 +113,6 @@ __xmlcdatacontent__ = "messyContent"
|
|||||||
|
|
||||||
global xmlMarshallerLogger
|
global xmlMarshallerLogger
|
||||||
xmlMarshallerLogger = logging.getLogger("activegrid.util.xmlmarshaller.marshal")
|
xmlMarshallerLogger = logging.getLogger("activegrid.util.xmlmarshaller.marshal")
|
||||||
xmlMarshallerLogger.setLevel(aglogging.LEVEL_WARN)
|
|
||||||
# INFO : low-level info
|
# INFO : low-level info
|
||||||
# DEBUG : debugging info
|
# DEBUG : debugging info
|
||||||
|
|
||||||
@@ -184,6 +187,7 @@ DICT_ITEM_VALUE_NAME = "value"
|
|||||||
################################################################################
|
################################################################################
|
||||||
|
|
||||||
def setattrignorecase(object, name, value):
|
def setattrignorecase(object, name, value):
|
||||||
|
## print "[setattrignorecase] name = %s, value = %s" % (name, value)
|
||||||
if (name not in object.__dict__):
|
if (name not in object.__dict__):
|
||||||
namelow = name.lower()
|
namelow = name.lower()
|
||||||
for attr in object.__dict__:
|
for attr in object.__dict__:
|
||||||
@@ -193,27 +197,95 @@ def setattrignorecase(object, name, value):
|
|||||||
object.__dict__[name] = value
|
object.__dict__[name] = value
|
||||||
|
|
||||||
def getComplexType(obj):
|
def getComplexType(obj):
|
||||||
|
if (hasattr(obj, "_instancexsdcomplextype")):
|
||||||
|
return obj._instancexsdcomplextype
|
||||||
if (hasattr(obj, "__xsdcomplextype__")):
|
if (hasattr(obj, "__xsdcomplextype__")):
|
||||||
return obj.__xsdcomplextype__
|
return obj.__xsdcomplextype__
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _objectfactory(objname, objargs=None, objclass=None):
|
def _objectfactory(objtype, objargs=None, objclass=None):
|
||||||
"dynamically create an object based on the objname and return it."
|
"dynamically create an object based on the objtype and return it."
|
||||||
## print "[objectfactory] objname [%s]" % (objname)
|
|
||||||
if not isinstance(objargs, list):
|
if not isinstance(objargs, list):
|
||||||
objargs = [objargs]
|
objargs = [objargs]
|
||||||
if (objclass != None):
|
if (objclass != None):
|
||||||
|
obj = None
|
||||||
if (len(objargs) > 0):
|
if (len(objargs) > 0):
|
||||||
if (hasattr(objclass, "__xmlcdatacontent__")):
|
if (hasattr(objclass, "__xmlcdatacontent__")):
|
||||||
obj = objclass()
|
obj = objclass()
|
||||||
contentAttr = obj.__xmlcdatacontent__
|
contentAttr = obj.__xmlcdatacontent__
|
||||||
obj.__dict__[contentAttr] = str(objargs[0])
|
obj.__dict__[contentAttr] = str(objargs[0])
|
||||||
return obj
|
else:
|
||||||
return objclass(*objargs)
|
obj = objclass(*objargs)
|
||||||
else:
|
else:
|
||||||
return objclass()
|
obj = objclass()
|
||||||
return objutils.newInstance(objname, objargs)
|
if ((obj != None) and (hasattr(obj, 'postUnmarshal'))):
|
||||||
|
obj.postUnmarshal()
|
||||||
|
return obj
|
||||||
|
return objutils.newInstance(objtype, objargs)
|
||||||
|
|
||||||
|
class GenericXMLObject(object):
|
||||||
|
def __init__(self, content=None):
|
||||||
|
if content != None:
|
||||||
|
self._content = content
|
||||||
|
self.__xmlcontent__ = '_content'
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return "GenericXMLObject(%s)" % objutils.toDiffableString(self.__dict__)
|
||||||
|
|
||||||
|
def setXMLAttributes(self, xmlName, attrs=None, children=None, nsMap=None, defaultNS=None):
|
||||||
|
if xmlName != None:
|
||||||
|
i = xmlName.rfind(':')
|
||||||
|
if i < 0:
|
||||||
|
self.__xmlname__ = xmlName
|
||||||
|
if defaultNS != None:
|
||||||
|
self.__xmldefaultnamespace__ = str(defaultNS)
|
||||||
|
else:
|
||||||
|
self.__xmlname__ = xmlName[i+1:]
|
||||||
|
prefix = xmlName[:i]
|
||||||
|
if nsMap.has_key(prefix):
|
||||||
|
self.__xmldefaultnamespace__ = str(nsMap[prefix])
|
||||||
|
if attrs != None:
|
||||||
|
for attrname, attr in attrs.items():
|
||||||
|
attrname = str(attrname)
|
||||||
|
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
|
||||||
|
pass
|
||||||
|
elif attrname == "objtype":
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
if not hasattr(self, '__xmlattributes__'):
|
||||||
|
self.__xmlattributes__ = []
|
||||||
|
i = attrname.rfind(':')
|
||||||
|
if i >= 0:
|
||||||
|
prefix = attrname[:i]
|
||||||
|
attrname = attrname[i+1:]
|
||||||
|
if not hasattr(self, '__xmlattrnamespaces__'):
|
||||||
|
self.__xmlattrnamespaces__ = {}
|
||||||
|
if self.__xmlattrnamespaces__.has_key(prefix):
|
||||||
|
alist = self.__xmlattrnamespaces__[prefix]
|
||||||
|
else:
|
||||||
|
alist = []
|
||||||
|
alist.append(attrname)
|
||||||
|
self.__xmlattrnamespaces__[prefix] = alist
|
||||||
|
self.__xmlattributes__.append(attrname)
|
||||||
|
if hasattr(self, '__xmlattributes__'):
|
||||||
|
self.__xmlattributes__.sort()
|
||||||
|
if children != None and len(children) > 0:
|
||||||
|
childList = []
|
||||||
|
flattenList = {}
|
||||||
|
for childname, child in children:
|
||||||
|
childstr = str(childname)
|
||||||
|
if childstr in childList:
|
||||||
|
if not flattenList.has_key(childstr):
|
||||||
|
flattenList[childstr] = (childstr,)
|
||||||
|
else:
|
||||||
|
childList.append(childstr)
|
||||||
|
if len(flattenList) > 0:
|
||||||
|
self.__xmlflattensequence__ = flattenList
|
||||||
|
|
||||||
|
def initialize(self, arg1=None):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Element:
|
class Element:
|
||||||
def __init__(self, name, attrs=None, xsname=None):
|
def __init__(self, name, attrs=None, xsname=None):
|
||||||
self.name = name
|
self.name = name
|
||||||
@@ -222,9 +294,11 @@ class Element:
|
|||||||
self.children = []
|
self.children = []
|
||||||
self.objclass = None
|
self.objclass = None
|
||||||
self.xsname = xsname
|
self.xsname = xsname
|
||||||
|
self.objtype = None
|
||||||
|
|
||||||
def getobjtype(self):
|
def getobjtype(self):
|
||||||
objtype = self.attrs.get("objtype")
|
# objtype = self.attrs.get("objtype")
|
||||||
|
objtype = self.objtype
|
||||||
if (objtype == None):
|
if (objtype == None):
|
||||||
if (len(self.children) > 0):
|
if (len(self.children) > 0):
|
||||||
objtype = "dict"
|
objtype = "dict"
|
||||||
@@ -238,16 +312,35 @@ class NsElement(object):
|
|||||||
self.targetNS = None
|
self.targetNS = None
|
||||||
self.defaultNS = None
|
self.defaultNS = None
|
||||||
self.prefix = None
|
self.prefix = None
|
||||||
|
|
||||||
def isEmpty(self):
|
|
||||||
return ((self.nsMap == {}) and (self.targetNS == None) and (self.defaultNS == None))
|
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
if self.prefix == None:
|
||||||
|
strVal = 'prefix = None; '
|
||||||
|
else:
|
||||||
|
strVal = 'prefix = "%s"; ' % (self.prefix)
|
||||||
|
if self.targetNS == None:
|
||||||
|
strVal += 'targetNS = None; '
|
||||||
|
else:
|
||||||
|
strVal += 'targetNS = "%s"; ' % (self.targetNS)
|
||||||
|
if self.defaultNS == None:
|
||||||
|
strVal += 'defaultNS = None; '
|
||||||
|
else:
|
||||||
|
strVal += 'defaultNS = "%s"; ' % (self.defaultNS)
|
||||||
|
if len(self.nsMap) == 0:
|
||||||
|
strVal += 'nsMap = None; '
|
||||||
|
else:
|
||||||
|
strVal += 'nsMap = {'
|
||||||
|
for ik, iv in self.nsMap.iteritems():
|
||||||
|
strVal += '%s=%s; ' % (ik,iv)
|
||||||
|
strVal += '}'
|
||||||
|
return strVal
|
||||||
|
|
||||||
def setKnownTypes(self, masterKnownTypes, masterKnownNamespaces, parentNSE):
|
def setKnownTypes(self, masterKnownTypes, masterKnownNamespaces, parentNSE):
|
||||||
# if we're a nested element, extend our parent element's mapping
|
# if we're a nested element, extend our parent element's mapping
|
||||||
if parentNSE != None:
|
if parentNSE != None:
|
||||||
self.knownTypes = parentNSE.knownTypes.copy()
|
self.knownTypes = parentNSE.knownTypes.copy()
|
||||||
# but if we have a different default namespace, replace the parent's default mappings
|
# but if we have a different default namespace, replace the parent's default mappings
|
||||||
if parentNSE.defaultNS != self.defaultNS:
|
if (self.defaultNS != None) and (parentNSE.defaultNS != self.defaultNS):
|
||||||
newKT = self.knownTypes.copy()
|
newKT = self.knownTypes.copy()
|
||||||
for tag in newKT:
|
for tag in newKT:
|
||||||
if tag.find(':') < 0:
|
if tag.find(':') < 0:
|
||||||
@@ -283,7 +376,6 @@ class NsElement(object):
|
|||||||
self.knownTypes[knownTagName] = mapClass
|
self.knownTypes[knownTagName] = mapClass
|
||||||
else: # e.g. "ItemSearchRequest"
|
else: # e.g. "ItemSearchRequest"
|
||||||
self.knownTypes[tag] = mapClass
|
self.knownTypes[tag] = mapClass
|
||||||
## print 'mapping <%s> to class "%s"' % (tag, mapClass.__name__)
|
|
||||||
|
|
||||||
def expandQName(self, eName, attrName, attrValue):
|
def expandQName(self, eName, attrName, attrValue):
|
||||||
bigValue = attrValue
|
bigValue = attrValue
|
||||||
@@ -298,38 +390,57 @@ class NsElement(object):
|
|||||||
if shortNs == attrNS:
|
if shortNs == attrNS:
|
||||||
bigValue = '%s:%s' % (longNs, attrNCName)
|
bigValue = '%s:%s' % (longNs, attrNCName)
|
||||||
break
|
break
|
||||||
## print '[expandQName] input attrName = "%s" and attrValue "%s"; output = "%s"' % (attrName, attrValue, bigValue)
|
|
||||||
return bigValue
|
return bigValue
|
||||||
|
|
||||||
class XMLObjectFactory(xml.sax.ContentHandler):
|
class XMLObjectFactory(xml.sax.ContentHandler):
|
||||||
def __init__(self, knownTypes=None, knownNamespaces=None):
|
def __init__(self, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||||
self.rootelement = None
|
self.rootelement = None
|
||||||
if (knownTypes == None):
|
if xmlSource == None:
|
||||||
self.knownTypes = {}
|
self.xmlSource = "unknown"
|
||||||
else:
|
else:
|
||||||
self.knownTypes = knownTypes
|
self.xmlSource = xmlSource
|
||||||
if (knownNamespaces == None):
|
self.createGenerics = createGenerics
|
||||||
self.knownNamespaces = {}
|
|
||||||
else:
|
|
||||||
self.knownNamespaces = knownNamespaces
|
|
||||||
self.skipper = False
|
self.skipper = False
|
||||||
self.elementstack = []
|
self.elementstack = []
|
||||||
self.nsstack = []
|
self.nsstack = []
|
||||||
self.collectContent = None
|
self.collectContent = None
|
||||||
|
if (knownNamespaces == None):
|
||||||
|
self.knownNamespaces = {}
|
||||||
|
else:
|
||||||
|
self.knownNamespaces = knownNamespaces
|
||||||
|
self.reversedNamespaces = {}
|
||||||
|
for longns, shortns in self.knownNamespaces.iteritems():
|
||||||
|
self.reversedNamespaces[shortns] = longns
|
||||||
|
self.knownTypes = {}
|
||||||
|
if (knownTypes != None):
|
||||||
|
for tag, cls in knownTypes.iteritems():
|
||||||
|
i = tag.rfind(':')
|
||||||
|
if i >= 0:
|
||||||
|
shortns = tag[:i]
|
||||||
|
tag = tag[i+1:]
|
||||||
|
if not self.reversedNamespaces.has_key(shortns):
|
||||||
|
errorString = 'Error unmarshalling XML document from source "%s": knownTypes specifies an unmapped short namespace "%s" for element "%s"' % (self.xmlSource, shortns, tag)
|
||||||
|
raise UnmarshallerException(errorString)
|
||||||
|
longns = self.reversedNamespaces[shortns]
|
||||||
|
tag = '%s:%s' % (longns, tag)
|
||||||
|
self.knownTypes[tag] = cls
|
||||||
|
#printKnownTypes(self.knownTypes, 'Unmarshaller.XMLObjectFactory.__init__')
|
||||||
xml.sax.handler.ContentHandler.__init__(self)
|
xml.sax.handler.ContentHandler.__init__(self)
|
||||||
|
|
||||||
def appendElementStack(self, newElement, newNS):
|
def appendElementStack(self, newElement, newNS):
|
||||||
self.elementstack.append(newElement)
|
self.elementstack.append(newElement)
|
||||||
if (newNS.isEmpty()):
|
if (len(self.nsstack) > 0):
|
||||||
if (len(self.nsstack) > 0):
|
oldNS = self.nsstack[-1]
|
||||||
newNS = self.nsstack[-1]
|
if newNS.defaultNS == None:
|
||||||
else:
|
newNS.defaultNS = oldNS.defaultNS
|
||||||
newNS.knownTypes = self.knownTypes.copy()
|
if newNS.targetNS == None:
|
||||||
else:
|
newNS.targetNS = oldNS.targetNS
|
||||||
if (len(self.nsstack) > 0):
|
if len(newNS.nsMap) == 0:
|
||||||
newNS.setKnownTypes(self.knownTypes, self.knownNamespaces, self.nsstack[-1])
|
newNS.nsMap = oldNS.nsMap
|
||||||
else:
|
elif len(oldNS.nsMap) > 0:
|
||||||
newNS.setKnownTypes(self.knownTypes, self.knownNamespaces, None)
|
map = oldNS.nsMap.copy()
|
||||||
|
map.update(newNS.nsMap)
|
||||||
|
newNS.nsMap = map
|
||||||
self.nsstack.append(newNS)
|
self.nsstack.append(newNS)
|
||||||
return newNS
|
return newNS
|
||||||
|
|
||||||
@@ -353,11 +464,16 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
strVal += '>'
|
strVal += '>'
|
||||||
self.collectContent.content += strVal
|
self.collectContent.content += strVal
|
||||||
xsname = name
|
xsname = name
|
||||||
if name.find(':') > -1: # Strip namespace prefixes for now until actually looking them up in xsd
|
i = name.rfind(':')
|
||||||
name = name[name.rfind(":") + 1:]
|
if i >= 0:
|
||||||
|
nsname = name[:i]
|
||||||
|
name = name[i+1:]
|
||||||
|
else:
|
||||||
|
nsname = None
|
||||||
element = Element(name, attrs.copy(), xsname=xsname)
|
element = Element(name, attrs.copy(), xsname=xsname)
|
||||||
# if the element has namespace attributes, process them and add them to our stack
|
# if the element has namespace attributes, process them and add them to our stack
|
||||||
nse = NsElement()
|
nse = NsElement()
|
||||||
|
objtype = None
|
||||||
for k in attrs.getNames():
|
for k in attrs.getNames():
|
||||||
if k.startswith('xmlns'):
|
if k.startswith('xmlns'):
|
||||||
longNs = attrs[k]
|
longNs = attrs[k]
|
||||||
@@ -371,8 +487,28 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
nse.nsMap[shortNs] = longNs
|
nse.nsMap[shortNs] = longNs
|
||||||
elif k == 'targetNamespace':
|
elif k == 'targetNamespace':
|
||||||
nse.targetNS = attrs.getValue(k)
|
nse.targetNS = attrs.getValue(k)
|
||||||
|
elif k == 'objtype':
|
||||||
|
objtype = attrs.getValue(k)
|
||||||
nse = self.appendElementStack(element, nse)
|
nse = self.appendElementStack(element, nse)
|
||||||
element.objclass = nse.knownTypes.get(xsname)
|
if nsname != None:
|
||||||
|
if nse.nsMap.has_key(nsname):
|
||||||
|
longname = '%s:%s' % (nse.nsMap[nsname], name)
|
||||||
|
## elif objtype == None:
|
||||||
|
## errorString = 'Error unmarshalling XML document from source "%s": tag "%s" at line "%d", column "%d" has an undefined namespace' % (self.xmlSource, xsname, self._locator.getLineNumber(), self._locator.getColumnNumber())
|
||||||
|
## raise UnmarshallerException(errorString)
|
||||||
|
elif self.reversedNamespaces.has_key(nsname):
|
||||||
|
longname = '%s:%s' % (self.reversedNamespaces[nsname], name)
|
||||||
|
else:
|
||||||
|
longname = xsname
|
||||||
|
elif nse.defaultNS != None:
|
||||||
|
longname = '%s:%s' % (nse.defaultNS, name)
|
||||||
|
else:
|
||||||
|
longname = name
|
||||||
|
element.objtype = objtype
|
||||||
|
element.objclass = self.knownTypes.get(longname)
|
||||||
|
if element.objclass == None and len(self.knownNamespaces) == 0:
|
||||||
|
# handles common case where tags are unqualified and knownTypes are too, but there's a defaultNS
|
||||||
|
element.objclass = self.knownTypes.get(name)
|
||||||
if (hasattr(element.objclass, "__xmlcontent__")):
|
if (hasattr(element.objclass, "__xmlcontent__")):
|
||||||
self.collectContent = element
|
self.collectContent = element
|
||||||
|
|
||||||
@@ -387,8 +523,9 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
def endElement(self, name):
|
def endElement(self, name):
|
||||||
## print "[endElement] </%s>" % name
|
## print "[endElement] </%s>" % name
|
||||||
xsname = name
|
xsname = name
|
||||||
if name.find(":") > -1: # Strip namespace prefixes for now until actually looking them up in xsd
|
i = name.rfind(':')
|
||||||
name = name[name.find(":") + 1:]
|
if i >= 0: # Strip namespace prefixes for now until actually looking them up in xsd
|
||||||
|
name = name[i+1:]
|
||||||
if self.skipper:
|
if self.skipper:
|
||||||
if xsname == "xs:annotation" or xsname == "xsd:annotation": # here too
|
if xsname == "xs:annotation" or xsname == "xsd:annotation": # here too
|
||||||
self.skipper = False
|
self.skipper = False
|
||||||
@@ -405,34 +542,36 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
element, nse = self.popElementStack()
|
element, nse = self.popElementStack()
|
||||||
if ((len(self.elementstack) > 1) and (self.elementstack[-1].getobjtype() == "None")):
|
if ((len(self.elementstack) > 1) and (self.elementstack[-1].getobjtype() == "None")):
|
||||||
parentElement = self.elementstack[-2]
|
parentElement = self.elementstack[-2]
|
||||||
## print "[endElement] %s: found parent with objtype==None: using its grandparent" % name
|
|
||||||
elif (len(self.elementstack) > 0):
|
elif (len(self.elementstack) > 0):
|
||||||
parentElement = self.elementstack[-1]
|
parentElement = self.elementstack[-1]
|
||||||
objtype = element.getobjtype()
|
objtype = element.getobjtype()
|
||||||
## print "element objtype is: ", objtype
|
|
||||||
if (objtype == "None"):
|
if (objtype == "None"):
|
||||||
## print "[endElement] %s: skipping a (objtype==None) end tag" % name
|
|
||||||
return
|
return
|
||||||
constructorarglist = []
|
constructorarglist = []
|
||||||
if (len(element.content) > 0):
|
if (len(element.content) > 0):
|
||||||
strippedElementContent = element.content.strip()
|
strippedElementContent = element.content.strip()
|
||||||
if (len(strippedElementContent) > 0):
|
if (len(strippedElementContent) > 0):
|
||||||
constructorarglist.append(element.content)
|
constructorarglist.append(element.content)
|
||||||
|
# If the element requires an object, but none is known, use the GenericXMLObject class
|
||||||
|
if ((element.objclass == None) and (element.attrs.get("objtype") == None) and ((len(element.attrs) > 0) or (len(element.children) > 0))):
|
||||||
|
if self.createGenerics:
|
||||||
|
element.objclass = GenericXMLObject
|
||||||
obj = _objectfactory(objtype, constructorarglist, element.objclass)
|
obj = _objectfactory(objtype, constructorarglist, element.objclass)
|
||||||
|
if element.objclass == GenericXMLObject:
|
||||||
|
obj.setXMLAttributes(str(xsname), element.attrs, element.children, nse.nsMap, nse.defaultNS)
|
||||||
complexType = getComplexType(obj)
|
complexType = getComplexType(obj)
|
||||||
if (obj != None):
|
if (obj != None):
|
||||||
if (hasattr(obj, "__xmlname__") and getattr(obj, "__xmlname__") == "sequence"):
|
if (hasattr(obj, "__xmlname__") and getattr(obj, "__xmlname__") == "sequence"):
|
||||||
self.elementstack[-1].children = oldChildren
|
self.elementstack[-1].children = oldChildren
|
||||||
return
|
return
|
||||||
if (len(element.attrs) > 0) and not isinstance(obj, list):
|
if (len(element.attrs) > 0) and not isinstance(obj, list):
|
||||||
## print "[endElement] %s: element has attrs and the obj is not a list" % name
|
|
||||||
for attrname, attr in element.attrs.items():
|
for attrname, attr in element.attrs.items():
|
||||||
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
|
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
|
||||||
if attrname.startswith(XMLNS_PREFIX):
|
if attrname.startswith(XMLNS_PREFIX):
|
||||||
ns = attrname[XMLNS_PREFIX_LENGTH:]
|
ns = attrname[XMLNS_PREFIX_LENGTH:]
|
||||||
else:
|
else:
|
||||||
ns = ""
|
ns = ""
|
||||||
if complexType != None:
|
if complexType != None or element.objclass == GenericXMLObject:
|
||||||
if not hasattr(obj, "__xmlnamespaces__"):
|
if not hasattr(obj, "__xmlnamespaces__"):
|
||||||
obj.__xmlnamespaces__ = {ns:attr}
|
obj.__xmlnamespaces__ = {ns:attr}
|
||||||
elif ns not in obj.__xmlnamespaces__:
|
elif ns not in obj.__xmlnamespaces__:
|
||||||
@@ -447,7 +586,6 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
xsdElement = complexType.findElement(attrname)
|
xsdElement = complexType.findElement(attrname)
|
||||||
if (xsdElement != None):
|
if (xsdElement != None):
|
||||||
type = xsdElement.type
|
type = xsdElement.type
|
||||||
## print 'Unmarshalling element "%s", attribute "%s" with type "%s"' % (name, xsdElement.name, type)
|
|
||||||
if (type != None):
|
if (type != None):
|
||||||
if (type == TYPE_QNAME):
|
if (type == TYPE_QNAME):
|
||||||
attr = nse.expandQName(name, attrname, attr)
|
attr = nse.expandQName(name, attrname, attr)
|
||||||
@@ -455,11 +593,15 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
### ToDO remove maxOccurs hack after bug 177 is fixed
|
### ToDO remove maxOccurs hack after bug 177 is fixed
|
||||||
if attrname == "maxOccurs" and attr == "unbounded":
|
if attrname == "maxOccurs" and attr == "unbounded":
|
||||||
attr = "-1"
|
attr = "-1"
|
||||||
attr = _objectfactory(type, attr)
|
try:
|
||||||
|
attr = _objectfactory(type, attr)
|
||||||
|
except Exception, exceptData:
|
||||||
|
errorString = 'Error unmarshalling attribute "%s" at line %d, column %d in XML document from source "%s": %s' % (attrname, self._locator.getLineNumber(), self._locator.getColumnNumber(), self.xmlSource, str(exceptData))
|
||||||
|
raise UnmarshallerException(errorString)
|
||||||
try:
|
try:
|
||||||
setattrignorecase(obj, _toAttrName(obj, attrname), attr)
|
setattrignorecase(obj, _toAttrName(obj, attrname), attr)
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
errorString = 'Error unmarshalling XML document at line %i, column %i: The object type of attribute "%s" of XML element "%s": not specified or known' % (self._locator.getLineNumber(), self._locator.getColumnNumber(), attrname, name)
|
errorString = 'Error setting value of attribute "%s" at line %d, column %d in XML document from source "%s": object type of XML element "%s" is not specified or known' % (attrname, self._locator.getLineNumber(), self._locator.getColumnNumber(), self.xmlSource, name)
|
||||||
raise UnmarshallerException(errorString)
|
raise UnmarshallerException(errorString)
|
||||||
## obj.__dict__[_toAttrName(obj, attrname)] = attr
|
## obj.__dict__[_toAttrName(obj, attrname)] = attr
|
||||||
# stuff any child attributes meant to be in a sequence via the __xmlflattensequence__
|
# stuff any child attributes meant to be in a sequence via the __xmlflattensequence__
|
||||||
@@ -474,14 +616,12 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
flattenDict[str(xmlnametuple)] = sequencename
|
flattenDict[str(xmlnametuple)] = sequencename
|
||||||
else:
|
else:
|
||||||
for xmlname in xmlnametuple:
|
for xmlname in xmlnametuple:
|
||||||
## print "[endElement]: adding flattenDict[%s] = %s" % (xmlname, sequencename)
|
|
||||||
flattenDict[xmlname] = sequencename
|
flattenDict[xmlname] = sequencename
|
||||||
else:
|
else:
|
||||||
raise Exception("Invalid type for __xmlflattensequence___ : it must be a dict")
|
raise Exception("Invalid type for __xmlflattensequence___ : it must be a dict")
|
||||||
|
|
||||||
# reattach an object"s attributes to it
|
# reattach an object"s attributes to it
|
||||||
for childname, child in element.children:
|
for childname, child in element.children:
|
||||||
## print "[endElement] childname is: ", childname, "; child is: ", child
|
|
||||||
if (childname in flattenDict):
|
if (childname in flattenDict):
|
||||||
sequencename = _toAttrName(obj, flattenDict[childname])
|
sequencename = _toAttrName(obj, flattenDict[childname])
|
||||||
if (not hasattr(obj, sequencename)):
|
if (not hasattr(obj, sequencename)):
|
||||||
@@ -499,12 +639,13 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
else:
|
else:
|
||||||
obj[childname] = child
|
obj[childname] = child
|
||||||
else:
|
else:
|
||||||
## print "childname = %s, obj = %s, child = %s" % (childname, repr(obj), repr(child))
|
# don't replace a good attribute value with a bad one
|
||||||
try:
|
childAttrName = _toAttrName(obj, childname)
|
||||||
setattrignorecase(obj, _toAttrName(obj, childname), child)
|
if (not hasattr(obj, childAttrName)) or (getattr(obj, childAttrName) == None) or (getattr(obj, childAttrName) == []) or (not isinstance(child, GenericXMLObject)):
|
||||||
except AttributeError:
|
try:
|
||||||
raise MarshallerException("Error unmarshalling child element \"%s\" of XML element \"%s\": object type not specified or known" % (childname, name))
|
setattrignorecase(obj, childAttrName, child)
|
||||||
## obj.__dict__[_toAttrName(obj, childname)] = child
|
except AttributeError:
|
||||||
|
raise MarshallerException("Error unmarshalling child element \"%s\" of XML element \"%s\": object type not specified or known" % (childname, name))
|
||||||
|
|
||||||
if (complexType != None):
|
if (complexType != None):
|
||||||
for element in complexType.elements:
|
for element in complexType.elements:
|
||||||
@@ -524,7 +665,6 @@ class XMLObjectFactory(xml.sax.ContentHandler):
|
|||||||
if (len(self.elementstack) > 0):
|
if (len(self.elementstack) > 0):
|
||||||
## print "[endElement] appending child with name: ", name, "; objtype: ", objtype
|
## print "[endElement] appending child with name: ", name, "; objtype: ", objtype
|
||||||
parentElement.children.append((name, obj))
|
parentElement.children.append((name, obj))
|
||||||
## print "parentElement now has ", len(parentElement.children), " children"
|
|
||||||
else:
|
else:
|
||||||
self.rootelement = obj
|
self.rootelement = obj
|
||||||
|
|
||||||
@@ -539,7 +679,12 @@ def _toAttrName(obj, name):
|
|||||||
break
|
break
|
||||||
## if (name.startswith("__") and not name.endswith("__")):
|
## if (name.startswith("__") and not name.endswith("__")):
|
||||||
## name = "_%s%s" % (obj.__class__.__name__, name)
|
## name = "_%s%s" % (obj.__class__.__name__, name)
|
||||||
return name
|
return str(name)
|
||||||
|
|
||||||
|
def printKnownTypes(kt, where):
|
||||||
|
print 'KnownTypes from %s' % (where)
|
||||||
|
for tag, cls in kt.iteritems():
|
||||||
|
print '%s => %s' % (tag, str(cls))
|
||||||
|
|
||||||
__typeMappingXsdToLang = {
|
__typeMappingXsdToLang = {
|
||||||
"string": "str",
|
"string": "str",
|
||||||
@@ -569,7 +714,7 @@ def xsdToLangType(xsdType):
|
|||||||
if xsdType.startswith(XMLSCHEMA_XSD_URL):
|
if xsdType.startswith(XMLSCHEMA_XSD_URL):
|
||||||
xsdType = xsdType[len(XMLSCHEMA_XSD_URL)+1:]
|
xsdType = xsdType[len(XMLSCHEMA_XSD_URL)+1:]
|
||||||
elif xsdType.startswith(AG_URL):
|
elif xsdType.startswith(AG_URL):
|
||||||
xsdType = xsdType[len(AG_URL)+1:]
|
xsdType = xsdType[len(AG_URL)+1:]
|
||||||
langType = __typeMappingXsdToLang.get(xsdType)
|
langType = __typeMappingXsdToLang.get(xsdType)
|
||||||
if (langType == None):
|
if (langType == None):
|
||||||
raise Exception("Unknown xsd type %s" % xsdType)
|
raise Exception("Unknown xsd type %s" % xsdType)
|
||||||
@@ -588,8 +733,11 @@ def _getXmlValue(langValue):
|
|||||||
else:
|
else:
|
||||||
return str(langValue)
|
return str(langValue)
|
||||||
|
|
||||||
def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||||
objectfactory = XMLObjectFactory(knownTypes, knownNamespaces)
|
objectfactory = XMLObjectFactory(knownTypes, knownNamespaces, xmlSource, createGenerics)
|
||||||
|
# on Linux, pyXML's sax.parseString fails when passed unicode
|
||||||
|
if (not sysutils.isWindows()):
|
||||||
|
xmlstr = str(xmlstr)
|
||||||
try:
|
try:
|
||||||
xml.sax.parseString(xmlstr, objectfactory)
|
xml.sax.parseString(xmlstr, objectfactory)
|
||||||
except xml.sax.SAXParseException, errorData:
|
except xml.sax.SAXParseException, errorData:
|
||||||
@@ -600,17 +748,19 @@ def unmarshal(xmlstr, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
|||||||
return objectfactory.getRootObject()
|
return objectfactory.getRootObject()
|
||||||
|
|
||||||
def marshal(obj, elementName=None, prettyPrint=False, marshalType=True, indent=0, knownTypes=None, knownNamespaces=None, encoding=-1):
|
def marshal(obj, elementName=None, prettyPrint=False, marshalType=True, indent=0, knownTypes=None, knownNamespaces=None, encoding=-1):
|
||||||
## print '[marshal] entered with elementName = "%s"' % (elementName)
|
|
||||||
worker = XMLMarshalWorker(prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces)
|
worker = XMLMarshalWorker(prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces)
|
||||||
if obj != None and hasattr(obj, '__xmldeepexclude__'):
|
if obj != None and hasattr(obj, '__xmldeepexclude__'):
|
||||||
worker.xmldeepexclude = obj.__xmldeepexclude__
|
worker.xmldeepexclude = obj.__xmldeepexclude__
|
||||||
xmlstr = "".join(worker._marshal(obj, elementName, indent=indent))
|
xmlstr = "".join(worker._marshal(obj, elementName, indent=indent))
|
||||||
if (isinstance(encoding, basestring)):
|
aglogging.info(xmlMarshallerLogger, "marshal produced string of type %s", type(xmlstr))
|
||||||
return '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr.encode(encoding))
|
if (encoding == None):
|
||||||
elif (encoding == None):
|
|
||||||
return xmlstr
|
return xmlstr
|
||||||
else:
|
if (not isinstance(encoding, basestring)):
|
||||||
return '<?xml version="1.0" encoding="%s"?>\n%s' % (sys.getdefaultencoding(), xmlstr)
|
encoding = sys.getdefaultencoding()
|
||||||
|
if (not isinstance(xmlstr, unicode)):
|
||||||
|
xmlstr = xmlstr.decode()
|
||||||
|
xmlstr = u'<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr)
|
||||||
|
return xmlstr.encode(encoding)
|
||||||
|
|
||||||
class XMLMarshalWorker(object):
|
class XMLMarshalWorker(object):
|
||||||
def __init__(self, marshalType=True, prettyPrint=False, knownTypes=None, knownNamespaces=None):
|
def __init__(self, marshalType=True, prettyPrint=False, knownTypes=None, knownNamespaces=None):
|
||||||
@@ -695,7 +845,7 @@ class XMLMarshalWorker(object):
|
|||||||
newNS.prefix = self.nsstack[-1].prefix
|
newNS.prefix = self.nsstack[-1].prefix
|
||||||
else:
|
else:
|
||||||
newNS.prefix = ''
|
newNS.prefix = ''
|
||||||
if hasattr(obj, "__xmldefaultnamespace__"):
|
if obj != None and hasattr(obj, "__xmldefaultnamespace__"):
|
||||||
longPrefixNS = getattr(obj, "__xmldefaultnamespace__")
|
longPrefixNS = getattr(obj, "__xmldefaultnamespace__")
|
||||||
if longPrefixNS == defaultLongNS:
|
if longPrefixNS == defaultLongNS:
|
||||||
newNS.prefix = ''
|
newNS.prefix = ''
|
||||||
@@ -705,13 +855,12 @@ class XMLMarshalWorker(object):
|
|||||||
if v == longPrefixNS:
|
if v == longPrefixNS:
|
||||||
newNS.prefix = k + ':'
|
newNS.prefix = k + ':'
|
||||||
break;
|
break;
|
||||||
## print '[appendNSStack] found longPrefixNS in nameSpaces = "%s"' % (newNS.prefix)
|
|
||||||
except:
|
except:
|
||||||
if (longPrefixNS in asDict(self.knownNamespaces)):
|
if (longPrefixNS in asDict(self.knownNamespaces)):
|
||||||
newNS.prefix = self.knownNamespaces[longPrefixNS] + ':'
|
newNS.prefix = self.knownNamespaces[longPrefixNS] + ':'
|
||||||
else:
|
else:
|
||||||
raise MarshallerException('Error marshalling __xmldefaultnamespace__ ("%s") not defined in namespace stack' % (longPrefixNS))
|
raise MarshallerException('Error marshalling __xmldefaultnamespace__ ("%s") not defined in namespace stack' % (longPrefixNS))
|
||||||
if hasattr(obj, "targetNamespace"):
|
if obj != None and hasattr(obj, "targetNamespace"):
|
||||||
newNS.targetNS = obj.targetNamespace
|
newNS.targetNS = obj.targetNamespace
|
||||||
elif len(self.nsstack) > 0:
|
elif len(self.nsstack) > 0:
|
||||||
newNS.targetNS = self.nsstack[-1].targetNS
|
newNS.targetNS = self.nsstack[-1].targetNS
|
||||||
@@ -749,9 +898,11 @@ class XMLMarshalWorker(object):
|
|||||||
|
|
||||||
def _marshal(self, obj, elementName=None, nameSpacePrefix="", indent=0):
|
def _marshal(self, obj, elementName=None, nameSpacePrefix="", indent=0):
|
||||||
if (obj != None):
|
if (obj != None):
|
||||||
xmlMarshallerLogger.debug("--> _marshal: elementName=%s%s, type=%s, obj=%s, indent=%d" % (nameSpacePrefix, elementName, type(obj), str(obj), indent))
|
aglogging.debug(xmlMarshallerLogger, "--> _marshal: elementName=%s%s, type=%s, obj=%s, indent=%d", nameSpacePrefix, elementName, type(obj), str(obj), indent)
|
||||||
else:
|
else:
|
||||||
xmlMarshallerLogger.debug("--> _marshal: elementName=%s%s, obj is None, indent=%d" % (nameSpacePrefix, elementName, indent))
|
aglogging.debug(xmlMarshallerLogger, "--> _marshal: elementName=%s%s, obj is None, indent=%d", nameSpacePrefix, elementName, indent)
|
||||||
|
if ((obj != None) and (hasattr(obj, 'preMarshal'))):
|
||||||
|
obj.preMarshal()
|
||||||
excludeAttrs = []
|
excludeAttrs = []
|
||||||
excludeAttrs.extend(self.xmldeepexclude)
|
excludeAttrs.extend(self.xmldeepexclude)
|
||||||
if hasattr(obj, "__xmlexclude__"):
|
if hasattr(obj, "__xmlexclude__"):
|
||||||
@@ -768,8 +919,8 @@ class XMLMarshalWorker(object):
|
|||||||
newline = ""
|
newline = ""
|
||||||
increment = 0
|
increment = 0
|
||||||
## Determine the XML element name. If it isn"t specified in the
|
## Determine the XML element name. If it isn"t specified in the
|
||||||
## parameter list, look for it in the __xmlname__ Lang
|
## parameter list, look for it in the __xmlname__ attribute,
|
||||||
## attribute, else use the default generic BASETYPE_ELEMENT_NAME.
|
## else use the default generic BASETYPE_ELEMENT_NAME.
|
||||||
nameSpaceAttrs = self.appendNSStack(obj)
|
nameSpaceAttrs = self.appendNSStack(obj)
|
||||||
nameSpacePrefix = self.getNSPrefix()
|
nameSpacePrefix = self.getNSPrefix()
|
||||||
if not elementName:
|
if not elementName:
|
||||||
@@ -779,13 +930,15 @@ class XMLMarshalWorker(object):
|
|||||||
elementName = nameSpacePrefix + BASETYPE_ELEMENT_NAME
|
elementName = nameSpacePrefix + BASETYPE_ELEMENT_NAME
|
||||||
else:
|
else:
|
||||||
elementName = nameSpacePrefix + elementName
|
elementName = nameSpacePrefix + elementName
|
||||||
## print '[XMLMarshalWorker._marshal] elementName "%s"; nameSpaceAttrs is "%s"' % (elementName, nameSpaceAttrs)
|
|
||||||
|
|
||||||
if (hasattr(obj, "__xmlsequencer__")) and (obj.__xmlsequencer__ != None):
|
if (hasattr(obj, "__xmlsequencer__")) and (obj.__xmlsequencer__ != None):
|
||||||
if (XMLSCHEMA_XSD_URL in self.nsstack[-1].nameSpaces.values()):
|
if (XMLSCHEMA_XSD_URL in self.nsstack[-1].nameSpaces.values()):
|
||||||
for kShort, vLong in self.nsstack[-1].nameSpaces.iteritems():
|
for kShort, vLong in self.nsstack[-1].nameSpaces.iteritems():
|
||||||
if vLong == XMLSCHEMA_XSD_URL:
|
if vLong == XMLSCHEMA_XSD_URL:
|
||||||
xsdPrefix = kShort + ':'
|
if kShort != DEFAULT_NAMESPACE_KEY:
|
||||||
|
xsdPrefix = kShort + ':'
|
||||||
|
else:
|
||||||
|
xsdPrefix = ''
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
xsdPrefix = 'xs:'
|
xsdPrefix = 'xs:'
|
||||||
@@ -793,7 +946,6 @@ class XMLMarshalWorker(object):
|
|||||||
else:
|
else:
|
||||||
elementAdd = None
|
elementAdd = None
|
||||||
|
|
||||||
## print "marshal: entered with elementName: ", elementName
|
|
||||||
members_to_skip = []
|
members_to_skip = []
|
||||||
## Add more members_to_skip based on ones the user has selected
|
## Add more members_to_skip based on ones the user has selected
|
||||||
## via the __xmlexclude__ and __xmldeepexclude__ attributes.
|
## via the __xmlexclude__ and __xmldeepexclude__ attributes.
|
||||||
@@ -806,7 +958,6 @@ class XMLMarshalWorker(object):
|
|||||||
xmlattributes = obj.__xmlattributes__
|
xmlattributes = obj.__xmlattributes__
|
||||||
members_to_skip.extend(xmlattributes)
|
members_to_skip.extend(xmlattributes)
|
||||||
for attr in xmlattributes:
|
for attr in xmlattributes:
|
||||||
## print 'Processing element "%s"; attribute "%s"' % (elementName, attr)
|
|
||||||
internalAttrName = attr
|
internalAttrName = attr
|
||||||
ifDefPy()
|
ifDefPy()
|
||||||
if (attr.startswith("__") and not attr.endswith("__")):
|
if (attr.startswith("__") and not attr.endswith("__")):
|
||||||
@@ -814,7 +965,6 @@ class XMLMarshalWorker(object):
|
|||||||
endIfDef()
|
endIfDef()
|
||||||
# Fail silently if a python attribute is specified to be
|
# Fail silently if a python attribute is specified to be
|
||||||
# an XML attribute but is missing.
|
# an XML attribute but is missing.
|
||||||
## print "marshal: processing attribute ", internalAttrName
|
|
||||||
attrNameSpacePrefix = ""
|
attrNameSpacePrefix = ""
|
||||||
if hasattr(obj, "__xmlattrnamespaces__"):
|
if hasattr(obj, "__xmlattrnamespaces__"):
|
||||||
for nameSpaceKey, nameSpaceAttributes in getattr(obj, "__xmlattrnamespaces__").iteritems():
|
for nameSpaceKey, nameSpaceAttributes in getattr(obj, "__xmlattrnamespaces__").iteritems():
|
||||||
@@ -856,8 +1006,7 @@ class XMLMarshalWorker(object):
|
|||||||
else:
|
else:
|
||||||
value = objutils.toDiffableRepr(value)
|
value = objutils.toDiffableRepr(value)
|
||||||
|
|
||||||
objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, saxutils.escape(value))
|
objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, utillang.escape(value))
|
||||||
## print "marshal: new objattrs is: ", objattrs
|
|
||||||
if (obj == None):
|
if (obj == None):
|
||||||
xmlString = [""]
|
xmlString = [""]
|
||||||
elif isinstance(obj, bool):
|
elif isinstance(obj, bool):
|
||||||
@@ -873,9 +1022,18 @@ class XMLMarshalWorker(object):
|
|||||||
objTypeStr = self._genObjTypeStr("float")
|
objTypeStr = self._genObjTypeStr("float")
|
||||||
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||||
elif isinstance(obj, unicode): # have to check before basestring - unicode is instance of base string
|
elif isinstance(obj, unicode): # have to check before basestring - unicode is instance of base string
|
||||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj.encode()), elementName, newline)]
|
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, utillang.escape(obj.encode()), elementName, newline)]
|
||||||
elif isinstance(obj, basestring):
|
elif isinstance(obj, basestring):
|
||||||
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj), elementName, newline)]
|
xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, utillang.escape(obj), elementName, newline)]
|
||||||
|
elif isinstance(obj, datetime.datetime):
|
||||||
|
objTypeStr = self._genObjTypeStr("datetime")
|
||||||
|
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||||
|
elif isinstance(obj, datetime.date):
|
||||||
|
objTypeStr = self._genObjTypeStr("date")
|
||||||
|
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||||
|
elif isinstance(obj, datetime.time):
|
||||||
|
objTypeStr = self._genObjTypeStr("time")
|
||||||
|
xmlString = ['%s<%s%s>%s</%s>%s' % (prefix, elementName, objTypeStr, str(obj), elementName, newline)]
|
||||||
elif isinstance(obj, list):
|
elif isinstance(obj, list):
|
||||||
if len(obj) < 1:
|
if len(obj) < 1:
|
||||||
xmlString = ""
|
xmlString = ""
|
||||||
@@ -910,13 +1068,15 @@ class XMLMarshalWorker(object):
|
|||||||
elif hasattr(obj, "__xmlcontent__"):
|
elif hasattr(obj, "__xmlcontent__"):
|
||||||
contentValue = getattr(obj, obj.__xmlcontent__)
|
contentValue = getattr(obj, obj.__xmlcontent__)
|
||||||
if contentValue == None:
|
if contentValue == None:
|
||||||
contentValue = ''
|
xmlString = ["%s<%s%s%s/>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, newline)]
|
||||||
else:
|
else:
|
||||||
contentValue = saxutils.escape(contentValue)
|
contentValue = utillang.escape(contentValue)
|
||||||
xmlString = ["%s<%s%s%s>%s</%s>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, contentValue, elementName, newline)]
|
xmlString = ["%s<%s%s%s>%s</%s>%s" % (prefix, elementName, nameSpaceAttrs, objattrs, contentValue, elementName, newline)]
|
||||||
else:
|
else:
|
||||||
# Only add the objtype if the element tag is unknown to us.
|
# Only add the objtype if the element tag is unknown to us.
|
||||||
if (self.isKnownType(elementName) == True):
|
if (isinstance(obj, GenericXMLObject)):
|
||||||
|
objTypeStr = ""
|
||||||
|
elif (self.isKnownType(elementName) == True):
|
||||||
objTypeStr = ""
|
objTypeStr = ""
|
||||||
else:
|
else:
|
||||||
objTypeStr = self._genObjTypeStr("%s.%s" % (obj.__class__.__module__, className))
|
objTypeStr = self._genObjTypeStr("%s.%s" % (obj.__class__.__module__, className))
|
||||||
@@ -929,7 +1089,7 @@ class XMLMarshalWorker(object):
|
|||||||
if hasattr(obj, "__xmlbody__"):
|
if hasattr(obj, "__xmlbody__"):
|
||||||
xmlbody = getattr(obj, obj.__xmlbody__)
|
xmlbody = getattr(obj, obj.__xmlbody__)
|
||||||
if xmlbody != None:
|
if xmlbody != None:
|
||||||
xmlMemberString.append(xmlbody)
|
xmlMemberString.append(utillang.escape(xmlbody))
|
||||||
else:
|
else:
|
||||||
if hasattr(obj, "__xmlattrgroups__"):
|
if hasattr(obj, "__xmlattrgroups__"):
|
||||||
attrGroups = obj.__xmlattrgroups__.copy()
|
attrGroups = obj.__xmlattrgroups__.copy()
|
||||||
@@ -975,21 +1135,17 @@ class XMLMarshalWorker(object):
|
|||||||
xmlname = None
|
xmlname = None
|
||||||
if (len(xmlnametuple) == 1):
|
if (len(xmlnametuple) == 1):
|
||||||
xmlname = xmlnametuple[0]
|
xmlname = xmlnametuple[0]
|
||||||
## ix = 0
|
|
||||||
if not isinstance(value, (list, tuple)):
|
if not isinstance(value, (list, tuple)):
|
||||||
value = [value]
|
value = [value]
|
||||||
for seqitem in value:
|
for seqitem in value:
|
||||||
## xmlname = xmlnametuple[ix]
|
|
||||||
## ix += 1
|
|
||||||
## if (ix >= len(xmlnametuple)):
|
|
||||||
## ix = 0
|
|
||||||
xmlMemberString.extend(self._marshal(seqitem, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
xmlMemberString.extend(self._marshal(seqitem, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
||||||
else:
|
else:
|
||||||
if (hasattr(obj, "__xmlrename__") and name in asDict(obj.__xmlrename__)):
|
if (hasattr(obj, "__xmlrename__") and name in asDict(obj.__xmlrename__)):
|
||||||
xmlname = obj.__xmlrename__[name]
|
xmlname = obj.__xmlrename__[name]
|
||||||
else:
|
else:
|
||||||
xmlname = name
|
xmlname = name
|
||||||
xmlMemberString.extend(self._marshal(value, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
if (value != None):
|
||||||
|
xmlMemberString.extend(self._marshal(value, xmlname, subElementNameSpacePrefix, indent=indent+increment))
|
||||||
if (eName != "__nogroup__"):
|
if (eName != "__nogroup__"):
|
||||||
xmlMemberString.append("%s</%s>%s" % (prefix, eName, newline))
|
xmlMemberString.append("%s</%s>%s" % (prefix, eName, newline))
|
||||||
prefix = prefix[:-increment]
|
prefix = prefix[:-increment]
|
||||||
@@ -1022,8 +1178,8 @@ class XMLMarshalWorker(object):
|
|||||||
xmlString.append("><![CDATA[%s]]></%s>%s" % (cdataContent, elementName, newline))
|
xmlString.append("><![CDATA[%s]]></%s>%s" % (cdataContent, elementName, newline))
|
||||||
else:
|
else:
|
||||||
xmlString.append("/>%s" % newline)
|
xmlString.append("/>%s" % newline)
|
||||||
## return xmlString
|
if aglogging.isEnabledForDebug(xmlMarshallerLogger):
|
||||||
xmlMarshallerLogger.debug("<-- _marshal: %s" % str(xmlString))
|
aglogging.debug(xmlMarshallerLogger, "<-- _marshal: %s", objutils.toDiffableString(xmlString))
|
||||||
#print "<-- _marshal: %s" % str(xmlString)
|
#print "<-- _marshal: %s" % str(xmlString)
|
||||||
self.popNSStack()
|
self.popNSStack()
|
||||||
return xmlString
|
return xmlString
|
||||||
|
@@ -22,35 +22,44 @@ import activegrid.util.aglogging as aglogging
|
|||||||
|
|
||||||
xmlLogger = logging.getLogger("activegrid.util.xml")
|
xmlLogger = logging.getLogger("activegrid.util.xml")
|
||||||
|
|
||||||
def load(fileName, knownTypes=None, knownNamespaces=None):
|
def load(fileName, knownTypes=None, knownNamespaces=None, createGenerics=False):
|
||||||
loadedObject = None
|
loadedObject = None
|
||||||
fileObject = file(fileName)
|
fileObject = file(fileName)
|
||||||
timeStart = time.time()
|
timeStart = time.time()
|
||||||
|
xml = ""
|
||||||
try:
|
try:
|
||||||
xml = fileObject.read()
|
xml = fileObject.read()
|
||||||
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=fileName)
|
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=fileName, createGenerics=createGenerics)
|
||||||
loadedObject.fileName = os.path.abspath(fileName)
|
loadedObject.fileName = os.path.abspath(fileName)
|
||||||
if hasattr(loadedObject, 'initialize'):
|
if hasattr(loadedObject, 'initialize'):
|
||||||
loadedObject.initialize()
|
loadedObject.initialize()
|
||||||
finally:
|
finally:
|
||||||
fileObject.close()
|
fileObject.close()
|
||||||
timeDone = time.time()
|
if xmlLogger.isEnabledFor(aglogging.LEVEL_INFO):
|
||||||
aglogging.info(xmlLogger, ('Load statistics for file %s: elapsed time = %f secs' % (fileName, timeDone-timeStart)))
|
timeDone = time.time()
|
||||||
|
aglogging.info(xmlLogger, ('Load statistics for file %s (%d bytes): elapsed time = %f secs' % (fileName, len(xml), timeDone-timeStart)))
|
||||||
return loadedObject
|
return loadedObject
|
||||||
|
|
||||||
def loadURI(uri, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
def loadURI(uri, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||||
loadedObject = None
|
loadedObject = None
|
||||||
xml = urllib.urlopen(uri).read()
|
timeStart = time.time()
|
||||||
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource)
|
xml = ""
|
||||||
loadedObject.fileName = uri
|
try:
|
||||||
if hasattr(loadedObject, 'initialize'):
|
xml = urllib.urlopen(uri).read()
|
||||||
loadedObject.initialize()
|
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource, createGenerics=createGenerics)
|
||||||
|
loadedObject.fileName = uri
|
||||||
|
if hasattr(loadedObject, 'initialize'):
|
||||||
|
loadedObject.initialize()
|
||||||
|
finally:
|
||||||
|
if xmlLogger.isEnabledFor(aglogging.LEVEL_INFO):
|
||||||
|
timeDone = time.time()
|
||||||
|
aglogging.info(xmlLogger, ('Load statistics for URI %s (%d bytes): elapsed time = %f secs' % (uri, len(xml), timeDone-timeStart)))
|
||||||
return loadedObject
|
return loadedObject
|
||||||
|
|
||||||
def unmarshal(xml, knownTypes=None, knownNamespaces=None, xmlSource=None):
|
def unmarshal(xml, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||||
if (knownTypes == None):
|
if (knownTypes == None):
|
||||||
knownTypes, knownNamespaces = getAgKnownTypes()
|
knownTypes, knownNamespaces = getAgKnownTypes()
|
||||||
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource)
|
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource, createGenerics=createGenerics)
|
||||||
|
|
||||||
def save(fileName, objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
|
def save(fileName, objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
|
||||||
if hasattr(objectToSave, '_xmlReadOnly') and objectToSave._xmlReadOnly == True:
|
if hasattr(objectToSave, '_xmlReadOnly') and objectToSave._xmlReadOnly == True:
|
||||||
@@ -155,41 +164,6 @@ def getAgVersion(fileName):
|
|||||||
version = xml[i+1:j]
|
version = xml[i+1:j]
|
||||||
return version
|
return version
|
||||||
|
|
||||||
def escape(data):
|
|
||||||
"""Escape ', ", &, <, and > in a string of data.
|
|
||||||
|
|
||||||
Basically, everything that saxutils.escape does (and this calls that, at
|
|
||||||
least for now), but with " added as well.
|
|
||||||
|
|
||||||
XXX TODO make this faster; saxutils.escape() is really slow
|
|
||||||
"""
|
|
||||||
|
|
||||||
import xml.sax.saxutils as saxutils
|
|
||||||
|
|
||||||
data=saxutils.escape(data)
|
|
||||||
data=data.replace("\"", """)
|
|
||||||
|
|
||||||
# IE doesn't support '
|
|
||||||
# data=data.replace("\'", "'")
|
|
||||||
data=data.replace("\'", "'")
|
|
||||||
|
|
||||||
return data
|
|
||||||
|
|
||||||
def unescape(data):
|
|
||||||
"""Unescape ', ", &, <, and > in a string of data.
|
|
||||||
|
|
||||||
Basically, everything that saxutils.unescape does (and this calls that, at
|
|
||||||
least for now), but with " added as well.
|
|
||||||
|
|
||||||
XXX TODO make this faster; saxutils.unescape() is really slow
|
|
||||||
"""
|
|
||||||
|
|
||||||
import xml.sax.saxutils as saxutils
|
|
||||||
|
|
||||||
data=data.replace(""", "\"")
|
|
||||||
data=data.replace("'", "\'")
|
|
||||||
return saxutils.unescape(data)
|
|
||||||
|
|
||||||
|
|
||||||
AG_NS_URL = "http://www.activegrid.com/ag.xsd"
|
AG_NS_URL = "http://www.activegrid.com/ag.xsd"
|
||||||
BPEL_NS_URL = "http://schemas.xmlsoap.org/ws/2003/03/business-process"
|
BPEL_NS_URL = "http://schemas.xmlsoap.org/ws/2003/03/business-process"
|
||||||
@@ -197,7 +171,9 @@ HTTP_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/http/"
|
|||||||
MIME_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/mime/"
|
MIME_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/mime/"
|
||||||
SOAP_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap/"
|
SOAP_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap/"
|
||||||
SOAP12_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap12/"
|
SOAP12_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap12/"
|
||||||
|
SOAP_NS_ENCODING = "http://schemas.xmlsoap.org/soap/encoding/"
|
||||||
WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/"
|
WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/"
|
||||||
|
WSSE_NS_URL = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
|
||||||
XFORMS_NS_URL = "http://www.w3c.org/xform.xsd"
|
XFORMS_NS_URL = "http://www.w3c.org/xform.xsd"
|
||||||
XMLSCHEMA_NS_URL = "http://www.w3.org/2001/XMLSchema"
|
XMLSCHEMA_NS_URL = "http://www.w3.org/2001/XMLSchema"
|
||||||
XSI_NS_URL = "http://www.w3.org/2001/XMLSchema-instance"
|
XSI_NS_URL = "http://www.w3.org/2001/XMLSchema-instance"
|
||||||
@@ -209,7 +185,8 @@ KNOWN_NAMESPACES = { AG_NS_URL : "ag",
|
|||||||
MIME_WSDL_NS_URL : "mime",
|
MIME_WSDL_NS_URL : "mime",
|
||||||
SOAP_NS_URL : "soap",
|
SOAP_NS_URL : "soap",
|
||||||
SOAP12_NS_URL : "soap12",
|
SOAP12_NS_URL : "soap12",
|
||||||
WSDL_NS_URL : "wsdl",
|
WSDL_NS_URL : "wsdl",
|
||||||
|
WSSE_NS_URL : "wsse",
|
||||||
XFORMS_NS_URL : "xforms",
|
XFORMS_NS_URL : "xforms",
|
||||||
XMLSCHEMA_NS_URL : "xs",
|
XMLSCHEMA_NS_URL : "xs",
|
||||||
XACML_NS_URL : "xacml",
|
XACML_NS_URL : "xacml",
|
||||||
@@ -226,19 +203,23 @@ def getAgXsdToClassName():
|
|||||||
"ag:body" : "activegrid.model.processmodel.Body",
|
"ag:body" : "activegrid.model.processmodel.Body",
|
||||||
"ag:category_substitutions" : "activegrid.server.layoutrenderer.CategorySubstitutions",
|
"ag:category_substitutions" : "activegrid.server.layoutrenderer.CategorySubstitutions",
|
||||||
"ag:command" : "activegrid.model.wsdl.Command",
|
"ag:command" : "activegrid.model.wsdl.Command",
|
||||||
|
"ag:setElement" : "activegrid.model.processmodel.SetElementOperation",
|
||||||
"ag:css" : "activegrid.server.layoutrenderer.CSS",
|
"ag:css" : "activegrid.server.layoutrenderer.CSS",
|
||||||
"ag:cssRule" : "activegrid.model.processmodel.CssRule",
|
|
||||||
"ag:databaseService" : "activegrid.server.deployment.DatabaseService",
|
"ag:databaseService" : "activegrid.server.deployment.DatabaseService",
|
||||||
"ag:datasource" : "activegrid.data.dataservice.DataSource",
|
"ag:datasource" : "activegrid.data.dataservice.DataSource",
|
||||||
"ag:dataObjectList" : "activegrid.data.datalang.DataObjectList",
|
"ag:dataObjectList" : "activegrid.data.datalang.DataObjectList",
|
||||||
"ag:debug" : "activegrid.model.processmodel.DebugOperation",
|
"ag:debug" : "activegrid.model.processmodel.DebugOperation",
|
||||||
"ag:deployment" : "activegrid.server.deployment.Deployment",
|
"ag:deployment" : "activegrid.server.deployment.Deployment",
|
||||||
|
"ag:formData" : "activegrid.model.processmodel.FormData",
|
||||||
|
"ag:formVar" : "activegrid.model.processmodel.FormVar",
|
||||||
"ag:generator" : "activegrid.server.layoutrenderer.SerializableGenerator",
|
"ag:generator" : "activegrid.server.layoutrenderer.SerializableGenerator",
|
||||||
"ag:head" : "activegrid.server.layoutrenderer.Head",
|
"ag:head" : "activegrid.server.layoutrenderer.Head",
|
||||||
"ag:hr" : "activegrid.model.processmodel.HorizontalRow",
|
"ag:hr" : "activegrid.model.processmodel.HorizontalRow",
|
||||||
"ag:identity" : "activegrid.model.identitymodel.Identity",
|
"ag:identity" : "activegrid.model.identitymodel.Identity",
|
||||||
"ag:identityref" : "activegrid.server.deployment.IdentityRef",
|
"ag:identityref" : "activegrid.server.deployment.IdentityRef",
|
||||||
"ag:image" : "activegrid.model.processmodel.Image",
|
"ag:image" : "activegrid.model.processmodel.Image",
|
||||||
|
"ag:inputPart" : "activegrid.model.processmodel.InputPart",
|
||||||
|
"ag:keystore" : "activegrid.model.identitymodel.KeyStore",
|
||||||
"ag:label" : "activegrid.model.processmodel.Label",
|
"ag:label" : "activegrid.model.processmodel.Label",
|
||||||
"ag:layout" : "activegrid.server.layoutrenderer.Layout",
|
"ag:layout" : "activegrid.server.layoutrenderer.Layout",
|
||||||
"ag:layouts" : "activegrid.server.layoutrenderer.Layouts",
|
"ag:layouts" : "activegrid.server.layoutrenderer.Layouts",
|
||||||
@@ -246,9 +227,11 @@ def getAgXsdToClassName():
|
|||||||
"ag:localService" : "activegrid.server.deployment.LocalService",
|
"ag:localService" : "activegrid.server.deployment.LocalService",
|
||||||
"ag:parameter" : "activegrid.server.layoutrenderer.Parameter",
|
"ag:parameter" : "activegrid.server.layoutrenderer.Parameter",
|
||||||
"ag:parameters" : "activegrid.server.layoutrenderer.Parameters",
|
"ag:parameters" : "activegrid.server.layoutrenderer.Parameters",
|
||||||
|
"ag:postInitialize" : "activegrid.model.processmodel.PostInitialize",
|
||||||
"ag:processref" : "activegrid.server.deployment.ProcessRef",
|
"ag:processref" : "activegrid.server.deployment.ProcessRef",
|
||||||
"ag:query" : "activegrid.model.processmodel.Query",
|
"ag:query" : "activegrid.model.processmodel.Query",
|
||||||
"ag:soapService" : "activegrid.server.deployment.SoapService",
|
"ag:soapService" : "activegrid.server.deployment.SoapService",
|
||||||
|
"ag:redirect" : "activegrid.server.layoutrenderer.Redirect",
|
||||||
"ag:requiredFile" : "activegrid.server.layoutrenderer.RequiredFile",
|
"ag:requiredFile" : "activegrid.server.layoutrenderer.RequiredFile",
|
||||||
"ag:resource" : "activegrid.model.identitymodel.IDResource",
|
"ag:resource" : "activegrid.model.identitymodel.IDResource",
|
||||||
"ag:restService" : "activegrid.server.deployment.RestService",
|
"ag:restService" : "activegrid.server.deployment.RestService",
|
||||||
@@ -355,27 +338,38 @@ def getAgXsdToClassName():
|
|||||||
"xforms:xforms" : "activegrid.model.processmodel.XFormsRoot",
|
"xforms:xforms" : "activegrid.model.processmodel.XFormsRoot",
|
||||||
"xs:all" : "activegrid.model.schema.XsdSequence",
|
"xs:all" : "activegrid.model.schema.XsdSequence",
|
||||||
"xs:any" : "activegrid.model.schema.XsdAny",
|
"xs:any" : "activegrid.model.schema.XsdAny",
|
||||||
|
"xs:anyAttribute" : "activegrid.model.schema.XsdAnyAttribute",
|
||||||
"xs:attribute" : "activegrid.model.schema.XsdAttribute",
|
"xs:attribute" : "activegrid.model.schema.XsdAttribute",
|
||||||
|
"xs:choice" : "activegrid.model.schema.XsdChoice",
|
||||||
"xs:complexContent" : "activegrid.model.schema.XsdComplexContent",
|
"xs:complexContent" : "activegrid.model.schema.XsdComplexContent",
|
||||||
"xs:complexType" : "activegrid.model.schema.XsdComplexType",
|
"xs:complexType" : "activegrid.model.schema.XsdComplexType",
|
||||||
|
"xs:documentation" : "activegrid.model.schema.XsdDocumentation",
|
||||||
"xs:element" : "activegrid.model.schema.XsdElement",
|
"xs:element" : "activegrid.model.schema.XsdElement",
|
||||||
"xs:enumeration" : "activegrid.model.schema.XsdEnumeration",
|
"xs:enumeration" : "activegrid.model.schema.XsdFacetEnumeration",
|
||||||
"xs:extension" : "activegrid.model.schema.XsdExtension",
|
"xs:extension" : "activegrid.model.schema.XsdExtension",
|
||||||
|
"xs:fractionDigits" : "activegrid.model.schema.XsdFacetFractionDigits",
|
||||||
"xs:field" : "activegrid.model.schema.XsdKeyField",
|
"xs:field" : "activegrid.model.schema.XsdKeyField",
|
||||||
"xs:import" : "activegrid.model.schema.XsdInclude",
|
"xs:import" : "activegrid.model.schema.XsdInclude",
|
||||||
"xs:include" : "activegrid.model.schema.XsdInclude",
|
"xs:include" : "activegrid.model.schema.XsdInclude",
|
||||||
"xs:key" : "activegrid.model.schema.XsdKey",
|
"xs:key" : "activegrid.model.schema.XsdKey",
|
||||||
"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
|
"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
|
||||||
"xs:length" : "activegrid.model.schema.XsdLength",
|
"xs:length" : "activegrid.model.schema.XsdFacetLength",
|
||||||
"xs:list" : "activegrid.model.schema.XsdList",
|
"xs:list" : "activegrid.model.schema.XsdList",
|
||||||
"xs:maxLength" : "activegrid.model.schema.XsdMaxLength",
|
"xs:maxExclusive" : "activegrid.model.schema.XsdFacetMaxExclusive",
|
||||||
|
"xs:maxInclusive" : "activegrid.model.schema.XsdFacetMaxInclusive",
|
||||||
|
"xs:maxLength" : "activegrid.model.schema.XsdFacetMaxLength",
|
||||||
|
"xs:minExclusive" : "activegrid.model.schema.XsdFacetMinExclusive",
|
||||||
|
"xs:minInclusive" : "activegrid.model.schema.XsdFacetMinInclusive",
|
||||||
|
"xs:minLength" : "activegrid.model.schema.XsdFacetMinLength",
|
||||||
|
"xs:pattern" : "activegrid.model.schema.XsdFacetPattern",
|
||||||
"xs:restriction" : "activegrid.model.schema.XsdRestriction",
|
"xs:restriction" : "activegrid.model.schema.XsdRestriction",
|
||||||
"xs:schema" : "activegrid.model.schema.Schema",
|
"xs:schema" : "activegrid.model.schema.Schema",
|
||||||
"xs:selector" : "activegrid.model.schema.XsdKeySelector",
|
"xs:selector" : "activegrid.model.schema.XsdKeySelector",
|
||||||
"xs:sequence" : "activegrid.model.schema.XsdSequence",
|
"xs:sequence" : "activegrid.model.schema.XsdSequence",
|
||||||
"xs:simpleContent" : "activegrid.model.schema.XsdSimpleContent",
|
"xs:simpleContent" : "activegrid.model.schema.XsdSimpleContent",
|
||||||
"xs:simpleType" : "activegrid.model.schema.XsdSimpleType",
|
"xs:simpleType" : "activegrid.model.schema.XsdSimpleType",
|
||||||
"xs:totalDigits" : "activegrid.model.schema.XsdTotalDigits",
|
"xs:totalDigits" : "activegrid.model.schema.XsdFacetTotalDigits",
|
||||||
|
"xs:whiteSpace" : "activegrid.model.schema.XsdFacetWhiteSpace",
|
||||||
}
|
}
|
||||||
return agXsdToClassName
|
return agXsdToClassName
|
||||||
|
|
||||||
|
@@ -121,6 +121,7 @@ class FindService(wx.lib.pydocview.DocService):
|
|||||||
self._findDialog = None
|
self._findDialog = None
|
||||||
|
|
||||||
self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString)
|
self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString)
|
||||||
|
self._replaceDialog.CenterOnParent()
|
||||||
self._replaceDialog.Show(True)
|
self._replaceDialog.Show(True)
|
||||||
else:
|
else:
|
||||||
if self._replaceDialog != None:
|
if self._replaceDialog != None:
|
||||||
@@ -129,6 +130,7 @@ class FindService(wx.lib.pydocview.DocService):
|
|||||||
self._replaceDialog = None
|
self._replaceDialog = None
|
||||||
|
|
||||||
self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString)
|
self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString)
|
||||||
|
self._findDialog.CenterOnParent()
|
||||||
self._findDialog.Show(True)
|
self._findDialog.Show(True)
|
||||||
|
|
||||||
|
|
||||||
@@ -152,6 +154,7 @@ class FindService(wx.lib.pydocview.DocService):
|
|||||||
""" Display Goto Line Number dialog box """
|
""" Display Goto Line Number dialog box """
|
||||||
line = -1
|
line = -1
|
||||||
dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line"))
|
dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line"))
|
||||||
|
dialog.CenterOnParent()
|
||||||
if dialog.ShowModal() == wx.ID_OK:
|
if dialog.ShowModal() == wx.ID_OK:
|
||||||
try:
|
try:
|
||||||
line = int(dialog.GetValue())
|
line = int(dialog.GetValue())
|
||||||
@@ -356,7 +359,10 @@ class FindDialog(wx.Dialog):
|
|||||||
wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent)
|
wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent)
|
||||||
cancelBtn = wx.Button(self, wx.ID_CANCEL)
|
cancelBtn = wx.Button(self, wx.ID_CANCEL)
|
||||||
wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose)
|
wx.EVT_BUTTON(self, wx.ID_CANCEL, self.OnClose)
|
||||||
buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE)
|
BTM_SPACE = HALF_SPACE
|
||||||
|
if wx.Platform == "__WXMAC__":
|
||||||
|
BTM_SPACE = SPACE
|
||||||
|
buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||||
buttonSizer.Add(cancelBtn, 0)
|
buttonSizer.Add(cancelBtn, 0)
|
||||||
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
||||||
|
|
||||||
@@ -455,9 +461,14 @@ class FindReplaceDialog(FindDialog):
|
|||||||
wx.EVT_BUTTON(self, FindService.REPLACEONE_ID, self.OnActionEvent)
|
wx.EVT_BUTTON(self, FindService.REPLACEONE_ID, self.OnActionEvent)
|
||||||
replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All"))
|
replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All"))
|
||||||
wx.EVT_BUTTON(self, FindService.REPLACEALL_ID, self.OnActionEvent)
|
wx.EVT_BUTTON(self, FindService.REPLACEALL_ID, self.OnActionEvent)
|
||||||
buttonSizer.Add(findBtn, 0, wx.BOTTOM, HALF_SPACE)
|
|
||||||
buttonSizer.Add(replaceBtn, 0, wx.BOTTOM, HALF_SPACE)
|
BTM_SPACE = HALF_SPACE
|
||||||
buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, HALF_SPACE)
|
if wx.Platform == "__WXMAC__":
|
||||||
|
BTM_SPACE = SPACE
|
||||||
|
|
||||||
|
buttonSizer.Add(findBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||||
|
buttonSizer.Add(replaceBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||||
|
buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||||
buttonSizer.Add(cancelBtn, 0)
|
buttonSizer.Add(cancelBtn, 0)
|
||||||
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
||||||
|
|
||||||
@@ -495,12 +506,24 @@ def getFindData():
|
|||||||
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\x81IDAT8\x8d\xa5S\xc1\x16\xc0\x10\x0ckk\xff\xff\xc7d\x87\xad^U\r\
|
\x00\x01\xb1IDAT8\x8d\xa5\x93=o\xd3P\x14\x86\x1f\xa7\x11\x95<\xdc\xc6\xecN+5\
|
||||||
\x93S\xe5U$\n\xb3$:\xc1e\x17(\x19Z\xb3$\x9e\xf1DD\xe2\x15\x01x\xea\x93\xef\
|
[\x86B\x99\xacLQ2Zr[\x89\xa1\xfd\x0b%\x95\x90\x00\xf1\x03\x80\x01\x98\x80\
|
||||||
\x04\x989\xea\x1b\xf2U\xc0\xda\xb4\xeb\x11\x1f:\xd8\xb5\xff8\x93\xd4\xa9\xae\
|
\x19G\xac\x0cm\xff@Y\xd9:\xd9Ck\x94\xd6\xddb\x94\x9b\x98\xc8\xd2e1C\xe5\x8b\
|
||||||
@/S\xaaUwJ3\x85\xc0\x81\xee\xeb.q\x17C\x81\xd5XU \x1a\x93\xc6\x18\x8d\x90\
|
\xdd\x14\x96\xbe\xdb=\x1f\xefy\xef\xf90\x8c\xda\x12wA\xbd\xfc\x18\xfa\x9fs\
|
||||||
\xe8}\x89\x00\x9a&\x9b_k\x94\x0c\xdf\xd78\xf8\x0b\x99Y\xb4\x08c\x9e\xfe\xc6\
|
\x80\xf9|\x0e\xc0\x93\xc1\x81\x01\xf0\xe6\xf5\xab\x1c`:\x9d\x02\xf0\xf6\xdd{\
|
||||||
\xe3\x087\xf9\xd0D\x180\xf1#\x8e\x00\x00\x00\x00IEND\xaeB`\x82'
|
\xa3\xc8\xa9\xddd\xec\xf5z\xb4Z\xeb\x00\x1c\x1f\x1d\xe6\x85\xdd\xf3<\x06\x83\
|
||||||
|
\xc1\x82\xbd\xa2 \x0cCL\xd3d<\x1e\x13\xc71\xb6m\x030\x1a\x8d\x08\x82\x00\x80\
|
||||||
|
\xb3\xb3s:\x9d\x8e\xce\xa9(h6\x9b8\x8e\x83m\xdb4\x1a\r\x82 \xe0\xc5\xf3g\xb9\
|
||||||
|
eY\xb4\xdbm\x1c\xc7Y\xe8\x81&\xf8\xf4\xf1C\xde\xedv+\xce\x97Owx\xfc\xe8k\xc5\
|
||||||
|
\xb6\xb7\xb7\x8b\xef\x0foW \x84\xe0\xea\xea\x02\xa5\x94n\x18\x80\x94\x92\xd9\
|
||||||
|
l\x02@\x96e\x95>\xd4nVO\xd3\xb9\x0e\xba\r\xa6i\xd2\xef\xf7\xf0\xfd!\xc7G\x87\
|
||||||
|
y\xed:)\xd5\x01J\xfd\xd6c\xfc~\x9a\xfc\x93\xe8\xf2\xf2\x02(Ma6\x9b \x84@)\
|
||||||
|
\xa5\t}\xff\x0b\xd0\'I~R\x14\xca\xb2L\xfb\x97\x97\xef-\xeeA!_J\x89\xeb\xba\
|
||||||
|
\xb8\xae\xab\xbf\x06\x7f\x97\xacP[\x87\xeb9\x0b!H\x92\ta\x18"\xa5\xd4U\xbd\
|
||||||
|
\xadm\xe3\xe1\x83\x8d<\x8a~\x90\xa6\xbf\x88\xe3\x18)\xa5&\xa9\x03X\x96E\xab\
|
||||||
|
\xb5\x8em7\xf5\xc2\x94\xb1\xba\xba\xc6\xe6\xe6\x06++\xf7\x89\xa2\xa8\xe2\xd3\
|
||||||
|
=89\xf9Va.\x14\x14\xd8\xdf?X VJa\x14\xd7X\xde\xef2\xbc\xadm\xe3\x7f~\xe3\xae\
|
||||||
|
\xe7\xfc\x07\x84;\xc5\x82\xa1m&\x95\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||||
|
|
||||||
|
|
||||||
def getFindBitmap():
|
def getFindBitmap():
|
||||||
|
@@ -17,45 +17,45 @@ import FindService
|
|||||||
_ = wx.GetTranslation
|
_ = wx.GetTranslation
|
||||||
|
|
||||||
class TextDocument(wx.lib.docview.Document):
|
class TextDocument(wx.lib.docview.Document):
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
wx.lib.docview.Document .__init__(self)
|
||||||
|
self._inModify = False
|
||||||
|
|
||||||
|
|
||||||
def OnSaveDocument(self, filename):
|
def SaveObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
if not view.GetTextCtrl().SaveFile(filename):
|
fileObject.write(view.GetTextCtrl().GetValue())
|
||||||
return False
|
|
||||||
self.Modify(False)
|
|
||||||
self.SetDocumentSaved(True)
|
|
||||||
#if wx.Platform == "__WXMAC__":
|
|
||||||
# fn = wx.Filename(filename)
|
|
||||||
# fn.MacSetDefaultTypeAndCreator()
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def OnOpenDocument(self, filename):
|
def LoadObject(self, fileObject):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
if not view.GetTextCtrl().LoadFile(filename):
|
data = fileObject.read()
|
||||||
return False
|
view.GetTextCtrl().SetValue(data)
|
||||||
self.SetFilename(filename, True)
|
|
||||||
self.Modify(False)
|
|
||||||
self.UpdateAllViews()
|
|
||||||
self._savedYet = True
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
def IsModified(self):
|
def IsModified(self):
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
if view and view.GetTextCtrl():
|
if view and view.GetTextCtrl():
|
||||||
return wx.lib.docview.Document.IsModified(self) or view.GetTextCtrl().IsModified()
|
return view.GetTextCtrl().IsModified()
|
||||||
else:
|
return False
|
||||||
return wx.lib.docview.Document.IsModified(self)
|
|
||||||
|
|
||||||
|
|
||||||
def Modify(self, mod):
|
def Modify(self, modify):
|
||||||
|
if self._inModify:
|
||||||
|
return
|
||||||
|
self._inModify = True
|
||||||
|
|
||||||
view = self.GetFirstView()
|
view = self.GetFirstView()
|
||||||
wx.lib.docview.Document.Modify(self, mod)
|
if not modify and view and view.GetTextCtrl():
|
||||||
if not mod and view and view.GetTextCtrl():
|
|
||||||
view.GetTextCtrl().DiscardEdits()
|
view.GetTextCtrl().DiscardEdits()
|
||||||
|
|
||||||
|
wx.lib.docview.Document.Modify(self, modify) # this must called be after the DiscardEdits call above.
|
||||||
|
|
||||||
|
self._inModify = False
|
||||||
|
|
||||||
|
|
||||||
class TextView(wx.lib.docview.View):
|
class TextView(wx.lib.docview.View):
|
||||||
|
|
||||||
@@ -75,6 +75,7 @@ class TextView(wx.lib.docview.View):
|
|||||||
sizer = wx.BoxSizer()
|
sizer = wx.BoxSizer()
|
||||||
font, color = self._GetFontAndColorFromConfig()
|
font, color = self._GetFontAndColorFromConfig()
|
||||||
self._textCtrl = self._BuildTextCtrl(frame, font, color = color)
|
self._textCtrl = self._BuildTextCtrl(frame, font, color = color)
|
||||||
|
self._textCtrl.Bind(wx.EVT_TEXT, self.OnModify)
|
||||||
sizer.Add(self._textCtrl, 1, wx.EXPAND, 0)
|
sizer.Add(self._textCtrl, 1, wx.EXPAND, 0)
|
||||||
frame.SetSizer(sizer)
|
frame.SetSizer(sizer)
|
||||||
frame.Layout()
|
frame.Layout()
|
||||||
@@ -83,6 +84,10 @@ class TextView(wx.lib.docview.View):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def OnModify(self, event):
|
||||||
|
self.GetDocument().Modify(True)
|
||||||
|
|
||||||
|
|
||||||
def _BuildTextCtrl(self, parent, font, color = wx.BLACK, value = "", selection = [0, 0]):
|
def _BuildTextCtrl(self, parent, font, color = wx.BLACK, value = "", selection = [0, 0]):
|
||||||
if self._wordWrap:
|
if self._wordWrap:
|
||||||
wordWrapStyle = wx.TE_WORDWRAP
|
wordWrapStyle = wx.TE_WORDWRAP
|
||||||
@@ -131,6 +136,9 @@ class TextView(wx.lib.docview.View):
|
|||||||
|
|
||||||
|
|
||||||
def OnUpdate(self, sender = None, hint = None):
|
def OnUpdate(self, sender = None, hint = None):
|
||||||
|
if wx.lib.docview.View.OnUpdate(self, sender, hint):
|
||||||
|
return
|
||||||
|
|
||||||
if hint == "Word Wrap":
|
if hint == "Word Wrap":
|
||||||
self.SetWordWrap(wx.ConfigBase_Get().ReadInt("TextEditorWordWrap", True))
|
self.SetWordWrap(wx.ConfigBase_Get().ReadInt("TextEditorWordWrap", True))
|
||||||
elif hint == "Font":
|
elif hint == "Font":
|
||||||
|
@@ -6,7 +6,7 @@
|
|||||||
#
|
#
|
||||||
# Created: 5/15/03
|
# Created: 5/15/03
|
||||||
# CVS-ID: $Id$
|
# CVS-ID: $Id$
|
||||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
|
# Copyright: (c) 2003-2006 ActiveGrid, Inc. (Port of wxWindows classes by Julian Smart et al)
|
||||||
# License: wxWindows license
|
# License: wxWindows license
|
||||||
#----------------------------------------------------------------------------
|
#----------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -214,8 +214,10 @@ class Document(wx.EvtHandler):
|
|||||||
false otherwise. You may need to override this if your document view
|
false otherwise. You may need to override this if your document view
|
||||||
maintains its own record of being modified (for example if using
|
maintains its own record of being modified (for example if using
|
||||||
xTextWindow to view and edit the document).
|
xTextWindow to view and edit the document).
|
||||||
|
This method has been extended to notify its views that the dirty flag has changed.
|
||||||
"""
|
"""
|
||||||
self._documentModified = modify
|
self._documentModified = modify
|
||||||
|
self.UpdateAllViews(hint=("modify", self, self._documentModified))
|
||||||
|
|
||||||
|
|
||||||
def SetDocumentModificationDate(self):
|
def SetDocumentModificationDate(self):
|
||||||
@@ -236,6 +238,16 @@ class Document(wx.EvtHandler):
|
|||||||
return self._documentModificationDate
|
return self._documentModificationDate
|
||||||
|
|
||||||
|
|
||||||
|
def IsDocumentModificationDateCorrect(self):
|
||||||
|
"""
|
||||||
|
Returns False if the file has been modified outside of the application.
|
||||||
|
This method has been added to wxPython and is not in wxWindows.
|
||||||
|
"""
|
||||||
|
if not os.path.exists(self.GetFilename()): # document must be in memory only and can't be out of date
|
||||||
|
return True
|
||||||
|
return self._documentModificationDate == os.path.getmtime(self.GetFilename())
|
||||||
|
|
||||||
|
|
||||||
def GetViews(self):
|
def GetViews(self):
|
||||||
"""
|
"""
|
||||||
Returns the list whose elements are the views on the document.
|
Returns the list whose elements are the views on the document.
|
||||||
@@ -271,6 +283,7 @@ class Document(wx.EvtHandler):
|
|||||||
Destructor. Removes itself from the document manager.
|
Destructor. Removes itself from the document manager.
|
||||||
"""
|
"""
|
||||||
self.DeleteContents()
|
self.DeleteContents()
|
||||||
|
self._documentModificationDate = None
|
||||||
if self.GetDocumentManager():
|
if self.GetDocumentManager():
|
||||||
self.GetDocumentManager().RemoveDocument(self)
|
self.GetDocumentManager().RemoveDocument(self)
|
||||||
wx.EvtHandler.Destroy(self)
|
wx.EvtHandler.Destroy(self)
|
||||||
@@ -364,7 +377,7 @@ class Document(wx.EvtHandler):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
""" check for file modification outside of application """
|
""" check for file modification outside of application """
|
||||||
if os.path.exists(self.GetFilename()) and os.path.getmtime(self.GetFilename()) != self.GetDocumentModificationDate():
|
if not self.IsDocumentModificationDateCorrect():
|
||||||
msgTitle = wx.GetApp().GetAppName()
|
msgTitle = wx.GetApp().GetAppName()
|
||||||
if not msgTitle:
|
if not msgTitle:
|
||||||
msgTitle = _("Application")
|
msgTitle = _("Application")
|
||||||
@@ -485,9 +498,9 @@ class Document(wx.EvtHandler):
|
|||||||
self.GetDocumentWindow())
|
self.GetDocumentWindow())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
self.SetDocumentModificationDate()
|
||||||
self.SetFilename(filename, True)
|
self.SetFilename(filename, True)
|
||||||
self.Modify(False)
|
self.Modify(False)
|
||||||
self.SetDocumentModificationDate()
|
|
||||||
self.SetDocumentSaved(True)
|
self.SetDocumentSaved(True)
|
||||||
#if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
|
#if wx.Platform == '__WXMAC__': # Not yet implemented in wxPython
|
||||||
# wx.FileName(file).MacSetDefaultTypeAndCreator()
|
# wx.FileName(file).MacSetDefaultTypeAndCreator()
|
||||||
@@ -529,9 +542,9 @@ class Document(wx.EvtHandler):
|
|||||||
self.GetDocumentWindow())
|
self.GetDocumentWindow())
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
self.SetDocumentModificationDate()
|
||||||
self.SetFilename(filename, True)
|
self.SetFilename(filename, True)
|
||||||
self.Modify(False)
|
self.Modify(False)
|
||||||
self.SetDocumentModificationDate()
|
|
||||||
self.SetDocumentSaved(True)
|
self.SetDocumentSaved(True)
|
||||||
self.UpdateAllViews()
|
self.UpdateAllViews()
|
||||||
return True
|
return True
|
||||||
@@ -614,7 +627,7 @@ class Document(wx.EvtHandler):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
""" check for file modification outside of application """
|
""" check for file modification outside of application """
|
||||||
if os.path.exists(self.GetFilename()) and os.path.getmtime(self.GetFilename()) != self.GetDocumentModificationDate():
|
if not self.IsDocumentModificationDateCorrect():
|
||||||
msgTitle = wx.GetApp().GetAppName()
|
msgTitle = wx.GetApp().GetAppName()
|
||||||
if not msgTitle:
|
if not msgTitle:
|
||||||
msgTitle = _("Warning")
|
msgTitle = _("Warning")
|
||||||
@@ -844,8 +857,14 @@ class View(wx.EvtHandler):
|
|||||||
unused but may in future contain application-specific information for
|
unused but may in future contain application-specific information for
|
||||||
making updating more efficient.
|
making updating more efficient.
|
||||||
"""
|
"""
|
||||||
pass
|
if hint:
|
||||||
|
if hint[0] == "modify": # if dirty flag changed, update the view's displayed title
|
||||||
|
frame = self.GetFrame()
|
||||||
|
if frame and hasattr(frame, "OnTitleIsModified"):
|
||||||
|
frame.OnTitleIsModified()
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
def OnChangeFilename(self):
|
def OnChangeFilename(self):
|
||||||
"""
|
"""
|
||||||
@@ -916,11 +935,11 @@ class View(wx.EvtHandler):
|
|||||||
Call this from your view frame's OnActivate member to tell the
|
Call this from your view frame's OnActivate member to tell the
|
||||||
framework which view is currently active. If your windowing system
|
framework which view is currently active. If your windowing system
|
||||||
doesn't call OnActivate, you may need to call this function from
|
doesn't call OnActivate, you may need to call this function from
|
||||||
any place where you know the view must be active, and
|
OnMenuCommand or any place where you know the view must be active, and
|
||||||
the framework will need to get the current view.
|
the framework will need to get the current view.
|
||||||
|
|
||||||
The prepackaged view frame wxDocChildFrame calls wxView.Activate from
|
The prepackaged view frame wxDocChildFrame calls wxView.Activate from
|
||||||
its OnActivate member.
|
its OnActivate member and from its OnMenuCommand member.
|
||||||
"""
|
"""
|
||||||
if self.GetDocument() and self.GetDocumentManager():
|
if self.GetDocument() and self.GetDocumentManager():
|
||||||
self.OnActivateView(activate, self, self.GetDocumentManager().GetCurrentView())
|
self.OnActivateView(activate, self, self.GetDocumentManager().GetCurrentView())
|
||||||
@@ -1865,7 +1884,7 @@ class DocManager(wx.EvtHandler):
|
|||||||
for document in self._docs:
|
for document in self._docs:
|
||||||
if document.GetFilename() and os.path.normcase(document.GetFilename()) == os.path.normcase(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 not document.IsDocumentModificationDateCorrect():
|
||||||
msgTitle = wx.GetApp().GetAppName()
|
msgTitle = wx.GetApp().GetAppName()
|
||||||
if not msgTitle:
|
if not msgTitle:
|
||||||
msgTitle = _("Warning")
|
msgTitle = _("Warning")
|
||||||
@@ -2148,7 +2167,7 @@ class DocManager(wx.EvtHandler):
|
|||||||
if len(descr) > 0:
|
if len(descr) > 0:
|
||||||
descr = descr + _('|')
|
descr = descr + _('|')
|
||||||
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
|
||||||
descr = _("All (*.*)|*.*|%s") % descr # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
descr = _("All|*.*|%s") % descr # spacing is important, make sure there is no space after the "|", it causes a bug on wx_gtk
|
||||||
else:
|
else:
|
||||||
descr = _("*.*")
|
descr = _("*.*")
|
||||||
|
|
||||||
@@ -2791,6 +2810,7 @@ class DocMDIChildFrame(wx.MDIChildFrame):
|
|||||||
self._childView.Activate(event.GetActive())
|
self._childView.Activate(event.GetActive())
|
||||||
self._activated = 0
|
self._activated = 0
|
||||||
|
|
||||||
|
|
||||||
def OnCloseWindow(self, event):
|
def OnCloseWindow(self, event):
|
||||||
"""
|
"""
|
||||||
Closes and deletes the current view and document.
|
Closes and deletes the current view and document.
|
||||||
@@ -2846,6 +2866,28 @@ class DocMDIChildFrame(wx.MDIChildFrame):
|
|||||||
self._childView = view
|
self._childView = view
|
||||||
|
|
||||||
|
|
||||||
|
def OnTitleIsModified(self):
|
||||||
|
"""
|
||||||
|
Add/remove to the frame's title an indication that the document is dirty.
|
||||||
|
If the document is dirty, an '*' is appended to the title
|
||||||
|
This method has been added to wxPython and is not in wxWindows.
|
||||||
|
"""
|
||||||
|
title = self.GetTitle()
|
||||||
|
if title:
|
||||||
|
if self.GetDocument().IsModified():
|
||||||
|
if title.endswith("*"):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
title = title + "*"
|
||||||
|
self.SetTitle(title)
|
||||||
|
else:
|
||||||
|
if title.endswith("*"):
|
||||||
|
title = title[:-1]
|
||||||
|
self.SetTitle(title)
|
||||||
|
else:
|
||||||
|
return
|
||||||
|
|
||||||
|
|
||||||
class DocPrintout(wx.Printout):
|
class DocPrintout(wx.Printout):
|
||||||
"""
|
"""
|
||||||
DocPrintout is a default Printout that prints the first page of a document
|
DocPrintout is a default Printout that prints the first page of a document
|
||||||
@@ -2892,15 +2934,6 @@ class DocPrintout(wx.Printout):
|
|||||||
return pageNum == 1
|
return pageNum == 1
|
||||||
|
|
||||||
|
|
||||||
def OnBeginDocument(self, startPage, endPage):
|
|
||||||
"""
|
|
||||||
Not quite sure why this was overridden, but it was in wxWindows! :)
|
|
||||||
"""
|
|
||||||
if not wx.Printout.OnBeginDocument(self, startPage, endPage):
|
|
||||||
return False
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
def GetPageInfo(self):
|
def GetPageInfo(self):
|
||||||
"""
|
"""
|
||||||
Indicates that the DocPrintout only has a single page.
|
Indicates that the DocPrintout only has a single page.
|
||||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user