This commit was manufactured by cvs2svn to create tag 'wxPy_2_6_4_0'.
git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/tags/wxPy_2_6_4_0@44989 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
0
wxPython/samples/ide/activegrid/model/__init__.py
Normal file
0
wxPython/samples/ide/activegrid/model/__init__.py
Normal file
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,43 +5,53 @@
|
||||
# Author: Morgan Hua
|
||||
#
|
||||
# Created: 3/22/05
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||
# CVS-ID: $Id$
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import wx
|
||||
from IDE import ACTIVEGRID_BASE_IDE, getSplashBitmap
|
||||
import os.path
|
||||
from IDE import ACTIVEGRID_BASE_IDE, getSplashBitmap, getIDESplashBitmap
|
||||
import activegrid.util.sysutils as sysutilslib
|
||||
_ = wx.GetTranslation
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Package License Data for AboutDialog
|
||||
# Package, License, URL
|
||||
# If no information is available, put a None as a place holder.
|
||||
#
|
||||
# NO GPL Allowed. Only LGPL, BSD, and Public Domain Based Licenses!
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
licenseData = [
|
||||
("ActiveGrid", "ASL 2.0", "http://apache.org/licenses/LICENSE-2.0"),
|
||||
("Python 2.3", "Python Software Foundation License", "http://www.python.org/2.3/license.html"),
|
||||
("wxPython 2.5", "wxWidgets 2 - LGPL", "http://wxwidgets.org/newlicen.htm"),
|
||||
("wxWidgets", "wxWindows Library License 3", "http://www.wxwidgets.org/manuals/2.5.4/wx_wxlicense.html"),
|
||||
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
|
||||
licenseData = [ # add licenses for base IDE features
|
||||
("ActiveGrid", "Apache License, Version 2.0", "http://apache.org/licenses/LICENSE-2.0"),
|
||||
("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"),
|
||||
("wxWidgets", "wxWindows Library License 3", "http://www.wxwidgets.org/manuals/2.6.1/wx_wxlicense.html"),
|
||||
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
|
||||
("process.py", "See file", "http://starship.python.net/~tmick/"),
|
||||
("pysvn", "Apache License", "http://pysvn.tigris.org/"),
|
||||
("pysvn", "Apache License, Version 2.0", "http://pysvn.tigris.org/"),
|
||||
]
|
||||
|
||||
if not ACTIVEGRID_BASE_IDE: # add licenses for database connections only if not the base IDE
|
||||
if not ACTIVEGRID_BASE_IDE: # add licenses for non-base IDE features such as database connections
|
||||
licenseData += [
|
||||
("pydb2", "LGPL", "http://sourceforge.net/projects/pydb2"),
|
||||
("pydb2", "LGPL", "http://sourceforge.net/projects/pydb2"),
|
||||
("pysqlite", "Python License (CNRI)", "http://sourceforge.net/projects/pysqlite"),
|
||||
("mysql-python", "GPL, Python License (CNRI), Zope Public License", "http://sourceforge.net/projects/mysql-python"),
|
||||
("cx_Oracle", "Computronix", "http://http://www.computronix.com/download/License(cxOracle).txt"),
|
||||
("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"),
|
||||
("SQLite", "Public Domain", "http://www.sqlite.org/copyright.html"),
|
||||
("PyGreSQL", "BSD", "http://www.pygresql.org"),
|
||||
("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/"),
|
||||
("python-ldap", "Python Software Foundation License", "http://python-ldap.sourceforge.net"),
|
||||
("Sarissa", "LGPL", "http://sourceforge.net/projects/sarissa/"),
|
||||
("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__':
|
||||
if wx.Platform == '__WXMSW__': # add Windows only licenses
|
||||
licenseData += [("pywin32", "Python Software Foundation License", "http://sourceforge.net/projects/pywin32/")]
|
||||
|
||||
class AboutDialog(wx.Dialog):
|
||||
@@ -56,10 +66,25 @@ class AboutDialog(wx.Dialog):
|
||||
|
||||
aboutPage = wx.Panel(nb, -1)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
splash_bmp = getSplashBitmap()
|
||||
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
splash_bmp = getSplashBitmap()
|
||||
else:
|
||||
splash_bmp = getIDESplashBitmap()
|
||||
|
||||
# find version number from
|
||||
versionFilepath = os.path.join(sysutilslib.mainModuleDir, "version.txt")
|
||||
if os.path.exists(versionFilepath):
|
||||
versionfile = open(versionFilepath, 'r')
|
||||
versionLines = versionfile.readlines()
|
||||
versionfile.close()
|
||||
version = "".join(versionLines)
|
||||
else:
|
||||
version = _("Version Unknown - %s not found" % versionFilepath)
|
||||
|
||||
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(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\nVersion 0.7 Early Access\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
|
||||
sizer.Add(wx.StaticText(aboutPage, -1, 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)
|
||||
aboutPage.SetSizer(sizer)
|
||||
nb.AddPage(aboutPage, _("Copyright"))
|
||||
@@ -67,36 +92,40 @@ class AboutDialog(wx.Dialog):
|
||||
licensePage = wx.Panel(nb, -1)
|
||||
grid = wx.grid.Grid(licensePage, -1)
|
||||
grid.CreateGrid(len(licenseData), 2)
|
||||
|
||||
|
||||
dc = wx.ClientDC(grid)
|
||||
dc.SetFont(grid.GetLabelFont())
|
||||
grid.SetColLabelValue(0, _("License"))
|
||||
grid.SetColLabelValue(1, _("URL"))
|
||||
w, maxHeight = dc.GetTextExtent(_("License"))
|
||||
w, h = dc.GetTextExtent(_("URL"))
|
||||
if h > maxHeight:
|
||||
maxHeight = h
|
||||
w, h1 = dc.GetTextExtent(_("License"))
|
||||
w, h2 = dc.GetTextExtent(_("URL"))
|
||||
maxHeight = max(h1, h2)
|
||||
grid.SetColLabelSize(maxHeight + 6) # add a 6 pixel margin
|
||||
|
||||
maxW = 0
|
||||
for row, data in enumerate(licenseData):
|
||||
package = data[0]
|
||||
license = data[1]
|
||||
url = data[2]
|
||||
if package:
|
||||
grid.SetRowLabelValue(row, package)
|
||||
w, h = dc.GetTextExtent(package)
|
||||
if w > maxW:
|
||||
maxW = w
|
||||
if license:
|
||||
grid.SetCellValue(row, 0, license)
|
||||
if url:
|
||||
grid.SetCellValue(row, 1, url)
|
||||
|
||||
|
||||
grid.EnableEditing(False)
|
||||
grid.EnableDragGridSize(False)
|
||||
grid.EnableDragColSize(False)
|
||||
grid.EnableDragRowSize(False)
|
||||
grid.SetRowLabelAlignment(wx.ALIGN_LEFT, wx.ALIGN_CENTRE)
|
||||
grid.SetLabelBackgroundColour(wx.WHITE)
|
||||
grid.AutoSizeColumn(0, 100)
|
||||
grid.AutoSizeColumn(1, 100)
|
||||
grid.AutoSizeColumn(0)
|
||||
grid.AutoSizeColumn(1)
|
||||
grid.SetRowLabelSize(maxW + 10)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(grid, 1, wx.EXPAND|wx.ALL, 10)
|
||||
licensePage.SetSizer(sizer)
|
||||
@@ -104,17 +133,18 @@ class AboutDialog(wx.Dialog):
|
||||
|
||||
creditsPage = wx.Panel(nb, -1)
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(wx.StaticText(creditsPage, -1, _("ActiveGrid Development Team:\n\nLawrence Bruhmuller\nEric Chu\nMatt Fryer\nJoel Hare\nMorgan Hua\nAlan Mullendore\nJeff Norton\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)
|
||||
nb.AddPage(creditsPage, _("Credits"))
|
||||
|
||||
|
||||
sizer = wx.BoxSizer(wx.VERTICAL)
|
||||
sizer.Add(nb, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
btn = wx.Button(self, wx.ID_OK)
|
||||
sizer.Add(btn, 0, wx.ALIGN_CENTRE|wx.ALL, 5)
|
||||
|
||||
self.SetSizer(sizer)
|
||||
self.SetAutoLayout(True)
|
||||
sizer.Fit(self)
|
||||
|
||||
self.Layout()
|
||||
self.Fit()
|
||||
grid.ForceRefresh() # wxBug: Get rid of unnecessary scrollbars
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,20 @@ SHAPE_BRUSH = wx.Brush("WHEAT", wx.SOLID)
|
||||
LINE_BRUSH = wx.BLACK_BRUSH
|
||||
INACTIVE_SELECT_BRUSH = wx.Brush("LIGHT BLUE", wx.SOLID)
|
||||
|
||||
NORMALFONT = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
|
||||
SLANTFONT = wx.Font(NORMALFONT.GetPointSize(), NORMALFONT.GetFamily(), wx.SLANT, NORMALFONT.GetWeight())
|
||||
BOLDFONT = wx.Font(NORMALFONT.GetPointSize(), NORMALFONT.GetFamily(), NORMALFONT.GetStyle(), wx.BOLD)
|
||||
|
||||
DEFAULT_BACKGROUND_COLOR = wx.Colour(0xEE, 0xEE, 0xEE)
|
||||
HEADER_BRUSH = wx.Brush(wx.Colour(0xDB, 0xEB, 0xFF), wx.SOLID)
|
||||
BODY_BRUSH = wx.Brush(wx.WHITE, wx.SOLID)
|
||||
|
||||
|
||||
PARKING_VERTICAL = 1
|
||||
PARKING_HORIZONTAL = 2
|
||||
PARKING_OFFSET = 30 # space between shapes
|
||||
|
||||
FORCE_REDRAW_METHOD = "ForceRedraw"
|
||||
|
||||
def GetRawModel(model):
|
||||
if hasattr(model, "GetRawModel"):
|
||||
@@ -32,6 +46,27 @@ def GetRawModel(model):
|
||||
return rawModel
|
||||
|
||||
|
||||
def GetLabel(model):
|
||||
model = GetRawModel(model)
|
||||
if hasattr(model, "__xmlname__"):
|
||||
label = model.__xmlname__
|
||||
try:
|
||||
if (len(label) > 0):
|
||||
label = label[0].upper() + label[1:]
|
||||
if (hasattr(model, "complexType")):
|
||||
label += ': %s/%s' % (model.complexType.name, model.name)
|
||||
else:
|
||||
if model.name:
|
||||
label += ': %s' % model.name
|
||||
elif model.ref:
|
||||
label += ': %s' % model.ref
|
||||
except AttributeError:
|
||||
pass
|
||||
else:
|
||||
label = str(model)
|
||||
return label
|
||||
|
||||
|
||||
class CanvasView(wx.lib.docview.View):
|
||||
|
||||
|
||||
@@ -40,9 +75,10 @@ class CanvasView(wx.lib.docview.View):
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def __init__(self, brush = SHAPE_BRUSH):
|
||||
def __init__(self, brush=SHAPE_BRUSH, background=DEFAULT_BACKGROUND_COLOR):
|
||||
wx.lib.docview.View.__init__(self)
|
||||
self._brush = brush
|
||||
self._backgroundColor = background
|
||||
self._canvas = None
|
||||
self._pt1 = None
|
||||
self._pt2 = None
|
||||
@@ -50,6 +86,7 @@ class CanvasView(wx.lib.docview.View):
|
||||
self._propShape = None
|
||||
self._maxWidth = 2000
|
||||
self._maxHeight = 16000
|
||||
self._valetParking = False
|
||||
|
||||
|
||||
def OnDraw(self, dc):
|
||||
@@ -68,6 +105,7 @@ class CanvasView(wx.lib.docview.View):
|
||||
frame.SetSizer(sizer)
|
||||
frame.Layout()
|
||||
self.Activate()
|
||||
wx.EVT_RIGHT_DOWN(self._canvas, self.OnRightClick)
|
||||
return True
|
||||
|
||||
|
||||
@@ -145,12 +183,30 @@ class CanvasView(wx.lib.docview.View):
|
||||
|
||||
self._canvas.SetScrollbars(20, 20, self._maxWidth / 20, self._maxHeight / 20)
|
||||
|
||||
self._canvas.SetBackgroundColour(wx.WHITE)
|
||||
self._canvas.SetBackgroundColour(self._backgroundColor)
|
||||
self._diagram = ogl.Diagram()
|
||||
self._canvas.SetDiagram(self._diagram)
|
||||
self._diagram.SetCanvas(self._canvas)
|
||||
self._canvas.SetFont(NORMALFONT)
|
||||
|
||||
|
||||
def OnClear(self, event):
|
||||
""" Deletion of selected objects from view.
|
||||
*Must Override*
|
||||
"""
|
||||
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):
|
||||
key = event.KeyCode()
|
||||
if key == wx.WXK_DELETE:
|
||||
@@ -159,7 +215,43 @@ class CanvasView(wx.lib.docview.View):
|
||||
event.Skip()
|
||||
|
||||
|
||||
def OnRightClick(self, event):
|
||||
""" force selection underneath right click position. """
|
||||
self.Activate()
|
||||
self._canvas.SetFocus()
|
||||
|
||||
dc = wx.ClientDC(self._canvas)
|
||||
self._canvas.PrepareDC(dc)
|
||||
x, y = event.GetLogicalPosition(dc) # this takes into account scrollbar offset
|
||||
self.SetLastRightClick(x, y)
|
||||
shape = self._canvas.FindShape(x, y)[0]
|
||||
|
||||
model = None
|
||||
if not shape:
|
||||
self.SetSelection(None)
|
||||
self.SetPropertyShape(None)
|
||||
elif hasattr(shape, "GetModel"):
|
||||
self.BringToFront(shape)
|
||||
self.SetPropertyShape(shape)
|
||||
self.SetSelection(shape)
|
||||
shape.Select(True, dc)
|
||||
model = shape.GetModel()
|
||||
elif shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape): # ComplexTypeHeader for ComplexTypeShape
|
||||
self.BringToFront(shape)
|
||||
self.SetPropertyShape(shape.GetParent())
|
||||
self.SetSelection(shape.GetParent())
|
||||
shape.GetParent().Select(True, dc)
|
||||
model = shape.GetParent().GetModel()
|
||||
|
||||
self.SetPropertyModel(model)
|
||||
|
||||
return (shape, model)
|
||||
|
||||
|
||||
def OnLeftClick(self, event):
|
||||
self.Activate()
|
||||
self._canvas.SetFocus()
|
||||
|
||||
self.EraseRubberBand()
|
||||
|
||||
dc = wx.ClientDC(self._canvas)
|
||||
@@ -181,12 +273,15 @@ class CanvasView(wx.lib.docview.View):
|
||||
pass
|
||||
else:
|
||||
# click on empty part of canvas, deselect everything
|
||||
forceRedrawShapes = []
|
||||
needRefresh = False
|
||||
for shape in self._diagram.GetShapeList():
|
||||
if hasattr(shape, "GetModel"):
|
||||
if shape.Selected():
|
||||
needRefresh = True
|
||||
shape.Select(False, dc)
|
||||
if hasattr(shape, FORCE_REDRAW_METHOD):
|
||||
forceRedrawShapes.append(shape)
|
||||
if needRefresh:
|
||||
self._canvas.Redraw(dc)
|
||||
|
||||
@@ -195,7 +290,8 @@ class CanvasView(wx.lib.docview.View):
|
||||
if len(self.GetSelection()) == 0:
|
||||
self.SetPropertyShape(None)
|
||||
|
||||
|
||||
for shape in forceRedrawShapes:
|
||||
shape.ForceRedraw()
|
||||
|
||||
def OnLeftDoubleClick(self, event):
|
||||
propertyService = wx.GetApp().GetService(PropertyService.PropertyService)
|
||||
@@ -322,24 +418,42 @@ class CanvasView(wx.lib.docview.View):
|
||||
dc.EndDrawing()
|
||||
|
||||
|
||||
def FindParkingSpot(self, width, height):
|
||||
""" given a width and height, find a upper left corner where shape can be parked without overlapping other shape """
|
||||
offset = 30 # space between shapes
|
||||
x = offset
|
||||
y = offset
|
||||
maxX = 700 # max distance to the right where we'll place tables
|
||||
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):
|
||||
"""
|
||||
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
|
||||
noParkingSpot = True
|
||||
|
||||
while noParkingSpot:
|
||||
point = self.isSpotOccupied(x, y, width, height)
|
||||
if point:
|
||||
x = point[0] + offset
|
||||
if x > maxX:
|
||||
x = offset
|
||||
y = point[1] + offset
|
||||
if parking == PARKING_HORIZONTAL:
|
||||
x = point[0] + PARKING_OFFSET
|
||||
if x > max:
|
||||
x = PARKING_OFFSET
|
||||
y = point[1] + PARKING_OFFSET
|
||||
else: # parking == PARKING_VERTICAL:
|
||||
y = point[1] + PARKING_OFFSET
|
||||
if y > max:
|
||||
y = PARKING_OFFSET
|
||||
x = point[0] + PARKING_OFFSET
|
||||
else:
|
||||
noParkingSpot = False
|
||||
|
||||
if self._valetParking:
|
||||
self._valetPosition = (x, y)
|
||||
|
||||
return x, y
|
||||
|
||||
|
||||
@@ -351,7 +465,7 @@ class CanvasView(wx.lib.docview.View):
|
||||
y2 = y + height
|
||||
|
||||
for shape in self._diagram.GetShapeList():
|
||||
if isinstance(shape, ogl.RectangleShape) or isinstance(shape, ogl.EllipseShape):
|
||||
if isinstance(shape, ogl.RectangleShape) or isinstance(shape, ogl.EllipseShape) or isinstance(shape, ogl.PolygonShape):
|
||||
if shape.GetParent() and isinstance(shape.GetParent(), ogl.CompositeShape):
|
||||
# skip, part of a composite shape
|
||||
continue
|
||||
@@ -381,7 +495,7 @@ class CanvasView(wx.lib.docview.View):
|
||||
# Canvas methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def AddShape(self, shape, x = None, y = None, pen = None, brush = None, text = None, eventHandler = None):
|
||||
def AddShape(self, shape, x = None, y = None, pen = None, brush = None, text = None, eventHandler = None, shown=True):
|
||||
if isinstance(shape, ogl.CompositeShape):
|
||||
dc = wx.ClientDC(self._canvas)
|
||||
self._canvas.PrepareDC(dc)
|
||||
@@ -403,7 +517,7 @@ class CanvasView(wx.lib.docview.View):
|
||||
shape.AddText(text)
|
||||
shape.SetShadowMode(ogl.SHADOW_NONE)
|
||||
self._diagram.AddShape(shape)
|
||||
shape.Show(True)
|
||||
shape.Show(shown)
|
||||
if not eventHandler:
|
||||
eventHandler = EditorCanvasShapeEvtHandler(self)
|
||||
eventHandler.SetShape(shape)
|
||||
@@ -424,16 +538,22 @@ class CanvasView(wx.lib.docview.View):
|
||||
for line in shape.GetLines():
|
||||
shape.RemoveLine(line)
|
||||
self._diagram.RemoveShape(line)
|
||||
line.Delete()
|
||||
for obj in self._diagram.GetShapeList():
|
||||
for line in obj.GetLines():
|
||||
if self.IsShapeContained(shape, line.GetTo()) or self.IsShapeContained(shape, line.GetFrom()):
|
||||
obj.RemoveLine(line)
|
||||
self._diagram.RemoveShape(line)
|
||||
line.Delete()
|
||||
if line == shape:
|
||||
obj.RemoveLine(line)
|
||||
self._diagram.RemoveShape(line)
|
||||
line.Delete()
|
||||
|
||||
shape.RemoveFromCanvas(self._canvas)
|
||||
if self._canvas:
|
||||
shape.RemoveFromCanvas(self._canvas)
|
||||
self._diagram.RemoveShape(shape)
|
||||
shape.Delete()
|
||||
|
||||
|
||||
def IsShapeContained(self, parent, shape):
|
||||
@@ -448,29 +568,22 @@ class CanvasView(wx.lib.docview.View):
|
||||
def UpdateShape(self, model):
|
||||
for shape in self._diagram.GetShapeList():
|
||||
if hasattr(shape, "GetModel") and shape.GetModel() == model:
|
||||
oldw, oldh = shape.GetBoundingBoxMax()
|
||||
oldx = shape.GetX()
|
||||
oldy = shape.GetY()
|
||||
|
||||
x, y, w, h = model.getEditorBounds()
|
||||
newX = x + w / 2
|
||||
newY = y + h / 2
|
||||
changed = False
|
||||
if isinstance(shape, ogl.CompositeShape):
|
||||
if shape.GetX() != newX or shape.GetY() != newY:
|
||||
dc = wx.ClientDC(self._canvas)
|
||||
self._canvas.PrepareDC(dc)
|
||||
shape.SetSize(w, h, True) # wxBug: SetSize must be before Move because links won't go to the right place
|
||||
shape.Move(dc, newX, newY) # wxBug: Move must be before SetSize because links won't go to the right place
|
||||
changed = True
|
||||
else:
|
||||
oldw, oldh = shape.GetBoundingBoxMax()
|
||||
oldx = shape.GetX()
|
||||
oldy = shape.GetY()
|
||||
if oldw != w or oldh != h or oldx != newX or oldy != newY:
|
||||
shape.SetSize(w, h)
|
||||
shape.SetX(newX)
|
||||
shape.SetY(newY)
|
||||
changed = True
|
||||
if changed:
|
||||
|
||||
if oldw != w or oldh != h or oldx != newX or oldy != newY:
|
||||
dc = wx.ClientDC(self._canvas)
|
||||
self._canvas.PrepareDC(dc)
|
||||
shape.SetSize(w, h, True) # wxBug: SetSize must be before Move because links won't go to the right place
|
||||
shape.Move(dc, newX, newY) # wxBug: Move must be after SetSize because links won't go to the right place
|
||||
shape.ResetControlPoints()
|
||||
self._canvas.Refresh()
|
||||
|
||||
break
|
||||
|
||||
|
||||
@@ -481,6 +594,10 @@ class CanvasView(wx.lib.docview.View):
|
||||
return None
|
||||
|
||||
|
||||
def GetShapeCount(self):
|
||||
return self._diagram.GetCount()
|
||||
|
||||
|
||||
def GetSelection(self):
|
||||
return filter(lambda shape: shape.Selected(), self._diagram.GetShapeList())
|
||||
|
||||
@@ -526,7 +643,10 @@ class CanvasView(wx.lib.docview.View):
|
||||
|
||||
|
||||
def ScrollVisible(self, shape):
|
||||
xUnit, yUnit = shape._canvas.GetScrollPixelsPerUnit()
|
||||
if not shape:
|
||||
return
|
||||
|
||||
xUnit, yUnit = self._canvas.GetScrollPixelsPerUnit()
|
||||
scrollX, scrollY = self._canvas.GetViewStart() # in scroll units
|
||||
scrollW, scrollH = self._canvas.GetSize() # in pixels
|
||||
w, h = shape.GetBoundingBoxMax() # in pixels
|
||||
@@ -564,7 +684,10 @@ class CanvasView(wx.lib.docview.View):
|
||||
|
||||
# erase old selection if it still exists
|
||||
if self._propShape and self._propShape in self._diagram.GetShapeList():
|
||||
self._propShape.SetBrush(self._brush)
|
||||
if hasattr(self._propShape, "DEFAULT_BRUSH"):
|
||||
self._propShape.SetBrush(self._propShape.DEFAULT_BRUSH)
|
||||
else:
|
||||
self._propShape.SetBrush(self._brush)
|
||||
if (self._propShape._textColourName in ["BLACK", "WHITE"]): # Would use GetTextColour() but it is broken
|
||||
self._propShape.SetTextColour("BLACK", 0)
|
||||
self._propShape.Draw(dc)
|
||||
@@ -608,6 +731,9 @@ class CanvasView(wx.lib.docview.View):
|
||||
self._propShape.SetTextColour("WHITE", 0)
|
||||
self._propShape.Draw(dc)
|
||||
|
||||
if hasattr(self._propShape, FORCE_REDRAW_METHOD):
|
||||
self._propShape.ForceRedraw()
|
||||
|
||||
dc.EndDrawing()
|
||||
|
||||
|
||||
@@ -667,9 +793,10 @@ class EditorCanvasShapeEvtHandler(ogl.ShapeEvtHandler):
|
||||
if shape:
|
||||
model = shape.GetModel()
|
||||
|
||||
self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
|
||||
self._view.SetPropertyShape(shape)
|
||||
self._view.SetPropertyModel(model)
|
||||
if model:
|
||||
self._view.SetSelection(model, keys == self.SHIFT_KEY or keys == self.CONTROL_KEY)
|
||||
self._view.SetPropertyShape(shape)
|
||||
self._view.SetPropertyModel(model)
|
||||
|
||||
|
||||
def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
|
||||
@@ -686,7 +813,7 @@ class EditorCanvasShapeEvtHandler(ogl.ShapeEvtHandler):
|
||||
|
||||
def OnMovePre(self, dc, x, y, oldX, oldY, display):
|
||||
""" Prevent objects from being dragged outside of viewable area """
|
||||
if (x > self._view._maxWidth) or (y > self._view._maxHeight):
|
||||
if (x < 0) or (y < 0) or (x > self._view._maxWidth) or (y > self._view._maxHeight):
|
||||
return False
|
||||
|
||||
return ogl.ShapeEvtHandler.OnMovePre(self, dc, x, y, oldX, oldY, display)
|
||||
|
||||
@@ -19,8 +19,8 @@ import os
|
||||
import re
|
||||
import string
|
||||
import sys
|
||||
import DebuggerService
|
||||
import MarkerService
|
||||
from UICommon import CaseInsensitiveCompare
|
||||
_ = wx.GetTranslation
|
||||
if wx.Platform == '__WXMSW__':
|
||||
_WINDOWS = True
|
||||
@@ -119,16 +119,27 @@ class CodeView(STCTextEditor.TextView):
|
||||
return False
|
||||
id = event.GetId()
|
||||
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
|
||||
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
|
||||
elif (id == EXPAND_TOP_ID
|
||||
or id == COLLAPSE_TOP_ID
|
||||
or id == EXPAND_ALL_ID
|
||||
or id == COLLAPSE_ALL_ID
|
||||
or id == AUTO_COMPLETE_ID
|
||||
or id == COLLAPSE_ALL_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 == INDENT_LINES_ID
|
||||
or id == DEDENT_LINES_ID
|
||||
@@ -139,10 +150,12 @@ class CodeView(STCTextEditor.TextView):
|
||||
elif id == CHECK_CODE_ID:
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif (id == SET_INDENT_WIDTH_ID
|
||||
or id == FOLDING_ID):
|
||||
elif id == SET_INDENT_WIDTH_ID:
|
||||
event.Enable(True)
|
||||
return True
|
||||
elif id == FOLDING_ID:
|
||||
event.Enable(self.GetCtrl().GetViewFolding())
|
||||
return True
|
||||
elif id == USE_TABS_ID:
|
||||
event.Enable(True)
|
||||
event.Check(self.GetCtrl().GetUseTabs())
|
||||
@@ -209,7 +222,7 @@ class CodeView(STCTextEditor.TextView):
|
||||
filename = document.GetFilename()
|
||||
if filename:
|
||||
rootItem = treeCtrl.AddRoot(os.path.basename(filename))
|
||||
treeCtrl.SetDoSelectCallback(rootItem, self, None)
|
||||
treeCtrl.SetDoSelectCallback(rootItem, self, (0,0))
|
||||
else:
|
||||
return True
|
||||
|
||||
@@ -231,11 +244,13 @@ class CodeView(STCTextEditor.TextView):
|
||||
if classLine:
|
||||
indent = classLine.start(0)
|
||||
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:
|
||||
defLine = defPat.search(line)
|
||||
if defLine:
|
||||
indent = defLine.start(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:
|
||||
parentItem = rootItem
|
||||
@@ -354,18 +369,6 @@ class CodeView(STCTextEditor.TextView):
|
||||
return ['Put', 'Editor Specific', 'Keywords', 'Here']
|
||||
|
||||
|
||||
def CaseInsensitiveCompare(self, s1, s2):
|
||||
""" GetAutoCompleteKeywordList() method used to show keywords in case insensitive order """
|
||||
s1L = s1.lower()
|
||||
s2L = s2.lower()
|
||||
if s1L == s2L:
|
||||
return 0
|
||||
elif s1L < s2L:
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
def GetAutoCompleteKeywordList(self, context, hint):
|
||||
""" Replace this method with Editor specific keywords """
|
||||
kw = self.GetAutoCompleteDefaultKeywords()
|
||||
@@ -380,7 +383,7 @@ class CodeView(STCTextEditor.TextView):
|
||||
else:
|
||||
replaceLen = 0
|
||||
|
||||
kw.sort(self.CaseInsensitiveCompare)
|
||||
kw.sort(CaseInsensitiveCompare)
|
||||
return " ".join(kw), replaceLen
|
||||
|
||||
|
||||
@@ -410,6 +413,7 @@ class CodeView(STCTextEditor.TextView):
|
||||
|
||||
def OnSetIndentWidth(self):
|
||||
dialog = wx.TextEntryDialog(self._GetParentFrame(), _("Enter new indent width (2-10):"), _("Set Indent Width"), "%i" % self.GetCtrl().GetIndent())
|
||||
dialog.CenterOnParent()
|
||||
if dialog.ShowModal() == wx.ID_OK:
|
||||
try:
|
||||
indent = int(dialog.GetValue())
|
||||
@@ -477,13 +481,17 @@ class CodeView(STCTextEditor.TextView):
|
||||
|
||||
|
||||
def OnUpdate(self, sender = None, hint = None):
|
||||
if wx.lib.docview.View.OnUpdate(self, sender, hint):
|
||||
return
|
||||
|
||||
if hint == "ViewStuff":
|
||||
self.GetCtrl().SetViewDefaults()
|
||||
elif hint == "Font":
|
||||
font, color = self.GetFontAndColorFromConfig()
|
||||
font, color = self.GetCtrl().GetFontAndColorFromConfig()
|
||||
self.GetCtrl().SetFont(font)
|
||||
self.GetCtrl().SetFontColor(color)
|
||||
else:
|
||||
import DebuggerService
|
||||
dbg_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
||||
if dbg_service:
|
||||
dbg_service.SetCurrentBreakpointMarkers(self)
|
||||
@@ -633,7 +641,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
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)
|
||||
|
||||
self.UsePopUp(False)
|
||||
@@ -645,7 +653,6 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
self.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL)
|
||||
self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
|
||||
self.SetMarginSensitive(2, True)
|
||||
self.SetMarginWidth(2, 12)
|
||||
|
||||
self.SetMarginSensitive(1, False)
|
||||
self.SetMarginMask(1, 0x4)
|
||||
@@ -667,7 +674,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
# Define the breakpoint marker
|
||||
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
|
||||
|
||||
wx.stc.EVT_STC_MARGINCLICK(self, self.GetId(), self.OnMarginClick)
|
||||
@@ -703,7 +710,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
item = wx.MenuItem(menu, TOGGLEBREAKPOINT_ID, _("Toggle Breakpoint"))
|
||||
menu.AppendItem(item)
|
||||
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.AppendSeparator()
|
||||
|
||||
@@ -725,6 +732,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
|
||||
def OnPopToggleBP(self, event):
|
||||
""" Toggle break point on right click line, not current line """
|
||||
import DebuggerService
|
||||
wx.GetApp().GetService(DebuggerService.DebuggerService).OnToggleBreakpoint(event, line=self._rightClickLine)
|
||||
|
||||
|
||||
@@ -869,6 +877,7 @@ class CodeCtrl(STCTextEditor.TextCtrl):
|
||||
|
||||
elif evt.GetMargin() == 0:
|
||||
#This is used to toggle breakpoints via the debugger service.
|
||||
import DebuggerService
|
||||
db_service = wx.GetApp().GetService(DebuggerService.DebuggerService)
|
||||
if db_service:
|
||||
db_service.OnToggleBreakpoint(evt, line=self.LineFromPosition(evt.GetPosition()))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -6,39 +6,35 @@
|
||||
#
|
||||
# Created: 5/23/05
|
||||
# CVS-ID: $ID:$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import wx
|
||||
import wx.lib.pydocview
|
||||
import MessageService
|
||||
import ProjectEditor
|
||||
import os
|
||||
import os.path
|
||||
import pickle
|
||||
|
||||
import activegrid.util.xmlutils as xmlutils
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
SPACE = 10
|
||||
HALF_SPACE = 5
|
||||
|
||||
|
||||
EXTENSIONS_CONFIG_STRING = "Extensions"
|
||||
|
||||
|
||||
|
||||
# TODO: Redo extensions menu on OK, or provide alert that it won't happen until restart
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class Extension:
|
||||
|
||||
|
||||
def __init__(self, menuItemName):
|
||||
|
||||
def __init__(self, menuItemName=None):
|
||||
self.menuItemName = menuItemName
|
||||
self.id = 0
|
||||
self.menuItemDesc = ''
|
||||
@@ -46,32 +42,51 @@ class Extension:
|
||||
self.commandPreArgs = ''
|
||||
self.commandPostArgs = ''
|
||||
self.fileExt = None
|
||||
self.opOnSelectedFile = True
|
||||
|
||||
|
||||
class ExtensionService(wx.lib.pydocview.DocService):
|
||||
|
||||
EXTENSIONS_KEY = "/AG_Extensions"
|
||||
|
||||
def __init__(self):
|
||||
self.LoadExtensions()
|
||||
|
||||
|
||||
def __getExtensionKeyName(extensionName):
|
||||
return "%s/%s" % (ExtensionService.EXTENSIONS_KEY, extensionName)
|
||||
|
||||
|
||||
__getExtensionKeyName = staticmethod(__getExtensionKeyName)
|
||||
|
||||
|
||||
def LoadExtensions(self):
|
||||
self._extensions = []
|
||||
|
||||
extensionNames = []
|
||||
config = wx.ConfigBase_Get()
|
||||
pickledExtensions = config.Read(EXTENSIONS_CONFIG_STRING)
|
||||
if pickledExtensions:
|
||||
try:
|
||||
self._extensions = pickle.loads(pickledExtensions.encode('ascii'))
|
||||
except:
|
||||
tp, val, tb = sys.exc_info()
|
||||
traceback.print_exception(tp,val,tb)
|
||||
self._extensions = []
|
||||
else:
|
||||
self._extensions = []
|
||||
|
||||
path = config.GetPath()
|
||||
try:
|
||||
config.SetPath(ExtensionService.EXTENSIONS_KEY)
|
||||
cont, value, index = config.GetFirstEntry()
|
||||
while cont:
|
||||
extensionNames.append(value)
|
||||
cont, value, index = config.GetNextEntry(index)
|
||||
finally:
|
||||
config.SetPath(path)
|
||||
|
||||
for extensionName in extensionNames:
|
||||
extensionData = config.Read(self.__getExtensionKeyName(extensionName))
|
||||
if extensionData:
|
||||
extension = xmlutils.unmarshal(extensionData.encode('utf-8'))
|
||||
self._extensions.append(extension)
|
||||
|
||||
|
||||
def SaveExtensions(self):
|
||||
config = wx.ConfigBase_Get()
|
||||
config.Write(EXTENSIONS_CONFIG_STRING, pickle.dumps(self._extensions))
|
||||
config.DeleteGroup(ExtensionService.EXTENSIONS_KEY)
|
||||
for extension in self._extensions:
|
||||
config.Write(self.__getExtensionKeyName(extension.menuItemName), xmlutils.marshal(extension))
|
||||
|
||||
|
||||
def GetExtensions(self):
|
||||
@@ -82,16 +97,20 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
self._extensions = extensions
|
||||
|
||||
|
||||
def CheckSumExtensions(self):
|
||||
return xmlutils.marshal(self._extensions)
|
||||
|
||||
|
||||
def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
|
||||
toolsMenuIndex = menuBar.FindMenu(_("&Tools"))
|
||||
if toolsMenuIndex > -1:
|
||||
toolsMenu = menuBar.GetMenu(toolsMenuIndex)
|
||||
else:
|
||||
toolsMenu = wx.Menu()
|
||||
|
||||
|
||||
if self._extensions:
|
||||
if toolsMenu.GetMenuItems():
|
||||
toolsMenu.AppendSeparator()
|
||||
toolsMenu.AppendSeparator()
|
||||
for ext in self._extensions:
|
||||
# Append a tool menu item for each extension
|
||||
ext.id = wx.NewId()
|
||||
@@ -100,8 +119,15 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
wx.EVT_UPDATE_UI(frame, ext.id, frame.ProcessUpdateUIEvent)
|
||||
|
||||
if toolsMenuIndex == -1:
|
||||
formatMenuIndex = menuBar.FindMenu(_("&Format"))
|
||||
menuBar.Insert(formatMenuIndex + 1, toolsMenu, _("&Tools"))
|
||||
index = menuBar.FindMenu(_("&Run"))
|
||||
if index == -1:
|
||||
index = menuBar.FindMenu(_("&Project"))
|
||||
if index == -1:
|
||||
index = menuBar.FindMenu(_("&Format"))
|
||||
if index == -1:
|
||||
index = menuBar.FindMenu(_("&View"))
|
||||
menuBar.Insert(index + 1, toolsMenu, _("&Tools"))
|
||||
|
||||
|
||||
def ProcessEvent(self, event):
|
||||
id = event.GetId()
|
||||
@@ -126,6 +152,14 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
if fileExt in doc.GetDocumentTemplate().GetFileFilter():
|
||||
event.Enable(True)
|
||||
return True
|
||||
if extension.opOnSelectedFile and isinstance(doc, ProjectEditor.ProjectDocument):
|
||||
filename = doc.GetFirstView().GetSelectedFile()
|
||||
if filename:
|
||||
template = wx.GetApp().GetDocumentManager().FindTemplateForPath(filename)
|
||||
for fileExt in extension.fileExt:
|
||||
if fileExt in template.GetFileFilter():
|
||||
event.Enable(True)
|
||||
return True
|
||||
event.Enable(False)
|
||||
return False
|
||||
return False
|
||||
@@ -136,7 +170,12 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
doc = wx.GetApp().GetDocumentManager().GetCurrentDocument()
|
||||
if not doc:
|
||||
return
|
||||
filename = doc.GetFilename()
|
||||
if extension.opOnSelectedFile and isinstance(doc, ProjectEditor.ProjectDocument):
|
||||
filename = doc.GetFirstView().GetSelectedFile()
|
||||
if not filename:
|
||||
filename = doc.GetFilename()
|
||||
else:
|
||||
filename = doc.GetFilename()
|
||||
ext = os.path.splitext(filename)[1]
|
||||
if not '*' in extension.fileExt:
|
||||
if not ext or ext[1:] not in extension.fileExt:
|
||||
@@ -148,7 +187,7 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
if extension.commandPostArgs:
|
||||
cmds.append(extension.commandPostArgs)
|
||||
os.spawnv(os.P_NOWAIT, extension.command, cmds)
|
||||
|
||||
|
||||
else:
|
||||
cmd = extension.command
|
||||
if extension.commandPreArgs:
|
||||
@@ -163,107 +202,115 @@ class ExtensionService(wx.lib.pydocview.DocService):
|
||||
view.AddLines(line)
|
||||
view.GetControl().EnsureCaretVisible()
|
||||
f.close()
|
||||
|
||||
|
||||
|
||||
class ExtensionOptionsPanel(wx.Panel):
|
||||
|
||||
|
||||
def __init__(self, parent, id):
|
||||
wx.Panel.__init__(self, parent, id)
|
||||
|
||||
extOptionsPanelBorderSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
extOptionsPanelSizer = wx.FlexGridSizer(cols=2, hgap=SPACE, vgap=HALF_SPACE)
|
||||
|
||||
|
||||
extOptionsPanelBorderSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
|
||||
extOptionsPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
extCtrlSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
extCtrlSizer.Add(wx.StaticText(self, -1, _("Extensions:")), 0)
|
||||
self._extListBox = wx.ListBox(self, -1, size=(-1,185), style=wx.LB_SINGLE)
|
||||
extCtrlSizer.Add(wx.StaticText(self, -1, _("External Tools:")), 0, wx.BOTTOM, HALF_SPACE)
|
||||
self._extListBox = wx.ListBox(self, -1, style=wx.LB_SINGLE)
|
||||
self.Bind(wx.EVT_LISTBOX, self.OnListBoxSelect, self._extListBox)
|
||||
extCtrlSizer.Add(self._extListBox, 1, wx.TOP | wx.BOTTOM | wx.EXPAND, SPACE)
|
||||
buttonSizer = wx.GridSizer(rows=1, hgap=10, vgap=5)
|
||||
extCtrlSizer.Add(self._extListBox, 1, wx.BOTTOM | wx.EXPAND, SPACE)
|
||||
buttonSizer = wx.GridSizer(cols=2, vgap=HALF_SPACE, hgap=HALF_SPACE)
|
||||
self._moveUpButton = wx.Button(self, -1, _("Move Up"))
|
||||
self.Bind(wx.EVT_BUTTON, self.OnMoveUp, self._moveUpButton)
|
||||
buttonSizer.Add(self._moveUpButton, 0)
|
||||
buttonSizer.Add(self._moveUpButton, 1, wx.EXPAND)
|
||||
self._moveDownButton = wx.Button(self, -1, _("Move Down"))
|
||||
self.Bind(wx.EVT_BUTTON, self.OnMoveDown, self._moveDownButton)
|
||||
buttonSizer.Add(self._moveDownButton, 0)
|
||||
extCtrlSizer.Add(buttonSizer, 0, wx.ALIGN_CENTER | wx.BOTTOM, HALF_SPACE)
|
||||
buttonSizer = wx.GridSizer(rows=1, hgap=10, vgap=5)
|
||||
self._addButton = wx.Button(self, -1, _("Add"))
|
||||
buttonSizer.Add(self._moveDownButton, 1, wx.EXPAND)
|
||||
self._addButton = wx.Button(self, wx.ID_ADD)
|
||||
self.Bind(wx.EVT_BUTTON, self.OnAdd, self._addButton)
|
||||
buttonSizer.Add(self._addButton, 0)
|
||||
self._deleteButton = wx.Button(self, wx.ID_DELETE)
|
||||
buttonSizer.Add(self._addButton, 1, wx.EXPAND)
|
||||
self._deleteButton = wx.Button(self, wx.ID_DELETE, label=_("Delete")) # get rid of accelerator for letter d in "&Delete"
|
||||
self.Bind(wx.EVT_BUTTON, self.OnDelete, self._deleteButton)
|
||||
buttonSizer.Add(self._deleteButton, 0)
|
||||
buttonSizer.Add(self._deleteButton, 1, wx.EXPAND)
|
||||
extCtrlSizer.Add(buttonSizer, 0, wx.ALIGN_CENTER)
|
||||
extOptionsPanelSizer.Add(extCtrlSizer, 0)
|
||||
extOptionsPanelSizer.Add(extCtrlSizer, 0, wx.EXPAND)
|
||||
|
||||
self._extDetailPanel = wx.Panel(self)
|
||||
staticBox = wx.StaticBox(self._extDetailPanel, label=_("Selected Extension"))
|
||||
staticBoxSizer = wx.StaticBoxSizer(staticBox)
|
||||
self._extDetailPanel.SetSizer(staticBoxSizer)
|
||||
extDetailSizer = wx.FlexGridSizer(cols=1, hgap=5, vgap=3)
|
||||
staticBoxSizer.AddSizer(extDetailSizer, 0, wx.ALL, 5)
|
||||
staticBox = wx.StaticBox(self, label=_("Selected External Tool"))
|
||||
staticBoxSizer = wx.StaticBoxSizer(staticBox, wx.VERTICAL)
|
||||
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")))
|
||||
extDetailSizer = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
|
||||
extDetailSizer.AddGrowableCol(1,1)
|
||||
|
||||
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))
|
||||
extDetailSizer.Add(self._menuItemNameTextCtrl, 1, wx.EXPAND)
|
||||
self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
|
||||
extDetailSizer.Add(self._menuItemNameTextCtrl, 0, wx.EXPAND)
|
||||
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))
|
||||
extDetailSizer.Add(self._menuItemDescTextCtrl, 1, wx.EXPAND)
|
||||
extDetailSizer.Add(self._menuItemDescTextCtrl, 0, wx.EXPAND)
|
||||
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Path:")))
|
||||
self._commandTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Path:")), flag=wx.ALIGN_CENTER_VERTICAL)
|
||||
self._commandTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
|
||||
findFileButton = wx.Button(self._extDetailPanel, -1, _("Browse..."))
|
||||
def OnBrowseButton(event):
|
||||
fileDlg = wx.FileDialog(self, _("Choose an Executable:"), style=wx.OPEN | wx.HIDE_READONLY)
|
||||
fileDlg = wx.FileDialog(self, _("Choose an Executable:"), style=wx.OPEN|wx.FILE_MUST_EXIST|wx.HIDE_READONLY|wx.CHANGE_DIR)
|
||||
path = self._commandTextCtrl.GetValue()
|
||||
if path:
|
||||
fileDlg.SetPath(path)
|
||||
# fileDlg.CenterOnParent() # wxBug: caused crash with wx.FileDialog
|
||||
if fileDlg.ShowModal() == wx.ID_OK:
|
||||
self._commandTextCtrl.SetValue(fileDlg.GetPath())
|
||||
self._commandTextCtrl.SetInsertionPointEnd()
|
||||
self._commandTextCtrl.SetToolTipString(fileDlg.GetPath())
|
||||
fileDlg.Destroy()
|
||||
wx.EVT_BUTTON(findFileButton, -1, OnBrowseButton)
|
||||
hsizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
hsizer.Add(self._commandTextCtrl, 1, wx.EXPAND)
|
||||
hsizer.Add(findFileButton, 0, wx.LEFT, HALF_SPACE)
|
||||
extDetailSizer.Add(hsizer, 0)
|
||||
extDetailSizer.Add(hsizer, 0, wx.EXPAND)
|
||||
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Arguments:")))
|
||||
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))
|
||||
extDetailSizer.Add(self._commandPreArgsTextCtrl, 1, wx.EXPAND)
|
||||
extDetailSizer.Add(self._commandPreArgsTextCtrl, 0, wx.EXPAND)
|
||||
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Arguments:")))
|
||||
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))
|
||||
extDetailSizer.Add(self._commandPostArgsTextCtrl, 1, wx.EXPAND)
|
||||
extDetailSizer.Add(self._commandPostArgsTextCtrl, 0, wx.EXPAND)
|
||||
|
||||
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions (Comma Separated):")))
|
||||
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.SetToolTipString(_("""For example: "txt, text" or "*" for all files"""))
|
||||
extDetailSizer.Add(self._fileExtTextCtrl, 1, wx.EXPAND)
|
||||
self._fileExtTextCtrl.SetToolTipString(_("""For example: "txt, text" (comma separated) or "*" for all files"""))
|
||||
extDetailSizer.Add(self._fileExtTextCtrl, 0, wx.EXPAND)
|
||||
|
||||
extOptionsPanelSizer.Add(self._extDetailPanel, 0)
|
||||
self._selFileCtrl = wx.CheckBox(self._extDetailPanel, -1, _("Operate on Selected File"))
|
||||
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."))
|
||||
|
||||
extOptionsPanelBorderSizer.Add(extOptionsPanelSizer, 0, wx.ALL | wx.EXPAND, SPACE)
|
||||
self._extDetailPanel.SetSizer(extDetailSizer)
|
||||
staticBoxSizer.Add(self._extDetailPanel, 1, wx.ALL|wx.EXPAND, SPACE)
|
||||
|
||||
extOptionsPanelSizer.Add(staticBoxSizer, 1, wx.LEFT|wx.EXPAND, SPACE)
|
||||
|
||||
extOptionsPanelBorderSizer.Add(extOptionsPanelSizer, 1, wx.ALL|wx.EXPAND, SPACE)
|
||||
self.SetSizer(extOptionsPanelBorderSizer)
|
||||
self.Layout()
|
||||
parent.AddPage(self, _("Extensions"))
|
||||
|
||||
|
||||
if self.PopulateItems():
|
||||
self._extListBox.SetSelection(0)
|
||||
self.OnListBoxSelect(None)
|
||||
self.OnListBoxSelect()
|
||||
|
||||
self.Layout()
|
||||
|
||||
parent.AddPage(self, _("External Tools"))
|
||||
|
||||
|
||||
def OnOK(self, optionsDialog):
|
||||
self.SaveCurrentItem()
|
||||
extensionsService = wx.GetApp().GetService(ExtensionService)
|
||||
oldExtensions = extensionsService.GetExtensions()
|
||||
extensionsService.SetExtensions(self._extensions)
|
||||
extensionsService.SaveExtensions()
|
||||
if oldExtensions.__repr__() != self._extensions.__repr__():
|
||||
if extensionsService.CheckSumExtensions() != self._oldExtensions: # see PopulateItems() note about self._oldExtensions
|
||||
msgTitle = wx.GetApp().GetAppName()
|
||||
if not msgTitle:
|
||||
msgTitle = _("Document Options")
|
||||
@@ -271,22 +318,23 @@ class ExtensionOptionsPanel(wx.Panel):
|
||||
msgTitle,
|
||||
wx.OK | wx.ICON_INFORMATION,
|
||||
self.GetParent())
|
||||
|
||||
|
||||
|
||||
def PopulateItems(self):
|
||||
extensionsService = wx.GetApp().GetService(ExtensionService)
|
||||
import copy
|
||||
self._extensions = copy.deepcopy(extensionsService.GetExtensions())
|
||||
self._oldExtensions = extensionsService.CheckSumExtensions() # wxBug: need to make a copy now since the deepcopy reorders fields, so we must compare the prestine copy with the modified copy
|
||||
for extension in self._extensions:
|
||||
self._extListBox.Append(extension.menuItemName, extension)
|
||||
self._currentItem = None
|
||||
self._currentItemIndex = -1
|
||||
return len(self._extensions)
|
||||
|
||||
|
||||
def OnListBoxSelect(self, event):
|
||||
|
||||
def OnListBoxSelect(self, event=None):
|
||||
self.SaveCurrentItem()
|
||||
if not self._extListBox.GetSelections():
|
||||
if self._extListBox.GetSelection() == wx.NOT_FOUND:
|
||||
self._currentItemIndex = -1
|
||||
self._currentItem = None
|
||||
self._deleteButton.Enable(False)
|
||||
@@ -316,55 +364,64 @@ class ExtensionOptionsPanel(wx.Panel):
|
||||
extension.fileExt = None
|
||||
else:
|
||||
extension.fileExt = fileExt.split(',')
|
||||
|
||||
extension.opOnSelectedFile = self._selFileCtrl.GetValue()
|
||||
|
||||
|
||||
def LoadItem(self, extension):
|
||||
if extension:
|
||||
self._menuItemDescTextCtrl.SetValue(extension.menuItemDesc or '')
|
||||
self._commandTextCtrl.SetValue(extension.command or '')
|
||||
self._commandTextCtrl.SetToolTipString(extension.command or '')
|
||||
self._commandPreArgsTextCtrl.SetValue(extension.commandPreArgs or '')
|
||||
self._commandPostArgsTextCtrl.SetValue(extension.commandPostArgs or '')
|
||||
if extension.fileExt:
|
||||
self._fileExtTextCtrl.SetValue(extension.fileExt.__repr__()[1:-1].replace("'","")) # Make the list a string, strip the brakcet on either side
|
||||
list = ""
|
||||
for ext in extension.fileExt:
|
||||
if list:
|
||||
list = list + ", "
|
||||
list = list + ext
|
||||
self._fileExtTextCtrl.SetValue(list)
|
||||
else:
|
||||
self._fileExtTextCtrl.SetValue('')
|
||||
self._selFileCtrl.SetValue(extension.opOnSelectedFile)
|
||||
self._menuItemNameTextCtrl.SetValue(extension.menuItemName or '') # Do the name last since it triggers the write event that updates the entire item
|
||||
self._extDetailPanel.Enable()
|
||||
else:
|
||||
self._menuItemNameTextCtrl.SetValue('')
|
||||
self._menuItemDescTextCtrl.SetValue('')
|
||||
self._commandTextCtrl.SetValue('')
|
||||
self._commandTextCtrl.SetToolTipString(_("Path to executable"))
|
||||
self._commandPreArgsTextCtrl.SetValue('')
|
||||
self._commandPostArgsTextCtrl.SetValue('')
|
||||
self._fileExtTextCtrl.SetValue('')
|
||||
self._selFileCtrl.SetValue(True)
|
||||
self._extDetailPanel.Enable(False)
|
||||
|
||||
|
||||
|
||||
|
||||
def OnAdd(self, event):
|
||||
self.SaveCurrentItem()
|
||||
extensionNames = map(lambda extension: extension.menuItemName, self._extensions)
|
||||
name = _("Untitled")
|
||||
count = 1
|
||||
while name in extensionNames:
|
||||
while self._extListBox.FindString(name) != wx.NOT_FOUND:
|
||||
count = count + 1
|
||||
name = _("Untitled %s") % count
|
||||
name = _("Untitled%s") % count
|
||||
extension = Extension(name)
|
||||
self._extensions.append(extension)
|
||||
self._extListBox.Append(extension.menuItemName, extension)
|
||||
self._extListBox.SetSelection(self._extListBox.GetCount() - 1)
|
||||
self.OnListBoxSelect(None)
|
||||
self._extListBox.SetStringSelection(extension.menuItemName)
|
||||
self.OnListBoxSelect()
|
||||
self._menuItemNameTextCtrl.SetFocus()
|
||||
self._menuItemNameTextCtrl.SetSelection(-1, -1)
|
||||
|
||||
|
||||
|
||||
def OnDelete(self, event):
|
||||
self._extListBox.Delete(self._currentItemIndex)
|
||||
self._extensions.remove(self._currentItem)
|
||||
self._extensions.remove(self._currentItem)
|
||||
self._currentItemIndex = min(self._currentItemIndex, self._extListBox.GetCount() - 1)
|
||||
if self._currentItemIndex > -1:
|
||||
self._extListBox.SetSelection(self._currentItemIndex)
|
||||
self._currentItem = None # Don't update it since it no longer exists
|
||||
self.OnListBoxSelect(None)
|
||||
self.OnListBoxSelect()
|
||||
|
||||
|
||||
def OnMoveUp(self, event):
|
||||
@@ -374,7 +431,7 @@ class ExtensionOptionsPanel(wx.Panel):
|
||||
self._extListBox.Insert(itemAboveString, self._currentItemIndex)
|
||||
self._extListBox.SetClientData(self._currentItemIndex, itemAboveData)
|
||||
self._currentItemIndex = self._currentItemIndex - 1
|
||||
self.OnListBoxSelect(None) # Reset buttons
|
||||
self.OnListBoxSelect() # Reset buttons
|
||||
|
||||
|
||||
def OnMoveDown(self, event):
|
||||
@@ -384,4 +441,4 @@ class ExtensionOptionsPanel(wx.Panel):
|
||||
self._extListBox.Insert(itemBelowString, self._currentItemIndex)
|
||||
self._extListBox.SetClientData(self._currentItemIndex, itemBelowData)
|
||||
self._currentItemIndex = self._currentItemIndex + 1
|
||||
self.OnListBoxSelect(None) # Reset buttons
|
||||
self.OnListBoxSelect() # Reset buttons
|
||||
|
||||
@@ -27,6 +27,7 @@ _ = wx.GetTranslation
|
||||
#----------------------------------------------------------------------------
|
||||
FILENAME_MARKER = _("Found in file: ")
|
||||
PROJECT_MARKER = _("Searching project: ")
|
||||
FILE_MARKER = _("Searching file: ")
|
||||
FIND_MATCHDIR = "FindMatchDir"
|
||||
FIND_MATCHDIRSUBFOLDERS = "FindMatchDirSubfolders"
|
||||
|
||||
@@ -39,6 +40,7 @@ class FindInDirService(FindService.FindService):
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
FINDFILE_ID = wx.NewId() # for bringing up Find in File dialog box
|
||||
FINDALL_ID = wx.NewId() # for bringing up Find All 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)
|
||||
|
||||
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_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_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):
|
||||
id = event.GetId()
|
||||
if id == FindInDirService.FINDALL_ID:
|
||||
if id == FindInDirService.FINDFILE_ID:
|
||||
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||
self.ShowFindAllDialog(view.GetCtrl().GetSelectedText())
|
||||
self.ShowFindInFileDialog(view.GetCtrl().GetSelectedText())
|
||||
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
|
||||
elif id == FindInDirService.FINDDIR_ID:
|
||||
view = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||
if hasattr(view, "GetCtrl") and view.GetCtrl() and hasattr(view.GetCtrl(), "GetSelectedText"):
|
||||
self.ShowFindDirDialog(view.GetCtrl().GetSelectedText())
|
||||
self.ShowFindInDirDialog(view.GetCtrl().GetSelectedText())
|
||||
else:
|
||||
self.ShowFindDirDialog()
|
||||
self.ShowFindInDirDialog()
|
||||
return True
|
||||
else:
|
||||
return FindService.FindService.ProcessEvent(self, event)
|
||||
@@ -77,10 +89,16 @@ class FindInDirService(FindService.FindService):
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
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)
|
||||
view = projectService.GetView()
|
||||
if view and view.GetDocument() and view.GetDocument().GetFiles():
|
||||
if projectService.GetFilesFromCurrentProject():
|
||||
event.Enable(True)
|
||||
else:
|
||||
event.Enable(False)
|
||||
@@ -91,10 +109,10 @@ class FindInDirService(FindService.FindService):
|
||||
return FindService.FindService.ProcessUpdateUIEvent(self, event)
|
||||
|
||||
|
||||
def ShowFindDirDialog(self, findString=None):
|
||||
def ShowFindInDirDialog(self, findString=None):
|
||||
config = wx.ConfigBase_Get()
|
||||
|
||||
frame = wx.Dialog(None, -1, _("Find in Directory"), size= (320,200))
|
||||
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Directory"), size= (320,200))
|
||||
borderSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
@@ -106,17 +124,17 @@ class FindInDirService(FindService.FindService):
|
||||
findDirButton = wx.Button(frame, -1, _("Browse..."))
|
||||
lineSizer.Add(findDirButton, 0, wx.LEFT, HALF_SPACE)
|
||||
contentSizer.Add(lineSizer, 0, wx.BOTTOM, SPACE)
|
||||
|
||||
|
||||
def OnBrowseButton(event):
|
||||
dlg = wx.DirDialog(frame, _("Choose a directory:"), style=wx.DD_DEFAULT_STYLE)
|
||||
dir = dirCtrl.GetValue()
|
||||
if len(dir):
|
||||
dlg.SetPath(dir)
|
||||
dlg.CenterOnParent()
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
dirCtrl.SetValue(dlg.GetPath())
|
||||
dirCtrl.SetToolTipString(dirCtrl.GetValue())
|
||||
dirCtrl.SetInsertionPointEnd()
|
||||
|
||||
dlg.Destroy()
|
||||
wx.EVT_BUTTON(findDirButton, -1, OnBrowseButton)
|
||||
|
||||
@@ -127,7 +145,10 @@ class FindInDirService(FindService.FindService):
|
||||
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)
|
||||
contentSizer.Add(lineSizer, flag=wx.EXPAND|wx.ALIGN_CENTER_VERTICAL|wx.BOTTOM, border=HALF_SPACE)
|
||||
|
||||
|
||||
if wx.Platform == "__WXMAC__":
|
||||
contentSizer.Add((-1, 10), 0, wx.EXPAND)
|
||||
|
||||
lineSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
lineSizer.Add(wx.StaticText(frame, -1, _("Find what:")), 0, wx.ALIGN_CENTER | wx.RIGHT, HALF_SPACE)
|
||||
if not findString:
|
||||
@@ -151,13 +172,17 @@ class FindInDirService(FindService.FindService):
|
||||
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
findBtn = wx.Button(frame, wx.ID_OK, _("Find"))
|
||||
findBtn.SetDefault()
|
||||
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(wx.Button(frame, wx.ID_CANCEL), 0)
|
||||
borderSizer.Add(buttonSizer, 0, wx.ALL, SPACE)
|
||||
|
||||
frame.SetSizer(borderSizer)
|
||||
frame.Fit()
|
||||
|
||||
frame.CenterOnParent()
|
||||
status = frame.ShowModal()
|
||||
|
||||
passedCheck = False
|
||||
@@ -168,6 +193,7 @@ class FindInDirService(FindService.FindService):
|
||||
_("Find in Directory"),
|
||||
wx.OK | wx.ICON_EXCLAMATION
|
||||
)
|
||||
dlg.CenterOnParent()
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
@@ -178,74 +204,44 @@ class FindInDirService(FindService.FindService):
|
||||
_("Find in Directory"),
|
||||
wx.OK | wx.ICON_EXCLAMATION
|
||||
)
|
||||
dlg.CenterOnParent()
|
||||
dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
|
||||
status = frame.ShowModal()
|
||||
else:
|
||||
passedCheck = True
|
||||
|
||||
|
||||
|
||||
# save user choice state for this and other Find Dialog Boxes
|
||||
dirString = dirCtrl.GetValue()
|
||||
searchSubfolders = subfolderCtrl.IsChecked()
|
||||
self.SaveFindDirConfig(dirString, searchSubfolders)
|
||||
|
||||
self.SaveFindInDirConfig(dirString, searchSubfolders)
|
||||
|
||||
findString = findCtrl.GetValue()
|
||||
matchCase = matchCaseCtrl.IsChecked()
|
||||
wholeWord = wholeWordCtrl.IsChecked()
|
||||
regExpr = regExprCtrl.IsChecked()
|
||||
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
||||
|
||||
|
||||
if status == wx.ID_OK:
|
||||
frame.Destroy()
|
||||
|
||||
frame.Destroy()
|
||||
if status == wx.ID_OK:
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
messageService.ShowWindow()
|
||||
|
||||
view = messageService.GetView()
|
||||
if view:
|
||||
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:
|
||||
docFile = file(dirString, 'r')
|
||||
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 + 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
|
||||
|
||||
try:
|
||||
view.ClearLines()
|
||||
view.SetCallback(self.OnJumpToFoundLine)
|
||||
|
||||
view.AddLines(_("Searching for '%s' in '%s'\n\n") % (findString, dirString))
|
||||
|
||||
if os.path.isfile(dirString):
|
||||
try:
|
||||
docFile = file(dirString, 'r')
|
||||
lineNum = 1
|
||||
needToDisplayFilename = True
|
||||
line = docFile.readline()
|
||||
@@ -253,7 +249,7 @@ class FindInDirService(FindService.FindService):
|
||||
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")
|
||||
view.AddLines(FILENAME_MARKER + dirString + "\n")
|
||||
needToDisplayFilename = False
|
||||
line = repr(lineNum).zfill(4) + ":" + line
|
||||
view.AddLines(line)
|
||||
@@ -261,31 +257,189 @@ class FindInDirService(FindService.FindService):
|
||||
lineNum += 1
|
||||
if not needToDisplayFilename:
|
||||
view.AddLines("\n")
|
||||
|
||||
view.AddLines(_("Search completed."))
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
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
|
||||
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
|
||||
else:
|
||||
frame.Destroy()
|
||||
return False
|
||||
|
||||
|
||||
def SaveFindDirConfig(self, dirString, searchSubfolders):
|
||||
|
||||
def SaveFindInDirConfig(self, dirString, searchSubfolders):
|
||||
""" Save search dir patterns and flags to registry.
|
||||
|
||||
|
||||
dirString = search directory
|
||||
searchSubfolders = Search subfolders
|
||||
"""
|
||||
config = wx.ConfigBase_Get()
|
||||
config.Write(FIND_MATCHDIR, dirString)
|
||||
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()
|
||||
|
||||
frame = wx.Dialog(None, -1, _("Find in Project"), size= (320,200))
|
||||
frame = wx.Dialog(wx.GetApp().GetTopWindow(), -1, _("Find in Project"), size= (320,200))
|
||||
borderSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
|
||||
contentSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
@@ -310,13 +464,17 @@ class FindInDirService(FindService.FindService):
|
||||
buttonSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
findBtn = wx.Button(frame, wx.ID_OK, _("Find"))
|
||||
findBtn.SetDefault()
|
||||
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(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
|
||||
@@ -326,100 +484,81 @@ class FindInDirService(FindService.FindService):
|
||||
regExpr = regExprCtrl.IsChecked()
|
||||
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
|
||||
|
||||
frame.Destroy()
|
||||
|
||||
if status == wx.ID_OK:
|
||||
frame.Destroy()
|
||||
|
||||
messageService = wx.GetApp().GetService(MessageService.MessageService)
|
||||
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)
|
||||
|
||||
self.DoFindIn(findString, matchCase, wholeWord, regExpr)
|
||||
return True
|
||||
else:
|
||||
frame.Destroy()
|
||||
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)
|
||||
lineText, pos = messageService.GetView().GetCurrLine()
|
||||
if lineText == "\n" or lineText.find(FILENAME_MARKER) != -1 or lineText.find(PROJECT_MARKER) != -1:
|
||||
if defLineNum == -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
|
||||
lineEnd = lineText.find(":")
|
||||
if lineEnd == -1:
|
||||
@@ -428,7 +567,10 @@ class FindInDirService(FindService.FindService):
|
||||
lineNum = int(lineText[0:lineEnd])
|
||||
|
||||
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)
|
||||
endPos = text.find("\n", startPos)
|
||||
@@ -442,8 +584,9 @@ class FindInDirService(FindService.FindService):
|
||||
break
|
||||
|
||||
if not foundView:
|
||||
doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT)
|
||||
foundView = doc.GetFirstView()
|
||||
doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE)
|
||||
if doc:
|
||||
foundView = doc.GetFirstView()
|
||||
|
||||
if foundView:
|
||||
foundView.GetFrame().SetFocus()
|
||||
@@ -456,5 +599,3 @@ class FindInDirService(FindService.FindService):
|
||||
# time, we don't see the selection, it is scrolled off screen
|
||||
foundView.SetSelection(startPos - 1 + len(lineText[lineEnd:].rstrip("\n")), startPos)
|
||||
wx.GetApp().GetService(OutlineService.OutlineService).LoadOutline(foundView, position=startPos)
|
||||
|
||||
|
||||
|
||||
@@ -121,6 +121,7 @@ class FindService(wx.lib.pydocview.DocService):
|
||||
self._findDialog = None
|
||||
|
||||
self._replaceDialog = FindReplaceDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Replace"), size=(320,200), findString=findString)
|
||||
self._replaceDialog.CenterOnParent()
|
||||
self._replaceDialog.Show(True)
|
||||
else:
|
||||
if self._replaceDialog != None:
|
||||
@@ -129,6 +130,7 @@ class FindService(wx.lib.pydocview.DocService):
|
||||
self._replaceDialog = None
|
||||
|
||||
self._findDialog = FindDialog(self.GetDocumentManager().FindSuitableParent(), -1, _("Find"), size=(320,200), findString=findString)
|
||||
self._findDialog.CenterOnParent()
|
||||
self._findDialog.Show(True)
|
||||
|
||||
|
||||
@@ -152,6 +154,7 @@ class FindService(wx.lib.pydocview.DocService):
|
||||
""" Display Goto Line Number dialog box """
|
||||
line = -1
|
||||
dialog = wx.TextEntryDialog(parent, _("Enter line number to go to:"), _("Go to Line"))
|
||||
dialog.CenterOnParent()
|
||||
if dialog.ShowModal() == wx.ID_OK:
|
||||
try:
|
||||
line = int(dialog.GetValue())
|
||||
@@ -356,7 +359,10 @@ class FindDialog(wx.Dialog):
|
||||
wx.EVT_BUTTON(self, FindService.FINDONE_ID, self.OnActionEvent)
|
||||
cancelBtn = wx.Button(self, wx.ID_CANCEL)
|
||||
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)
|
||||
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)
|
||||
replaceAllBtn = wx.Button(self, FindService.REPLACEALL_ID, _("Replace All"))
|
||||
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)
|
||||
buttonSizer.Add(replaceAllBtn, 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(replaceBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||
buttonSizer.Add(replaceAllBtn, 0, wx.BOTTOM, BTM_SPACE)
|
||||
buttonSizer.Add(cancelBtn, 0)
|
||||
gridSizer.Add(buttonSizer, pos=(0,2), span=(3,1))
|
||||
|
||||
@@ -495,12 +506,24 @@ def getFindData():
|
||||
return \
|
||||
'\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\x81IDAT8\x8d\xa5S\xc1\x16\xc0\x10\x0ckk\xff\xff\xc7d\x87\xad^U\r\
|
||||
\x93S\xe5U$\n\xb3$:\xc1e\x17(\x19Z\xb3$\x9e\xf1DD\xe2\x15\x01x\xea\x93\xef\
|
||||
\x04\x989\xea\x1b\xf2U\xc0\xda\xb4\xeb\x11\x1f:\xd8\xb5\xff8\x93\xd4\xa9\xae\
|
||||
@/S\xaaUwJ3\x85\xc0\x81\xee\xeb.q\x17C\x81\xd5XU \x1a\x93\xc6\x18\x8d\x90\
|
||||
\xe8}\x89\x00\x9a&\x9b_k\x94\x0c\xdf\xd78\xf8\x0b\x99Y\xb4\x08c\x9e\xfe\xc6\
|
||||
\xe3\x087\xf9\xd0D\x180\xf1#\x8e\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
\x00\x01\xb1IDAT8\x8d\xa5\x93=o\xd3P\x14\x86\x1f\xa7\x11\x95<\xdc\xc6\xecN+5\
|
||||
[\x86B\x99\xacLQ2Zr[\x89\xa1\xfd\x0b%\x95\x90\x00\xf1\x03\x80\x01\x98\x80\
|
||||
\x19G\xac\x0cm\xff@Y\xd9:\xd9Ck\x94\xd6\xddb\x94\x9b\x98\xc8\xd2e1C\xe5\x8b\
|
||||
\xdd\x14\x96\xbe\xdb=\x1f\xefy\xef\xf90\x8c\xda\x12wA\xbd\xfc\x18\xfa\x9fs\
|
||||
\x80\xf9|\x0e\xc0\x93\xc1\x81\x01\xf0\xe6\xf5\xab\x1c`:\x9d\x02\xf0\xf6\xdd{\
|
||||
\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():
|
||||
|
||||
@@ -76,7 +76,6 @@ class HtmlView(CodeEditor.CodeView):
|
||||
## sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
## sizer.Add(self._notebook, 1, wx.EXPAND)
|
||||
## frame.SetSizer(sizer)
|
||||
## frame.SetAutoLayout(True)
|
||||
##
|
||||
##
|
||||
## def OnNotebookChanging(self, event):
|
||||
@@ -120,7 +119,7 @@ class HtmlCtrl(CodeEditor.CodeCtrl):
|
||||
|
||||
|
||||
def SetViewDefaults(self):
|
||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = False, hasTabs = True)
|
||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = True, hasTabs = True, hasFolding=True)
|
||||
|
||||
|
||||
def GetFontAndColorFromConfig(self):
|
||||
@@ -157,7 +156,11 @@ class HtmlCtrl(CodeEditor.CodeCtrl):
|
||||
class HtmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||
|
||||
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):
|
||||
return getHTMLIcon()
|
||||
|
||||
|
||||
HTMLKEYWORDS = [
|
||||
@@ -199,16 +202,26 @@ def getHTMLData():
|
||||
return \
|
||||
'\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\xd3IDAT8\x8dcddbf\xa0\x040\xfe\xbf\xd1\xf3\x9f\x12\x03X\xfe}\xbeI\
|
||||
\x91\x0b\x98(\xd2=(\x0c`\x90W\xd2\xfc\x0f\x030\xb6\xbc\x92\xe6\x7f\x1d\x03\
|
||||
\xf3\xffN\xae\xde\xff\xff\xff\xff\xff\xdf\xc0\xd8\xfa\xff\xb5;O\xfe_\xbb\xf3\
|
||||
\xe4\xbf\x8e\x819\\\xcd\xd7_\xff\xff\xb3<|x\x9dAAY\x0b\xc5\xd0\x07w\xaf1\xd8\
|
||||
\xdbZ0\xec\xdd\xb5\x85\x81\x81\x81\x81\xe1\xdd\xf3\x1b\x0c\xab\x97\xcef\xe0`\
|
||||
ca\xf8\xfa\xf1\x19\\\x1d\x17+\x03\x03\x0b\x03\x03\x03Cqq>\xc3\xd3\x17o\x18V,\
|
||||
]\n\x97de\xe7\x81\xb3\x199\xc4\x18\x0e\x1d:\xc2 "*\xce\xf0\x8f\x11!\x8e\xd3\
|
||||
\x0b\xd8\xd8\xa7\x8e\xed\xf9\x7f\xf1\xcca\x14o\xca+i\xfeg\xfc{:\x95\xa2\x844\
|
||||
\xf0\xd1H\xb1\x01\x8c\x94\xe6F\x8a]\x00\x00YXz\xf0\x97\x87\'\x1a\x00\x00\x00\
|
||||
\x00IEND\xaeB`\x82'
|
||||
\x00\x01\xeeIDAT8\x8d}\x92?h\x13a\x18\xc6\x7fw=\x8d\xb4\x98\xa9-uP\x1a\xc9p$\
|
||||
\xdc`\xd0C\x8d\x8b)\xc5!Z\x11\xcc\xd0A\xd0*\xa8\x93\x8b8\x18\x11\x14RD\x07\t\
|
||||
N\xfe\xc1\x0cRAtS\x1c,\xcd\x10\x8c\xd8S\xba$9"\x11L\r\x96\x92\xa4.\xda#i\xa5\
|
||||
\xe7p^r\x97?\xbe\xd3\xf1~\xdf\xf3{\x9f\xe7\xbbW\xf8T(\x998j\xb9V\x07 _\xde\
|
||||
\x0e\xc0\xad\x19U\xe0?%\x01\x0c\xef\x19owv\xf9\xff\x01\x96\x88N\x850\x92)\
|
||||
\xf3\xde\x95s}!Rgcx\xdb\x9f\xd6\xf7Z\x13"\xa7\xcf\x00\xf4\x85t\x01\xea\x9b\
|
||||
\xedV\xfa\xd53\x00\xb2z\xb3\x7f\x84\xe5Z\xbd\x15\xc1)>x,\x04\x84,\xc0\xed\'\
|
||||
\xfd\x01\x9dB\xdb:\xc0\x8a\xb1E\xa3\xb2A8\xe0!\x9cL\x99\x00\x83;\x83D\x0fxQ\
|
||||
\x15Y\xe8\x19\xc1\x16\xff\xfe\xf2\x11V\xaf\xb1\x03\x90G\xe0\xf5\xe7\n\xd5\
|
||||
\xf58\xb0\xc4\xfc"\xbcL\xbf7c\x91#\x82h\xff\xae\xb5\xa6{\xf2\xdc\x9bi\x17\
|
||||
\xf8\xc6\x85\xaf\x9c\xbf:\x03\xc0\xe8P\x82\x8bwN\xa2\xe5\x8a\xa6\xe8\x9cjW\
|
||||
\xf1\xed\x1c`M\x05P\x94\xa7=\xf3\xcf\xa6&\x91\x8c_\x85\xd6c\xad\x18[\xae\x0b\
|
||||
\'\xf6\xef\xe6h4\r\xc0\xcf\x1f\xd0\xa8l0:\x94 \x937\x00\xc8\xe4\r\xeb\r:\x85\
|
||||
\xe3J\x0cy\xe41\xde\xb1\xbb\xd4\xbf\x97\x11\x07|\x00T\xcbz\x97\x0b\xb1\x97\
|
||||
\xb5jY\xa71\xf6\x0e-Wb65\xc9\x8b\xf9\xe7,\xaenZg\xebq\xd7])\xab7\xc9\xea\xee\
|
||||
\x8c\xdaB\x90\xf8u\xbde\x13n\xb6\x96I[\x08\xa2N$(~\x8b#\xfb\x12H\x1f\x1e^\
|
||||
\xeaZQ-W4\x0f\x9f\xaa\x01~\x8eO\r\x92\xc9\x1b\xc8>KlC\xbc{!\x1c\xf0\xf4\x8e\
|
||||
\xa0*\xb2\x90|\xb4\xcf\xe1\xa0-v\xd6\xe5\xb3\xd3\x08\x828\xd0\x8b\x01X\xcb\
|
||||
\xa2\xe5J\xdc\x7f\xe0o\xc3\'\n\x84\x03\x1eb\x91C\xa8\x8a,\xfc\x05\xf6\x0e\
|
||||
\xbfa\x1f\xe7Z\xfb\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getHTMLBitmap():
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
||||
#----------------------------------------------------------------------------
|
||||
import wx
|
||||
import wx.lib.docview
|
||||
import sys
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
@@ -36,10 +37,17 @@ class ImageView(wx.lib.docview.View):
|
||||
_("New Image File"),
|
||||
wx.OK | wx.ICON_EXCLAMATION)
|
||||
return False
|
||||
|
||||
try:
|
||||
self._bitmap = wx.Image(doc.GetFilename()).ConvertToBitmap()
|
||||
except:
|
||||
wx.MessageBox(_("Error loading '%s'. %s") % (doc.GetPrintableName(), sys.exc_value),
|
||||
_("Open Image File"),
|
||||
wx.OK | wx.ICON_EXCLAMATION)
|
||||
return False
|
||||
|
||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags)
|
||||
panel = wx.Panel(frame, -1)
|
||||
self._bitmap = wx.Image(doc.GetFilename()).ConvertToBitmap()
|
||||
self._ctrl = wx.StaticBitmap(panel, -1, self._bitmap, (0,0), (self._bitmap.GetWidth(), self._bitmap.GetHeight()))
|
||||
wx.EVT_LEFT_DOWN(self._ctrl, self.OnFocus)
|
||||
wx.EVT_LEFT_DCLICK(self._ctrl, self.OnFocus)
|
||||
@@ -85,15 +93,21 @@ import cStringIO
|
||||
|
||||
def getImageData():
|
||||
return \
|
||||
'\x89PNG\r\n\x1a\n\x00\x00\x00\rIHDR\x00\x00\x00\x10\x00\x00\x00\x10\x08\x02\
|
||||
\x00\x00\x00\x90\x91h6\x00\x00\x00\x03sBIT\x08\x08\x08\xdb\xe1O\xe0\x00\x00\
|
||||
\x00\x9aIDAT(\x91\x95\x92\xc1\r\xc50\x08C\xdd\xaa\xeb\xc12\xec\x90\x9b\x97!\
|
||||
\x0b\xb0\x03\x19\xe8\x1fR\xa9U\xf2\xd5\xb4>DH\xf8\t\x13\xb1E\x04\xbe\xe8\x00\
|
||||
@\xf2\x8d\xb5\xd6z\x02\x00\xccl\t\x98\x19\xc9}\xe9#y\x8f\xb0\x00H\xba\xc3\
|
||||
\xfd\x8a\xbd\x9e0\xe8xn\x9b\x99*q[r\x01`\xfa\x8f?\x91\x86-\x07\x8d\x00Iww\
|
||||
\xf7\xce\xcc\xf0>\xbb\x01\xa8j)e\x80G\xa0\xb7[k\x00J)\xfdU\xd5\xd6Z\x87O_D\
|
||||
\x88\x88\x88dff>\x17"r\x02y\xd33\xb3E\xc4\xcb\xe3\xeb\xda\xbe\x9e\xf7\x0f\
|
||||
\xa0B\x86\xd5X\x16\xcc\xea\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
'\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\x017IDAT8\x8dcddbfh\x9f\xb3\xf3?\x03\x0e\xf0\xfc\xc5[\x0c\xb1\xfb\x0f\
|
||||
\x9f10000l\x9e]\xc2\xc8\x02\x13,Ot\xc6e\x06V\xe0\x9f1\x81\x81\x81\x81\x81\
|
||||
\x81\x05Y\xf0\xdc\x0b\x88C\x1e|\xfc\xc2\xf0\xe3\xf7\x01\x86{\x1fO20000(\xf1\
|
||||
\x9b3p\xb0:\xc0\xd5\x05\xa9\xf3\xc2\xd9L\xe8&\xa3kf```8\xfah-\xc3\xb57\x9d\
|
||||
\x0c?~\x1f\xc0p\t\x86\x01\xe8\x9aa\xe0\xf9\xc7\'X\xc5Q\x0c\x90\xe1c\xc4P\xf4\
|
||||
\xfc\xe3\x13\x14\xb6\x02?\x0f~\x17(\xf1\x9bc\xd5\xcc\xc0\xc0\xc0 \xc9/\x03g_\
|
||||
\xbbx\ta\x00,\xaa\xc4\xb8\x18\x18\x8c%\xd5\xb0j\x86\x19n$\xc1\x88"\xc6\x82\
|
||||
\xaeH]X\x9d!T#\x96\xe1\xec\xf3[\x0cG\x1f\xade````\xb0\x96\x0bf0\x96TcP\x17V\
|
||||
\xc70\x14\xc3\x00\x98!\xea\xc2\xea\x0c\xb7\x1a\x1a\x19\x18\x18\x18\x18\xa2\
|
||||
\xd6,\xc0\xa6\x0c\xe1\x05J\x00\x0b\x03\x03"iz,\xd3A\x91|l\xf2\x8a\x81\x81\
|
||||
\x81\x81au\x87\x18\x8a\xf8\xd5\x8aW\xc4\xb9@VN\x0c\x9f4v\x03\x94\x05LH2\x04%\
|
||||
\x10wD]!h#N\x03`\xb9\x0b\x06`\t\x85\x10\x00\x00\xe4\x0ecz\x94h\xf0\x8e\x00\
|
||||
\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getImageBitmap():
|
||||
|
||||
@@ -36,16 +36,16 @@ class MarkerService(wx.lib.pydocview.DocService):
|
||||
|
||||
editMenu = menuBar.GetMenu(menuBar.FindMenu(_("&Edit")))
|
||||
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_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_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_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_UPDATE_UI(frame, MarkerService.MARKERPREV_ID, frame.ProcessUpdateUIEvent)
|
||||
|
||||
|
||||
@@ -14,6 +14,35 @@ import wx
|
||||
import Service
|
||||
import STCTextEditor
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Utility
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def ClearMessages():
|
||||
messageService = wx.GetApp().GetService(MessageService)
|
||||
view = messageService.GetView()
|
||||
if view:
|
||||
view.ClearLines()
|
||||
|
||||
|
||||
def ShowMessages(messages, clear=False):
|
||||
if ((messages != None) and (len(messages) > 0)):
|
||||
messageService = wx.GetApp().GetService(MessageService)
|
||||
messageService.ShowWindow(True)
|
||||
view = messageService.GetView()
|
||||
if view:
|
||||
if (clear):
|
||||
view.ClearLines()
|
||||
for message in messages:
|
||||
view.AddLines(message)
|
||||
view.AddLines("\n")
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
class MessageView(Service.ServiceView):
|
||||
""" Reusable Message View for any document.
|
||||
When an item is selected, the document view is called back (with DoSelectCallback) to highlight and display the corresponding item in the document view.
|
||||
@@ -36,52 +65,52 @@ class MessageView(Service.ServiceView):
|
||||
txtCtrl.SetFontColor(wx.BLACK)
|
||||
txtCtrl.StyleClearAll()
|
||||
txtCtrl.UpdateStyles()
|
||||
wx.EVT_SET_FOCUS(txtCtrl, self.OnFocus)
|
||||
|
||||
return txtCtrl
|
||||
|
||||
def GetDocument(self):
|
||||
return None
|
||||
|
||||
## def ProcessEvent(self, event):
|
||||
## stcControl = self.GetControl()
|
||||
## if not isinstance(stcControl, wx.stc.StyledTextCtrl):
|
||||
## return wx.lib.docview.View.ProcessUpdateUIEvent(self, event)
|
||||
## id = event.GetId()
|
||||
## if id == wx.ID_CUT:
|
||||
## stcControl.Cut()
|
||||
## return True
|
||||
## elif id == wx.ID_COPY:
|
||||
## stcControl.Copy()
|
||||
## return True
|
||||
## elif id == wx.ID_PASTE:
|
||||
## stcControl.Paste()
|
||||
## return True
|
||||
## elif id == wx.ID_CLEAR:
|
||||
## stcControl.Clear()
|
||||
## return True
|
||||
## elif id == wx.ID_SELECTALL:
|
||||
## stcControl.SetSelection(0, -1)
|
||||
## return True
|
||||
##
|
||||
##
|
||||
## def ProcessUpdateUIEvent(self, event):
|
||||
## stcControl = self.GetControl()
|
||||
## if not isinstance(stcControl, wx.stc.StyledTextCtrl):
|
||||
## return wx.lib.docview.View.ProcessUpdateUIEvent(self, event)
|
||||
## id = event.GetId()
|
||||
## if id == wx.ID_CUT:
|
||||
## event.Enable(stcControl.CanCut())
|
||||
## return True
|
||||
## elif id == wx.ID_COPY:
|
||||
## event.Enable(stcControl.CanCopy())
|
||||
## return True
|
||||
## elif id == wx.ID_PASTE:
|
||||
## event.Enable(stcControl.CanPaste())
|
||||
## return True
|
||||
## elif id == wx.ID_CLEAR:
|
||||
## event.Enable(True) # wxBug: should be stcControl.CanCut()) but disabling clear item means del key doesn't work in control as expected
|
||||
## return True
|
||||
## elif id == wx.ID_SELECTALL:
|
||||
## event.Enable(stcControl.GetTextLength() > 0)
|
||||
## return True
|
||||
def OnFocus(self, event):
|
||||
wx.GetApp().GetDocumentManager().ActivateView(self)
|
||||
event.Skip()
|
||||
|
||||
def ProcessEvent(self, event):
|
||||
stcControl = self.GetControl()
|
||||
if not isinstance(stcControl, wx.stc.StyledTextCtrl):
|
||||
return wx.lib.docview.View.ProcessEvent(self, event)
|
||||
id = event.GetId()
|
||||
if id == wx.ID_COPY:
|
||||
stcControl.Copy()
|
||||
return True
|
||||
elif id == wx.ID_CLEAR:
|
||||
stcControl.Clear()
|
||||
return True
|
||||
elif id == wx.ID_SELECTALL:
|
||||
stcControl.SetSelection(0, -1)
|
||||
return True
|
||||
|
||||
|
||||
def ProcessUpdateUIEvent(self, event):
|
||||
stcControl = self.GetControl()
|
||||
if not isinstance(stcControl, wx.stc.StyledTextCtrl):
|
||||
return wx.lib.docview.View.ProcessUpdateUIEvent(self, event)
|
||||
id = event.GetId()
|
||||
if id == wx.ID_CUT or id == wx.ID_PASTE:
|
||||
# I don't think cut or paste makes sense from a message/log window.
|
||||
event.Enable(False)
|
||||
return True
|
||||
elif id == wx.ID_COPY:
|
||||
hasSelection = (stcControl.GetSelectionStart() != stcControl.GetSelectionEnd())
|
||||
event.Enable(hasSelection)
|
||||
return True
|
||||
elif id == wx.ID_CLEAR:
|
||||
event.Enable(True) # wxBug: should be stcControl.CanCut()) but disabling clear item means del key doesn't work in control as expected
|
||||
return True
|
||||
elif id == wx.ID_SELECTALL:
|
||||
event.Enable(stcControl.GetTextLength() > 0)
|
||||
return True
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
@@ -95,6 +124,7 @@ class MessageView(Service.ServiceView):
|
||||
|
||||
|
||||
def AddLines(self, text):
|
||||
self.GetControl().SetCurrentPos(self.GetControl().GetTextLength())
|
||||
self.GetControl().SetReadOnly(False)
|
||||
self.GetControl().AddText(text)
|
||||
self.GetControl().SetReadOnly(True)
|
||||
@@ -139,5 +169,3 @@ class MessageService(Service.Service):
|
||||
|
||||
def _CreateView(self):
|
||||
return MessageView(self)
|
||||
|
||||
|
||||
|
||||
@@ -147,7 +147,11 @@ class OutlineView(Service.ServiceView):
|
||||
return
|
||||
|
||||
treeCtrl = self.GetControl()
|
||||
|
||||
parentItem = treeCtrl.GetRootItem()
|
||||
if not parentItem:
|
||||
return
|
||||
|
||||
if expanded[0] != treeCtrl.GetItemText(parentItem):
|
||||
return
|
||||
|
||||
@@ -157,8 +161,7 @@ class OutlineView(Service.ServiceView):
|
||||
treeCtrl.Expand(child)
|
||||
(child, cookie) = treeCtrl.GetNextChild(parentItem, cookie)
|
||||
|
||||
if parentItem:
|
||||
treeCtrl.EnsureVisible(parentItem)
|
||||
treeCtrl.EnsureVisible(parentItem)
|
||||
|
||||
|
||||
class OutlineTreeCtrl(wx.TreeCtrl):
|
||||
@@ -267,7 +270,7 @@ class OutlineTreeCtrl(wx.TreeCtrl):
|
||||
|
||||
if self.ItemHasChildren(item):
|
||||
child, cookie = self.GetFirstChild(item)
|
||||
while child and child.IsOk():
|
||||
while child.IsOk():
|
||||
self.FindDistanceToTreeItems(child, position, distances, items)
|
||||
child, cookie = self.GetNextChild(item, cookie)
|
||||
return False
|
||||
@@ -321,7 +324,7 @@ class OutlineService(Service.Service):
|
||||
|
||||
def __init__(self, serviceName, embeddedWindowLocation = wx.lib.pydocview.EMBEDDED_WINDOW_BOTTOM):
|
||||
Service.Service.__init__(self, serviceName, embeddedWindowLocation)
|
||||
self._validTemplates = []
|
||||
self._validViewTypes = []
|
||||
|
||||
|
||||
def _CreateView(self):
|
||||
@@ -493,9 +496,8 @@ class OutlineService(Service.Service):
|
||||
if self.GetView():
|
||||
currView = wx.GetApp().GetDocumentManager().GetCurrentView()
|
||||
if currView:
|
||||
for template in self._validTemplates:
|
||||
type = template.GetViewType()
|
||||
if isinstance(currView, type):
|
||||
for viewType in self._validViewTypes:
|
||||
if isinstance(currView, viewType):
|
||||
self.LoadOutline(currView)
|
||||
foundRegisteredView = True
|
||||
break
|
||||
@@ -506,14 +508,14 @@ class OutlineService(Service.Service):
|
||||
self._timer.Start(1000) # 1 second interval
|
||||
|
||||
|
||||
def AddTemplateForBackgroundHandler(self, template):
|
||||
self._validTemplates.append(template)
|
||||
def AddViewTypeForBackgroundHandler(self, viewType):
|
||||
self._validViewTypes.append(viewType)
|
||||
|
||||
|
||||
def GetTemplatesForBackgroundHandler(self):
|
||||
return self._validTemplates
|
||||
def GetViewTypesForBackgroundHandler(self):
|
||||
return self._validViewTypes
|
||||
|
||||
|
||||
def RemoveTemplateForBackgroundHandler(self, template):
|
||||
self._validTemplates.remove(template)
|
||||
def RemoveViewTypeForBackgroundHandler(self, viewType):
|
||||
self._validViewTypes.remove(viewType)
|
||||
|
||||
|
||||
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 os
|
||||
import re
|
||||
import FindInDirService
|
||||
import activegrid.util.appdirs as appdirs
|
||||
import activegrid.util.sysutils as sysutils
|
||||
_ = wx.GetTranslation
|
||||
|
||||
|
||||
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):
|
||||
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.SetKeyWords(4, string.join(PHPKEYWORDS))
|
||||
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):
|
||||
return True
|
||||
|
||||
|
||||
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):
|
||||
@@ -216,7 +254,113 @@ class PHPCtrl(CodeEditor.CodeCtrl):
|
||||
class PHPOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||
|
||||
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):
|
||||
return getPHPIcon()
|
||||
|
||||
|
||||
PHPKEYWORDS = [
|
||||
@@ -274,14 +418,22 @@ import cStringIO
|
||||
|
||||
def getPHPData():
|
||||
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{IDAT8\x8dclh8\xf0\x9f\x81\x02\xc0D\x89f\xaa\x18\xc0\x82M0<\\\x1c\
|
||||
\xce^\xb9\xf2%y.\xd0\xd4\xd4$\xde\x05\xf8l\x0c\x0f\x17\x87\x8baS\xc7x\xfd\
|
||||
\xfa\xf5\xff\xc8\xb6]\xbf~\x1d\xc3\x05\xf8\xc4\x98\x90\x05\xae_\xbf\x8e\xa1\
|
||||
\x88\x90\xd8 \x8aF\x98\x93`~\xc3\x05\xd0\xd5\xc1\r\x80\t\xc0B\xf7\xfa\xf5\
|
||||
\xeb(l\\\xeaP\xbc\x80\x1c\x85\xb8\xd8\xe8|&b\x9c\x8dn;2`\x1c\xf0\xdc\x08\x00\
|
||||
\x8e\xf2S\xed\xb0\xbe\xaa\xbc\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
\x00\x01GIDAT8\x8d\x8d\x931O\xc2@\x14\xc7\x7fW\xfa\x11\x1c\xe430\xb88\x18'\
|
||||
\x8c\x89\x0e\x0c\xc4\xd9\xdd\x85\xc9\xc5`\x82\x1b\t\x84\x98\x98\xe0\xa4_\x01\
|
||||
cd`t$\xb8h\xd0\xb8\xabD0\xd4\xd0\xb4%H $\xe7P\x0e{@\xa9\xff\xe4\r\xf7\xee~\
|
||||
\xff\xf7\xee^+\x1a\xcd\x8ed*\xab\xef\x02\xd0\xea\xda\x00\xb8\xce\x90\xb3\xa3\
|
||||
}\xc1*5\x9a\x1d\xf9\xf6#g\xf1\xea\xf9qyS\x97\xf5o)\x8f\xcfo\xa50b\x84\x85\
|
||||
\xb1\xca\xdc\x9b\xc0\xde\xe1\x01'\xa7U\x19v\xc6\xb4\xfa.\xeb\xc4\x01\x18L\
|
||||
\xfc\xa4;\xf2\xdb\x7f\xac\xdd\xd3s<\xda\x03+\xb4\x88\x19\x04\x15\x0c\xb0\x93\
|
||||
\xde\xc5\x9b\x80=\x86\xf6\xc5U\xa8\x81v\x05\x05\xab\xf6\xedq(\xf7\xd7A\xabk\
|
||||
\xb36\xd2\x93A\xd8\x1aF\x18\xcc\x83\xb0\x08\x7f\xbc\xb7\xc2\r\\g8\x03\x97\
|
||||
\xc1Q2{\x8e\xa7\x81/\xd7\xb5\x85C\xc9\xc46\xc9\x84>\xcaR!-`\xfa\x88\xab\xe0b\
|
||||
>\xb5\xb4\xb2\xfa6\xcc\xf6\xa7\xc5f\x00V\xc0\xc3\xf3\x17w\x95\xa7YN\xad\x83\
|
||||
\xfbP\x95\x06@un\xce\xd9\\\x8d\xad\x8d\xf8\xbf\xd6F\xa5\x9c\x11\x95rF\xfbaT\
|
||||
\xc50\x15\xf3)\xb29\xbfc!\x8c\x98v\xaf\xe0f\x14\\*\xa4\x85f\x10|\x9c(\xa9)\
|
||||
\xfc\x02?r\xb8\xfc~J.\xd0\x00\x00\x00\x00IEND\xaeB`\x82"
|
||||
|
||||
def getPHPBitmap():
|
||||
return BitmapFromImage(getPHPImage())
|
||||
|
||||
@@ -73,7 +73,7 @@ class PerlCtrl(CodeEditor.CodeCtrl):
|
||||
|
||||
|
||||
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):
|
||||
@@ -130,7 +130,11 @@ class PerlCtrl(CodeEditor.CodeCtrl):
|
||||
class PerlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||
|
||||
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):
|
||||
return getPerlIcon()
|
||||
|
||||
|
||||
PERLKEYWORDS = [
|
||||
@@ -392,24 +396,22 @@ import cStringIO
|
||||
|
||||
def getPerlData():
|
||||
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\x01\x81IDAT8\x8d\xa5S1n\xe30\x10\x1cJ\xf9\x80;U\x04\x04~\xc06\xdc\xa9\
|
||||
\x10\xd4\xb3K\xf2\x01\xf9\x01F\x92\xce\x8d:vI\x84\xdc\xd5\xaa\xdc%\xd1\x17\
|
||||
\x0c\x17ns\xa7\x07,\x16\xe0G6E@B\x91\x9c*\x0b\x10 \xb9\xe4\xecpg\xa8T\x92\
|
||||
\xe27q5^\xbc\xbf\xbd\n\x00\\\xdf\xdc\xaa\xb0\xf7\xfc\xf4(\xcc\x8c<\xcfqw\xff\
|
||||
\xa0\xa6\x00PI\x8aa\x18\xa4m[\xd9\xedvb\xad\x95a\x18D%)\xfa\xbe\x97\xc5b!\
|
||||
\xd6Z\xb1\xd6J\xdb\xb6\xa2\x92\x14\xe3\x91\x00\xc0r\xb5VZ\xeb\x08z<\x1e\xf1\
|
||||
\xfe\xf6*]\xd7\xc1\x18\x03c\x0c\xea\xba\x063\xe3\xff\xbf\x0f\xf9\xf1\tD\x14\
|
||||
\xe7\xce9\xec\xf7{\x00\x80\xf7\xfe\x1b\xf88\x920\xf1\xde\xc7j\xcc\x8c,\xcb\
|
||||
\xe2:\xe4\xeb\xba\x06\x80o,"\x03\xad5\x0e\x87C\xacz>\x9fAD\xb1\xba\xd6\x1aD\
|
||||
\x04f\x063\xcf\x19\\\xdf\xdc\xaa\xa2(p:\x9d\xe0\xbd\x07\x11\xc19\x07\xad5\
|
||||
\x98\x19\xce9l\xb7[\x10\x11\xf2<\x9f\x03\x00\xc0\xcb\x9f\xbf\xaa,\xcbX!\xcb2\
|
||||
t]\x17\xf3M\xd3\xc4\'\xc5\x98\xca\x12d\xddl6\x12d\x0c\x12\xab$\x85\xb5Vf2N\
|
||||
\x83\x88P\x14\x05\xbc\xf7h\x9a\x06UUE\xda\xc6\x98\xcbM\x1c\x871\x06\xde{TU\
|
||||
\x05\xe0\xcb\'\xe1RY\x96X\xae\xd6\xd1\x91\x17\x19\x00_]_\xae\xd6\x8a\x88\xf0\
|
||||
\xfc\xf4(\xe1\xd2\xb4\x07?\x02\x8c\x0f\x8e\x1d85\xd2\xc5\x06\xf6}?\xf3|\x18\
|
||||
\xb3\xdco\xbf\xf3\'`\xa6\xbc1\xa7\xd6\xcb\xbf\x00\x00\x00\x00IEND\xaeB`\x82'\
|
||||
\x00\x01CIDAT8\x8d\x95\x93\xbfN\x02A\x10\x87\xbf[\xef\x05\xach|\x02m}\x008\
|
||||
\x881Z\xd2\x1a\x13\x0bKx\x02{\xa3\xa13\xc6\xc6\xc6\xd2DZ+s\\\x83\x95\x1d\xa2\
|
||||
&V\x104\x01/p\x01\t\xa0\xe8X\xc0\x9d\x87\xdc^\xf0\x97Lfw3\xdf\xec\xcc\xfe1\
|
||||
\xca\x95\xba0\x95\xeb\xf5\x01h\xb4\xda\x00x\xde\x90\x83\xfd\r\x838\x95+u\xa9\
|
||||
\rDj\x03\x91\xe7\xbe\xc8}wb\xa7\xc5\xb2\xdc\xbe\x89\xe4\x8f\xae\xc4PK\xe8L\
|
||||
\xc5%\xef\x8da{7K\xee\xf0Rt1\xa6\xeb\xf5Y\x01>\xbea\xf45Y\xec\x8e&\xe5\xdf]\
|
||||
\xdb4\xdd\x0e\xaf/-\xed&&\x110\xc0\xfa\x96\xc5\xf1N\x06\x80\xe5\xb5\xac6\x81\
|
||||
\x82y\xb87\x9e\r\xeaT\x8b3s+\x95\x14+\x95\x14\x00\xd5h\xb5\xe9\x8e\xe6a\x7f\
|
||||
\xf70\x14\xf6\xfeXy\xde0\x08\xf2\xe1\xf6gt\xb9V*)v\xc9\t\xae\xd5.9\x86\x19\
|
||||
\x05\x9e\xefe\xe6i\x8dT\xd3\xed\xfc\x0b\x0e\xb7\x00\xd3C\xd4\x95\x1c'\xbf\
|
||||
\x15\x15\xbe\xe3\xc6;l\x9e\xdc\x00\xbf\xfe/`\x97\x1c#|\x0e&@\xb1p\x16\x04>U\
|
||||
\x1fI\x00\x17\xb9<\t\xa0\xc9*\t\x1e\xf4\xa5D\xbd\xeft:-q~\xe1\xbf\xb0\x88b\
|
||||
\x13\x84{\x8d\x9a\x03\xfc\x00\xea\x7f\xa9A\xa7\xc3Vo\x00\x00\x00\x00IEND\xae\
|
||||
B`\x82"
|
||||
|
||||
|
||||
def getPerlBitmap():
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -25,6 +25,8 @@ import keyword # for GetAutoCompleteKeywordList
|
||||
import sys # for GetAutoCompleteKeywordList
|
||||
import MessageService # for OnCheckCode
|
||||
import OutlineService
|
||||
import FindInDirService
|
||||
from UICommon import CaseInsensitiveCompare
|
||||
try:
|
||||
import checker # for pychecker
|
||||
_CHECKER_INSTALLED = True
|
||||
@@ -69,8 +71,11 @@ class PythonView(CodeEditor.CodeView):
|
||||
|
||||
def OnActivateView(self, activate, activeView, deactiveView):
|
||||
STCTextEditor.TextView.OnActivateView(self, activate, activeView, deactiveView)
|
||||
if activate:
|
||||
wx.CallAfter(self.LoadOutline) # need CallAfter because document isn't loaded yet
|
||||
if activate and self.GetCtrl():
|
||||
if self.GetDocumentManager().GetFlags() & wx.lib.docview.DOC_SDI:
|
||||
self.LoadOutline()
|
||||
else:
|
||||
wx.CallAfter(self.LoadOutline) # need CallAfter because document isn't loaded yet
|
||||
|
||||
|
||||
def OnClose(self, deleteWindow = True):
|
||||
@@ -99,7 +104,7 @@ class PythonView(CodeEditor.CodeView):
|
||||
filterkw = filter(lambda item: item.lower().startswith(lowerHint), kw) # remove variables and methods that don't match hint
|
||||
kw = filterkw
|
||||
|
||||
kw.sort(self.CaseInsensitiveCompare)
|
||||
kw.sort(CaseInsensitiveCompare)
|
||||
|
||||
if hint:
|
||||
replaceLen = len(hint)
|
||||
@@ -119,6 +124,7 @@ class PythonView(CodeEditor.CodeView):
|
||||
# pychecker only works on files, doesn't take a stream or string input
|
||||
if self.GetDocument().IsModified():
|
||||
dlg = wx.MessageDialog(self.GetFrame(), _("'%s' has been modfied and must be saved first. Save file and check code?") % filename, _("Check Code"))
|
||||
dlg.CenterOnParent()
|
||||
val = dlg.ShowModal()
|
||||
dlg.Destroy()
|
||||
if val == wx.ID_OK:
|
||||
@@ -138,11 +144,13 @@ class PythonView(CodeEditor.CodeView):
|
||||
# Set cursor to Wait cursor
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_WAIT))
|
||||
|
||||
# This takes a while for involved code
|
||||
checker.checkSyntax(self.GetDocument().GetFilename(), view)
|
||||
try:
|
||||
# This takes a while for involved code
|
||||
checker.checkSyntax(self.GetDocument().GetFilename(), view)
|
||||
|
||||
# Set cursor to Default cursor
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
finally:
|
||||
# Set cursor to Default cursor
|
||||
wx.GetApp().GetTopWindow().SetCursor(wx.StockCursor(wx.CURSOR_DEFAULT))
|
||||
|
||||
|
||||
def OnJumpToFoundLine(self, event):
|
||||
@@ -167,7 +175,7 @@ class PythonView(CodeEditor.CodeView):
|
||||
break
|
||||
|
||||
if not foundView:
|
||||
doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT)
|
||||
doc = wx.GetApp().GetDocumentManager().CreateDocument(filename, wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE)
|
||||
foundView = doc.GetFirstView()
|
||||
|
||||
if foundView:
|
||||
@@ -269,11 +277,29 @@ class PythonInterpreterView(wx.lib.docview.View):
|
||||
return True
|
||||
|
||||
|
||||
class PythonInterpreterDocument(wx.lib.docview.Document):
|
||||
""" Generate Unique Doc Type """
|
||||
pass
|
||||
|
||||
|
||||
class PythonService(CodeEditor.CodeService):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
CodeEditor.CodeService.__init__(self)
|
||||
docManager = wx.GetApp().GetDocumentManager()
|
||||
pythonInterpreterTemplate = wx.lib.docview.DocTemplate(docManager,
|
||||
_("Python Interpreter"),
|
||||
"*.Foobar",
|
||||
"Foobar",
|
||||
".Foobar",
|
||||
_("Python Interpreter Document"),
|
||||
_("Python Interpreter View"),
|
||||
PythonInterpreterDocument,
|
||||
PythonInterpreterView,
|
||||
flags = wx.lib.docview.TEMPLATE_INVISIBLE,
|
||||
icon = getPythonIcon())
|
||||
docManager.AssociateTemplate(pythonInterpreterTemplate)
|
||||
|
||||
|
||||
def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
|
||||
@@ -308,7 +334,7 @@ class PythonService(CodeEditor.CodeService):
|
||||
docManager = wx.GetApp().GetDocumentManager()
|
||||
event.Check(False)
|
||||
for doc in docManager.GetDocuments():
|
||||
if isinstance(doc.GetFirstView(), PythonInterpreterView):
|
||||
if isinstance(doc, PythonInterpreterDocument):
|
||||
event.Check(True)
|
||||
break
|
||||
return True
|
||||
@@ -318,28 +344,20 @@ class PythonService(CodeEditor.CodeService):
|
||||
|
||||
def OnViewPythonInterpreter(self, event):
|
||||
for doc in wx.GetApp().GetDocumentManager().GetDocuments():
|
||||
if isinstance(doc.GetFirstView(), PythonInterpreterView):
|
||||
doc.GetFirstView().GetDocument().DeleteAllViews()
|
||||
if isinstance(doc, PythonInterpreterDocument):
|
||||
doc.DeleteAllViews()
|
||||
return
|
||||
|
||||
docManager = self.GetDocumentManager()
|
||||
template = wx.lib.docview.DocTemplate(docManager,
|
||||
_("Python Interpreter"),
|
||||
"*.Foobar",
|
||||
"Foobar",
|
||||
".Foobar",
|
||||
_("Python Interpreter Document"),
|
||||
_("Python Interpreter View"),
|
||||
wx.lib.docview.Document,
|
||||
PythonInterpreterView,
|
||||
flags = wx.lib.docview.TEMPLATE_INVISIBLE)
|
||||
newDoc = template.CreateDocument('', wx.lib.docview.DOC_SILENT)
|
||||
if newDoc:
|
||||
newDoc.SetDocumentName(template.GetDocumentName())
|
||||
newDoc.SetDocumentTemplate(template)
|
||||
newDoc.OnNewDocument()
|
||||
newDoc.SetWriteable(False)
|
||||
newDoc.GetFirstView().GetFrame().SetTitle(_("Python Interpreter"))
|
||||
for template in self.GetDocumentManager().GetTemplates():
|
||||
if template.GetDocumentType() == PythonInterpreterDocument:
|
||||
newDoc = template.CreateDocument('', wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE)
|
||||
if newDoc:
|
||||
newDoc.SetDocumentName(template.GetDocumentName())
|
||||
newDoc.SetDocumentTemplate(template)
|
||||
newDoc.OnNewDocument()
|
||||
newDoc.SetWriteable(False)
|
||||
newDoc.GetFirstView().GetFrame().SetTitle(_("Python Interpreter"))
|
||||
break
|
||||
|
||||
|
||||
class PythonCtrl(CodeEditor.CodeCtrl):
|
||||
@@ -354,8 +372,42 @@ class PythonCtrl(CodeEditor.CodeCtrl):
|
||||
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):
|
||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Python", hasWordWrap = False, hasTabs = True)
|
||||
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix="Python", hasWordWrap=True, hasTabs=True, hasFolding=True)
|
||||
|
||||
|
||||
def GetFontAndColorFromConfig(self):
|
||||
@@ -544,40 +596,56 @@ class PythonOptionsPanel(wx.Panel):
|
||||
choosePathButton = wx.Button(self, -1, _("Browse..."))
|
||||
pathSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
HALF_SPACE = 5
|
||||
pathSizer.Add(pathLabel, 0, wx.ALIGN_LEFT | wx.LEFT | wx.RIGHT | wx.TOP, HALF_SPACE)
|
||||
pathSizer.Add(self._pathTextCtrl, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.RIGHT, HALF_SPACE)
|
||||
pathSizer.Add(choosePathButton, 0, wx.ALIGN_RIGHT | wx.LEFT, HALF_SPACE)
|
||||
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 = wx.BoxSizer(wx.VERTICAL)
|
||||
mainSizer.Add(pathSizer, 0, wx.LEFT | wx.RIGHT | wx.TOP, 10)
|
||||
mainSizer.Add(pathSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
|
||||
|
||||
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "Python", label = "Python", hasWordWrap = False, hasTabs = True, addPage=False)
|
||||
mainSizer.Add(self._otherOptions)
|
||||
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)
|
||||
self.SetSizer(mainSizer)
|
||||
parent.AddPage(self, _("Python"))
|
||||
|
||||
|
||||
def OnChoosePath(self, event):
|
||||
defaultDir = os.path.dirname(self._pathTextCtrl.GetValue().strip())
|
||||
defaultFile = os.path.basename(self._pathTextCtrl.GetValue().strip())
|
||||
if _WINDOWS:
|
||||
wildcard = _("*.exe")
|
||||
wildcard = _("Executable (*.exe)|*.exe|All|*.*")
|
||||
if not defaultFile:
|
||||
defaultFile = "python.exe"
|
||||
else:
|
||||
wildcard = _("*")
|
||||
path = wx.FileSelector(_("Select a File"),
|
||||
_(""),
|
||||
_(""),
|
||||
wildcard = wildcard ,
|
||||
flags = wx.HIDE_READONLY,
|
||||
parent = wx.GetApp().GetTopWindow())
|
||||
if path:
|
||||
self._pathTextCtrl.SetValue(path)
|
||||
self._pathTextCtrl.SetToolTipString(self._pathTextCtrl.GetValue())
|
||||
self._pathTextCtrl.SetInsertionPointEnd()
|
||||
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 OnOK(self, optionsDialog):
|
||||
if len(self._pathTextCtrl.GetValue()) > 0:
|
||||
config = wx.ConfigBase_Get()
|
||||
config.Write("ActiveGridPythonLocation", self._pathTextCtrl.GetValue())
|
||||
config = wx.ConfigBase_Get()
|
||||
config.Write("ActiveGridPythonLocation", self._pathTextCtrl.GetValue().strip())
|
||||
|
||||
self._otherOptions.OnOK(optionsDialog)
|
||||
|
||||
|
||||
def GetIcon(self):
|
||||
return getPythonIcon()
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Icon Bitmaps - generated by encode_bitmaps.py
|
||||
#----------------------------------------------------------------------------
|
||||
@@ -587,18 +655,28 @@ import cStringIO
|
||||
|
||||
def getPythonData():
|
||||
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\xd5IDAT8\x8d\x8d\x93Y\x0e\xc3 \x0cD\x9fM\xcf\xddNr2.\x96\xb8\x1f\
|
||||
\x05\n\x84.#Y\x10\xa3\x19o\xb1\x99'*\xe2<\x82\x0e\xe6\xc9\xf8\x01\xef?\xa4\
|
||||
\xf7)]\x05\x970O\xcdr\xce!\x119\xe7\x00\x02\x88\xfe}i\xb5\x848\x8f\xa8\x19\
|
||||
\xcc\x19}+\xc5\xcc\xd3\x92<CZ\x0b\x99\xc4\xb2N\x01<\x80\xad\xdc?\x88\xf8\x1c\
|
||||
X\x8f7\xe1\x1f\xdc*\xa9a+\xe1\xa3\xdc\xe7\xb4\xf6\xd1\xe5\xb6'\xc3@\xc5\xa0#\
|
||||
\xab\x94\xd1\x0bL\xf0\xe6\x17\xa8v\xc3\x8aS\xa0.\x8be\x13\xe3\x15\x8f\xe1\
|
||||
\xa5D\xee\xc9\xdb~%\xc7y\x84\xbb'sO\xd6\xd4\x17\xe4~\xc4\xf5\xef\xac\xa7\r\
|
||||
\xbbp?b&\x0f\x89i\x14\x93\xca\x14z\xc5oh\x02E\xc4<\xd92\x03\xe0:B^\xc4K#\xe7\
|
||||
\xe5\x00\x02\xfd\xb9H\x9ex\x02\x9a\x05a\xd2\xd3c\xc0\xcc\x00\x00\x00\x00IEND\
|
||||
\xaeB`\x82"
|
||||
\x00\x01\xe7IDAT8\x8d}\x921h\x13Q\x18\xc7\x7fw\xb9\x0ei\x9d*\xbd\xeb\x10\x8f\
|
||||
,\x99\x1c*A[\xaa\x19B\xe8\xd0\xb1\x0e%K\x87\x88T2\x88Cqp\tD\x14i\xe9\xe0V\
|
||||
\xdaQ\xb7\xe0P\xa1\x8b\xa0(\x95$z\xd5Q1\x90\xa2\xd7\x9a4^\x87\xa0`\x92!w9\
|
||||
\x87\xf8.\xb9\xa6\xc97\xbd\xef{\xef\xfb\xbd\xff\xfb\xbfO*~;v\xf9\x1f\xad\xba\
|
||||
\x05@\xf9\xd4\x06\xc0::$\xbb\x96\x92\x18\x11\n@(4\xdd\xcdB\xd3\xd4\x1d\x85\
|
||||
\x8b\x97\xe1\xe3;\x83\x99\xe5\x15\xb2\xe0\x8e\x82\xc8\xa3\xe8\x003\xcb+\xac\
|
||||
\xaee\xdda\xfb\xb2\x90\rPw\x14\x00\x9a\xb5\n\xbf\xfflSz\x9d\xa2Y\xdc"zca\xe8\
|
||||
\x05\xb2h\x14\xcd\xd0\xf3B\x9f\x98\xe5\xf9\xde\x13"\xaaB\xc7\xb1\xcfU!\x0b\
|
||||
\xc3D4k\x15\xac\x93\x03\xf4\x89Y\xaf\x96\xffT\x028\x17\xa2\xf4\'\xcdZ\x85\
|
||||
\xf7F\x06{\xaa\x80ev\xc1\x91\xb91>\x18\x0f\xb8\xb7\x95a\xe9\xca\x0b:\x8e\xed\
|
||||
\xca\x01E\x1a\x00\x98\r\x89\x92\x91\xa1\xda\xd8\x87\x06ha\x1f\x1b\x80\xcd\
|
||||
\x9d%\xe0\xa5\x0f"[G\x87\x98\x8d\xde/ia\x05-\xac`\x996\xf9\\\x0b\xcb\xb4)\
|
||||
\x1bmOMn\xf7\xd5\xf0\'\\\x8b\xdces\xe7\x8d\xef\x80h\xd6\xc2\n\xf9\\\x0b]\xf5\
|
||||
\xab\xf2\xcdApR#\xf1kp4b\xc9 \xf9\\\x0b\x80\xe4\xcdE\xaf\xdeqlW\xaeVL\xaf`~\
|
||||
\xd9\x03@W\xd3\x00\xc4\x13\x0b\xc4\x92A\xcf\xd0\xf9\xe8:\x89\xebW\x01(|\xfd\
|
||||
\xe1\xbe-~F\xbas\xff\x91\xf75\x82n\x9d\x1c\xf0}\xfciw\xdd\xe7A<\xd1\x1b\xa8j\
|
||||
c\x9f\xb2\xd1F\x92\xe4\x80O\x12\xc0\xc6\xb3\x14\xf6Ta\xe0)g\x81\xba\x9a\xf6\
|
||||
\x9b(\x07\x14I@\x84lq\xb8?\xe6\xa3\xeb\x00\xdc\xba\x9d\xf4+\x10*~\xfem\xf3\
|
||||
\xf8\xe1\x06\xc7\xa7\xdb\xe8j\x9a\xf8\xdc\xa4\xb7\x1f[\\\xe5\xd2\x851/\xff\
|
||||
\x07\xac\x9b\xd1e\x12\x96\x0f\xfd\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getPythonBitmap():
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# Created: 8/10/03
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2003-2005 ActiveGrid, Inc.
|
||||
# Copyright: (c) 2003-2006 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
@@ -47,9 +47,15 @@ TEXT_STATUS_BAR_ID = wx.NewId()
|
||||
class TextDocument(wx.lib.docview.Document):
|
||||
|
||||
|
||||
def __init__(self):
|
||||
wx.lib.docview.Document .__init__(self)
|
||||
self._inModify = False
|
||||
|
||||
|
||||
def SaveObject(self, fileObject):
|
||||
view = self.GetFirstView()
|
||||
fileObject.write(view.GetValue())
|
||||
view.SetModifyFalse()
|
||||
return True
|
||||
|
||||
|
||||
@@ -57,29 +63,43 @@ class TextDocument(wx.lib.docview.Document):
|
||||
view = self.GetFirstView()
|
||||
data = fileObject.read()
|
||||
view.SetValue(data)
|
||||
view.SetModifyFalse()
|
||||
return True
|
||||
|
||||
|
||||
def IsModified(self):
|
||||
view = self.GetFirstView()
|
||||
if view:
|
||||
return wx.lib.docview.Document.IsModified(self) or view.IsModified()
|
||||
else:
|
||||
return wx.lib.docview.Document.IsModified(self)
|
||||
return view.IsModified()
|
||||
return False
|
||||
|
||||
|
||||
def Modify(self, mod):
|
||||
def Modify(self, modify):
|
||||
if self._inModify:
|
||||
return
|
||||
self._inModify = True
|
||||
|
||||
view = self.GetFirstView()
|
||||
wx.lib.docview.Document.Modify(self, mod)
|
||||
if not mod and view:
|
||||
if not modify and view:
|
||||
view.SetModifyFalse()
|
||||
|
||||
wx.lib.docview.Document.Modify(self, modify) # this must called be after the SetModifyFalse call above.
|
||||
|
||||
self._inModify = False
|
||||
|
||||
|
||||
def OnCreateCommandProcessor(self):
|
||||
# Don't create a command processor, it has its own
|
||||
pass
|
||||
|
||||
|
||||
# Use this to override MultiClient.Select to prevent yellow background.
|
||||
def MultiClientSelectBGNotYellow(a):
|
||||
a.GetParent().multiView.UnSelect()
|
||||
a.selected = True
|
||||
#a.SetBackgroundColour(wx.Colour(255,255,0)) # Yellow
|
||||
a.Refresh()
|
||||
|
||||
class TextView(wx.lib.docview.View):
|
||||
MARKER_NUM = 0
|
||||
MARKER_MASK = 0x1
|
||||
@@ -102,6 +122,12 @@ class TextView(wx.lib.docview.View):
|
||||
|
||||
|
||||
def GetCtrl(self):
|
||||
if wx.Platform == "__WXMAC__":
|
||||
# look for active one first
|
||||
self._textEditor = self._GetActiveCtrl(self._dynSash)
|
||||
if self._textEditor == None: # it is possible none are active
|
||||
# look for any existing one
|
||||
self._textEditor = self._FindCtrl(self._dynSash)
|
||||
return self._textEditor
|
||||
|
||||
|
||||
@@ -116,9 +142,21 @@ class TextView(wx.lib.docview.View):
|
||||
|
||||
def OnCreate(self, doc, flags):
|
||||
frame = wx.GetApp().CreateDocumentFrame(self, doc, flags, style = wx.DEFAULT_FRAME_STYLE | wx.NO_FULL_REPAINT_ON_RESIZE)
|
||||
self._dynSash = wx.gizmos.DynamicSashWindow(frame, -1, style=wx.CLIP_CHILDREN)
|
||||
self._dynSash._view = self
|
||||
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
||||
# wxBug: DynamicSashWindow doesn't work on Mac, so revert to
|
||||
# multisash implementation
|
||||
if wx.Platform == "__WXMAC__":
|
||||
wx.lib.multisash.MultiClient.Select = MultiClientSelectBGNotYellow
|
||||
self._dynSash = wx.lib.multisash.MultiSash(frame, -1)
|
||||
self._dynSash.SetDefaultChildClass(self.GetCtrlClass()) # wxBug: MultiSash instantiates the first TextCtrl with this call
|
||||
|
||||
self._textEditor = self.GetCtrl() # wxBug: grab the TextCtrl from the MultiSash datastructure
|
||||
else:
|
||||
self._dynSash = wx.gizmos.DynamicSashWindow(frame, -1, style=wx.CLIP_CHILDREN)
|
||||
self._dynSash._view = self
|
||||
self._textEditor = self.GetCtrlClass()(self._dynSash, -1, style=wx.NO_BORDER)
|
||||
wx.EVT_LEFT_DOWN(self._textEditor, self.OnLeftClick)
|
||||
self._textEditor.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModify)
|
||||
|
||||
self._CreateSizer(frame)
|
||||
self.Activate()
|
||||
frame.Show(True)
|
||||
@@ -126,18 +164,29 @@ class TextView(wx.lib.docview.View):
|
||||
return True
|
||||
|
||||
|
||||
def OnModify(self, event):
|
||||
self.GetDocument().Modify(self._textEditor.GetModify())
|
||||
|
||||
|
||||
def _CreateSizer(self, frame):
|
||||
sizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
sizer.Add(self._dynSash, 1, wx.EXPAND)
|
||||
frame.SetSizer(sizer)
|
||||
frame.SetAutoLayout(True)
|
||||
|
||||
|
||||
def OnLeftClick(self, event):
|
||||
self.Activate()
|
||||
event.Skip()
|
||||
|
||||
|
||||
def OnUpdate(self, sender = None, hint = None):
|
||||
if wx.lib.docview.View.OnUpdate(self, sender, hint):
|
||||
return
|
||||
|
||||
if hint == "ViewStuff":
|
||||
self.GetCtrl().SetViewDefaults()
|
||||
elif hint == "Font":
|
||||
font, color = self.GetFontAndColorFromConfig()
|
||||
font, color = self.GetCtrl().GetFontAndColorFromConfig()
|
||||
self.GetCtrl().SetFont(font)
|
||||
self.GetCtrl().SetFontColor(color)
|
||||
|
||||
@@ -195,7 +244,7 @@ class TextView(wx.lib.docview.View):
|
||||
self.GetCtrl().SetViewEOL(not self.GetCtrl().GetViewEOL())
|
||||
return True
|
||||
elif id == VIEW_INDENTATION_GUIDES_ID:
|
||||
self.GetCtrl().SetViewIndentationGuides(not self.GetCtrl().GetViewIndentationGuides())
|
||||
self.GetCtrl().SetIndentationGuides(not self.GetCtrl().GetIndentationGuides())
|
||||
return True
|
||||
elif id == VIEW_RIGHT_EDGE_ID:
|
||||
self.GetCtrl().SetViewRightEdge(not self.GetCtrl().GetViewRightEdge())
|
||||
@@ -352,6 +401,29 @@ class TextView(wx.lib.docview.View):
|
||||
def _GetParentFrame(self):
|
||||
return wx.GetTopLevelParent(self.GetFrame())
|
||||
|
||||
def _GetActiveCtrl(self, parent):
|
||||
""" Walk through the MultiSash windows and find the active Control """
|
||||
if isinstance(parent, wx.lib.multisash.MultiClient) and parent.selected:
|
||||
return parent.child
|
||||
if hasattr(parent, "GetChildren"):
|
||||
for child in parent.GetChildren():
|
||||
found = self._GetActiveCtrl(child)
|
||||
if found:
|
||||
return found
|
||||
return None
|
||||
|
||||
|
||||
def _FindCtrl(self, parent):
|
||||
""" Walk through the MultiSash windows and find the first TextCtrl """
|
||||
if isinstance(parent, self.GetCtrlClass()):
|
||||
return parent
|
||||
if hasattr(parent, "GetChildren"):
|
||||
for child in parent.GetChildren():
|
||||
found = self._FindCtrl(child)
|
||||
if found:
|
||||
return found
|
||||
return None
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Methods for TextDocument to call
|
||||
@@ -401,6 +473,7 @@ class TextView(wx.lib.docview.View):
|
||||
data.SetInitialFont(self.GetCtrl().GetFont())
|
||||
data.SetColour(self.GetCtrl().GetFontColor())
|
||||
fontDialog = wx.FontDialog(self.GetFrame(), data)
|
||||
fontDialog.CenterOnParent()
|
||||
if fontDialog.ShowModal() == wx.ID_OK:
|
||||
data = fontDialog.GetFontData()
|
||||
self.GetCtrl().SetFont(data.GetChosenFont())
|
||||
@@ -520,9 +593,11 @@ class TextView(wx.lib.docview.View):
|
||||
def EnsureVisible(self, line):
|
||||
self.GetCtrl().EnsureVisible(line-1) # line numbering for editor is 0 based, we are 1 based.
|
||||
|
||||
|
||||
def EnsureVisibleEnforcePolicy(self, line):
|
||||
self.GetCtrl().EnsureVisibleEnforcePolicy(line-1) # line numbering for editor is 0 based, we are 1 based.
|
||||
|
||||
|
||||
def LineFromPosition(self, pos):
|
||||
return self.GetCtrl().LineFromPosition(pos)+1 # line numbering for editor is 0 based, we are 1 based.
|
||||
|
||||
@@ -614,7 +689,13 @@ class TextView(wx.lib.docview.View):
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def GetMarkerLines(self, mask=MARKER_MASK):
|
||||
retval = []
|
||||
for lineNum in range(self.GetCtrl().GetLineCount()):
|
||||
if self.GetCtrl().MarkerGet(lineNum) & mask:
|
||||
retval.append(lineNum)
|
||||
return retval
|
||||
|
||||
def GetMarkerCount(self):
|
||||
return self._markerCount
|
||||
|
||||
@@ -756,11 +837,12 @@ class TextStatusBar(wx.StatusBar):
|
||||
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)
|
||||
self._configPrefix = configPrefix
|
||||
self._hasWordWrap = hasWordWrap
|
||||
self._hasTabs = hasTabs
|
||||
self._hasFolding = hasFolding
|
||||
SPACE = 10
|
||||
HALF_SPACE = 5
|
||||
config = wx.ConfigBase_Get()
|
||||
@@ -797,6 +879,9 @@ class TextOptionsPanel(wx.Panel):
|
||||
self._viewRightEdgeCheckBox.SetValue(config.ReadInt(self._configPrefix + "EditorViewRightEdge", False))
|
||||
self._viewLineNumbersCheckBox = wx.CheckBox(self, -1, _("Show line numbers"))
|
||||
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:
|
||||
self._hasTabsCheckBox = wx.CheckBox(self, -1, _("Use spaces instead of tabs"))
|
||||
self._hasTabsCheckBox.SetValue(not wx.ConfigBase_Get().ReadInt(self._configPrefix + "EditorUseTabs", False))
|
||||
@@ -807,9 +892,9 @@ class TextOptionsPanel(wx.Panel):
|
||||
textPanelSizer = wx.BoxSizer(wx.VERTICAL)
|
||||
textFontSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
textFontSizer.Add(fontLabel, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.TOP, HALF_SPACE)
|
||||
textFontSizer.Add(self._sampleTextCtrl, 0, wx.ALIGN_LEFT | wx.EXPAND | wx.RIGHT, HALF_SPACE)
|
||||
textFontSizer.Add(self._sampleTextCtrl, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.RIGHT, HALF_SPACE)
|
||||
textFontSizer.Add(chooseFontButton, 0, wx.ALIGN_RIGHT | wx.LEFT, HALF_SPACE)
|
||||
textPanelSizer.Add(textFontSizer, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelSizer.Add(textFontSizer, 0, wx.ALL|wx.EXPAND, HALF_SPACE)
|
||||
if self._hasWordWrap:
|
||||
textPanelSizer.Add(self._wordWrapCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelSizer.Add(self._viewWhitespaceCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||
@@ -817,13 +902,15 @@ class TextOptionsPanel(wx.Panel):
|
||||
textPanelSizer.Add(self._viewIndentationGuideCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelSizer.Add(self._viewRightEdgeCheckBox, 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:
|
||||
textPanelSizer.Add(self._hasTabsCheckBox, 0, wx.ALL, HALF_SPACE)
|
||||
textIndentWidthSizer = wx.BoxSizer(wx.HORIZONTAL)
|
||||
textIndentWidthSizer.Add(indentWidthLabel, 0, wx.ALIGN_LEFT | wx.RIGHT | wx.TOP, HALF_SPACE)
|
||||
textIndentWidthSizer.Add(self._indentWidthChoice, 0, wx.ALIGN_LEFT | wx.EXPAND, HALF_SPACE)
|
||||
textPanelSizer.Add(textIndentWidthSizer, 0, wx.ALL, HALF_SPACE)
|
||||
textPanelBorderSizer.Add(textPanelSizer, 0, wx.ALL, SPACE)
|
||||
textPanelBorderSizer.Add(textPanelSizer, 0, wx.ALL|wx.EXPAND, SPACE)
|
||||
## styleButton = wx.Button(self, -1, _("Choose Style..."))
|
||||
## wx.EVT_BUTTON(self, styleButton.GetId(), self.OnChooseStyle)
|
||||
## textPanelBorderSizer.Add(styleButton, 0, wx.ALL, SPACE)
|
||||
@@ -856,6 +943,7 @@ class TextOptionsPanel(wx.Panel):
|
||||
## #'HTML', 'html',
|
||||
## #'XML', 'xml',
|
||||
## config)
|
||||
## dlg.CenterOnParent()
|
||||
## try:
|
||||
## dlg.ShowModal()
|
||||
## finally:
|
||||
@@ -868,6 +956,7 @@ class TextOptionsPanel(wx.Panel):
|
||||
data.SetInitialFont(self._textFont)
|
||||
data.SetColour(self._textColor)
|
||||
fontDialog = wx.FontDialog(self, data)
|
||||
##fontDialog.CenterOnParent()
|
||||
if fontDialog.ShowModal() == wx.ID_OK:
|
||||
data = fontDialog.GetFontData()
|
||||
self._textFont = data.GetChosenFont()
|
||||
@@ -888,6 +977,9 @@ class TextOptionsPanel(wx.Panel):
|
||||
config.WriteInt(self._configPrefix + "EditorViewRightEdge", self._viewRightEdgeCheckBox.GetValue())
|
||||
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorViewLineNumbers", True) != 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:
|
||||
doViewStuffUpdate = doViewStuffUpdate or config.ReadInt(self._configPrefix + "EditorWordWrap", False) != self._wordWrapCheckBox.GetValue()
|
||||
config.WriteInt(self._configPrefix + "EditorWordWrap", self._wordWrapCheckBox.GetValue())
|
||||
@@ -909,6 +1001,10 @@ class TextOptionsPanel(wx.Panel):
|
||||
document.UpdateAllViews(hint = "ViewStuff")
|
||||
if doFontUpdate:
|
||||
document.UpdateAllViews(hint = "Font")
|
||||
|
||||
|
||||
def GetIcon(self):
|
||||
return getTextIcon()
|
||||
|
||||
|
||||
class TextCtrl(wx.stc.StyledTextCtrl):
|
||||
@@ -958,8 +1054,27 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
||||
self.SetFontColor(color)
|
||||
self.MarkerDefineDefault()
|
||||
|
||||
# for multisash initialization
|
||||
if isinstance(parent, wx.lib.multisash.MultiClient):
|
||||
while parent.GetParent():
|
||||
parent = parent.GetParent()
|
||||
if hasattr(parent, "GetView"):
|
||||
break
|
||||
if hasattr(parent, "GetView"):
|
||||
textEditor = parent.GetView()._textEditor
|
||||
if textEditor:
|
||||
doc = textEditor.GetDocPointer()
|
||||
if doc:
|
||||
self.SetDocPointer(doc)
|
||||
|
||||
|
||||
def OnFocus(self, event):
|
||||
# wxBug: On Mac, the STC control may fire a focus/kill focus event
|
||||
# on shutdown even if the control is in an invalid state. So check
|
||||
# before handling the event.
|
||||
if self.IsBeingDeleted():
|
||||
return
|
||||
|
||||
self.SetSelBackground(1, "BLUE")
|
||||
self.SetSelForeground(1, "WHITE")
|
||||
if hasattr(self, "_dynSash"):
|
||||
@@ -968,6 +1083,11 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
||||
|
||||
|
||||
def OnKillFocus(self, event):
|
||||
# wxBug: On Mac, the STC control may fire a focus/kill focus event
|
||||
# on shutdown even if the control is in an invalid state. So check
|
||||
# before handling the event.
|
||||
if self.IsBeingDeleted():
|
||||
return
|
||||
self.SetSelBackground(0, "BLUE")
|
||||
self.SetSelForeground(0, "WHITE")
|
||||
self.SetSelBackground(1, "#C0C0C0")
|
||||
@@ -975,13 +1095,15 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
||||
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()
|
||||
self.SetViewWhiteSpace(config.ReadInt(configPrefix + "EditorViewWhitespace", False))
|
||||
self.SetViewEOL(config.ReadInt(configPrefix + "EditorViewEOL", False))
|
||||
self.SetIndentationGuides(config.ReadInt(configPrefix + "EditorViewIndentationGuides", False))
|
||||
self.SetViewRightEdge(config.ReadInt(configPrefix + "EditorViewRightEdge", False))
|
||||
self.SetViewLineNumbers(config.ReadInt(configPrefix + "EditorViewLineNumbers", True))
|
||||
if hasFolding:
|
||||
self.SetViewFolding(config.ReadInt(configPrefix + "EditorViewFolding", True))
|
||||
if hasWordWrap:
|
||||
self.SetWordWrap(config.ReadInt(configPrefix + "EditorWordWrap", False))
|
||||
if hasTabs: # These methods do not exist in STCTextEditor and are meant for subclasses
|
||||
@@ -1150,6 +1272,17 @@ class TextCtrl(wx.stc.StyledTextCtrl):
|
||||
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):
|
||||
return True
|
||||
|
||||
@@ -1328,13 +1461,21 @@ import cStringIO
|
||||
|
||||
def getTextData():
|
||||
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`IDAT8\x8d\xed\x931\x0e\xc00\x08\x03m\x92\xff\xff8q\xa7JU!$\x12\x1d\
|
||||
\xeb\t\t8n\x81\xb4\x86J\xfa]h\x0ee\x83\xb4\xc6\x14\x00\x00R\xcc \t\xcd\xa1\
|
||||
\x08\xd2\xa3\xe1\x08*\t$\x1d\xc4\x012\x0b\x00\xce\xe4\xc8\xe0\t}\xf7\x8f\rV\
|
||||
\xd9\x1a\xec\xe0\xbf\xc1\xd7\x06\xd9\xf5UX\xfdF+m\x03\xb8\x00\xe4\xc74B"x\
|
||||
\xf1\xf4\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
\x00\x015IDAT8\x8d\xad\x90\xb1N\xc2P\x14\x86\xbf\x02/\xe0\xec#\x18g\xc3\xe6T\
|
||||
\x13':1\x18H\x98\x14\x12\x17G\x177\x17\x9c4a\xc5\xc0d0\xc2\xccdLx\x02^@+\t\
|
||||
\xc1\x90\xf6r\xdb\xc6\x94\xe5:\\\xdbP)\xc5DOr\x92\x9b{\xff\xfb\xfd\xff9\xc6h\
|
||||
l+\xbek.\x02\x00\xec\x99\x03\x80\xeb\xf8\\\x9d\x1d\x1bd\xd5hl\xab\xd7O\x15\
|
||||
\xf7x\xa1\xfb\xeeq\xa4^>\x94\xba\xb8yRF.\xcf\xa6.D\xa0Nw\x18C\xad\xb2\x19\
|
||||
\x9f\x0f\xca\x165\xd1V\xed\xebZj\x92\xc2\\\x04\xec\x02\xd5\x8a\x89\xb7\xd4\
|
||||
\x97n\xa8\xe3?\x0f\x86\x08\x19dNP\x00\xf0\x96\xd0\x7f\xd0\t\x84\x0c(U-\x0eK&\
|
||||
\xd3P\x8bz\xcdV6 \x8a\xed\x86\x99f\xe9\x00{\xe6\xb0\x13\xc2\xa0\xd3\xd7\t\
|
||||
\x84\x9f\x10\xec\x9dTp\x1d\xb1=A\xa9j\x01\xc4\xb1\x01&\xfe\x9a~\x1d\xe0:Zu\
|
||||
\x7f\xdb\x05@J/!(\xd6\x1bL\xde\xec\xcd\x00!\x03\xa6!\x1c\x9dVR\x9d\xdf\xe5\
|
||||
\x96\x04\xd1au\xd3\xab3\xef\x9f_f\x03\xa2\xa5\x15\xeb\x8d\xc4\xc36\xe7\x18 \
|
||||
\xa5G\xaf\xd9J\xb8f\xcd\xfc\xb3\x0c#\x97\xff\xb58\xadr\x7f\xfa\xfd\x1f\x80/\
|
||||
\x04\x1f\x8fW\x0e^\xc3\x12\x00\x00\x00\x00IEND\xaeB`\x82"
|
||||
|
||||
|
||||
def getTextBitmap():
|
||||
@@ -1356,12 +1497,20 @@ def getZoomInData():
|
||||
return \
|
||||
'\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\x00wIDAT8\x8d\xa5\x93Q\x12\x80 \x08D\xb5\xe9X\xee\xe9\xb7{\xd5Gc\xa9\
|
||||
\xacX\xca\x1f\xa0\x8fE0\x92<\xc3\x82\xed*\x08\xa0\xf2I~\x07\x000\x17T,\xdb\
|
||||
\xd6;\x08\xa4\x00\xa4GA\xab\xca\x00\xbc*\x1eD\xb4\x90\xa4O\x1e\xe3\x16f\xcc(\
|
||||
\xc8\x95F\x95\x8d\x02\xef\xa1n\xa0\xce\xc5v\x91zc\xacU\xbey\x03\xf0.\xa8\xb8\
|
||||
\x04\x8c\xac\x04MM\xa1lA\xfe\x85?\x90\xe5=X\x06\\\xebCA\xb3Q\xf34\x14\x00\
|
||||
\x00\x00\x00IEND\xaeB`\x82'
|
||||
\x00\x01TIDAT8\x8d\x8d\x93\xbbJ\x03A\x14\x86\xbf\xd9,\xc6\xd8E%`)VF[{\xc1v\
|
||||
\xf1\x82\x8f\xb0\xb94\xda\xa5\x13\x11\x8b`\xa9h\x10F\xe3#H.\xa6\x15\xccKhg\
|
||||
\x10\xc1B\x8bTF\x90\xc0X\x8c3\xbb\xd9\xcdF\x7f\x18\xf6\xec\x9cs\xbe\xfd\xe70\
|
||||
+\x84\x93"\xacb\xc1W\xe1\xf7\xeb\xfa\x8d`\x82\xdcXcI\x8e\x02AM\x02\t\xe1\xa4\
|
||||
(\x16|uz)y\x19\xc0\xc9\xdd;\x99\xee!\x00\xd9\xbd\x00\xd6\xaf\x95\xc7B\xac\
|
||||
\x03\xd3\x1c\xd6\xc2t\x10\xf7\x13\x8e\xe0\x14\x0b\xbe\xa2$m\xf3\xca\xea\xacM\
|
||||
\xe6\xd2\xc1\xcaWdl>#\x0e\x8c\xed\xe7n\x90|\xa8\x96m\xbc~ y\x04Z\xcd\x86\xda\
|
||||
\xda\xde\xb1Gq\x00\xb2S\t\xfeB\x9aK\xa8\xb1\x0e\xf2\x15I.\xad\x0bo\x8f\xf4\
|
||||
\x97\xab\xe7z\x88\x1f\xdf\xf0\xfa9\x1e\xe0x\x9eG\xbf\x16X\xcd\xb8Ar\xc6\xd5\
|
||||
\x0b4\xd4\xf3\xbcd\x07F_\xc3 \x1e\x0c\xa3Y\x08\x9f\x1f~\xefA\xab\xd9P\x9dN\
|
||||
\x07\x80\xddcI\xc6\x85\xf9\xb4.8\xabhwK\xbd+6\x16\xf5\xdeZ=%F\x00\xa0\xa7\
|
||||
\x0b`@F\xc6\xf6\xd3\xc5&@\x0c"\xa2\xff\x82\x01\x85-\xb7\x9a\re\x00QH\x0c0N\
|
||||
\x06\x1a\x85\xbcym}\x0f\xfe\x92\x19\xdc\xf2~\xdb\xee\xdd\xf7\xf4\xf3_\x0e\
|
||||
\xa2N\xc2\xfa\x01MYp\xbc\xe4a\x0f\xa9\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
def getZoomInBitmap():
|
||||
return BitmapFromImage(getZoomInImage())
|
||||
@@ -1375,11 +1524,20 @@ def getZoomOutData():
|
||||
return \
|
||||
'\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\x00qIDAT8\x8d\xa5\x92Q\x0e\xc0 \x08C-z\xff\x13O\xd9\xd7\x16"\x05\x8d\
|
||||
\xf6O\xa2\x8f"\x05\xa4\x96\x1b5V\xd4\xd1\xd5\x9e!\x15\xdb\x00\x1d]\xe7\x07\
|
||||
\xac\xf6Iv.B*fW\x0e\x90u\xc9 d\x84\x87v\x82\xb4\xf5\x08\'r\x0e\xa2N\x91~\x07\
|
||||
\xd9G\x95\xe2W\xeb\x00\x19\xc4\xd6\\FX\x12\xa3 \xb1:\x05\xacdAG[\xb0y9r`u\
|
||||
\x9d\x83k\xc0\x0b#3@0A\x0c"\x93\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
\x00\x01RIDAT8\x8d\x8d\x93\xbbJ\x03A\x14\x86\xbf\xd9\x04\x93\x90J\x0cj#Dl\
|
||||
\xf4\x01\xec\x05\xdb\xc5\x0b>B\x92]\x1b+\xed,D\xb0\xb4\x08\x9afc|\x04\xc9\
|
||||
\x85\xb4>\x84\x95`\x93\x80`\x15\xd8*\x98\x84\xc0X\xcc\xce\xde7\xf8\xc30\x97=\
|
||||
\xf3\xcd\x7f\xce\xcc\na\xe4\x08\xabQ\xaf\xc9\xf0\xfc\xa5\xf3*X\xa1|b\xa3\xe5\
|
||||
D\x81 W\x81\x840r4\xea5\xf9\xf0\xe40Y@\xf3+\xf8\xb8\xbe\x16\x8c\xdd\x96\x9d\
|
||||
\n1\xf4\xc0\xdf\xdc\xb6\x01\xa8\xca\x19[\x05\xfc\x96%aY\x96\x0c\xdb\xae\xca\
|
||||
\x99\xea7\x8b\x91@w.\xf9x\xbcL\xb8\xf0k\xa0O\x1e{\xd31Q\x1d\xdd\xaaC\xfa\xbd\
|
||||
\xae<=;\xf7!F<\xd7,md\xc4\xf8\x0e\xf6\xaf\x1d\xb6\x8b*p\xa7\x0c\x95\xd0\x86\
|
||||
\xc9\x02\xbe\xa7\xe9\x00\xc34M\xdc\x96MA\xa8[,y\xc8r>h\x00ow6\xa6if;\x98K\
|
||||
\x95\xd6\xef\x12(\xc0t\x99~b8\x7f\xf0\xdeA\xbf\xd7\x95\xc3\xe1\x10\x80\x8b{\
|
||||
\x87R\x1e*\xde\xd55oTq\xf7Fm\x8ew\xd5\xdaa\'\'"\x00P\xd5\x05\xd0 -m\xfb\xf3\
|
||||
\xf9\x04 \x01\x11\xf1\x7fA\x83\xc2\x96\xfb\xbd\xae\xd4\x808$\x01H\x93\x86\
|
||||
\xc6!?\xe6 x\xca\xab\xa4\x0bwp5\xf0\xd7\xdeG\xaa\xff\x97\x83\xb8\x93\xb0\xfe\
|
||||
\x00\xc3\xa8ov\xfd\xe4\x9c\xa2\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getZoomOutBitmap():
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -106,6 +106,8 @@ class ServiceView(wx.EvtHandler):
|
||||
if (self._service.GetEmbeddedWindowLocation() == wx.lib.pydocview.EMBEDDED_WINDOW_BOTTOM):
|
||||
if ServiceView.bottomTab == None:
|
||||
ServiceView.bottomTab = wx.Notebook(frame, wx.NewId(), (0,0), (100,100), wx.LB_DEFAULT, "Bottom Tab")
|
||||
wx.EVT_RIGHT_DOWN(ServiceView.bottomTab, self.OnNotebookRightClick)
|
||||
wx.EVT_MIDDLE_DOWN(ServiceView.bottomTab, self.OnNotebookMiddleClick)
|
||||
sizer.Add(ServiceView.bottomTab, 1, wx.TOP|wx.EXPAND, 4)
|
||||
def OnFrameResize(event):
|
||||
ServiceView.bottomTab.SetSize(ServiceView.bottomTab.GetParent().GetSize())
|
||||
@@ -125,10 +127,46 @@ class ServiceView(wx.EvtHandler):
|
||||
sizer.Add(self._control, 1, wx.EXPAND, 0)
|
||||
frame.SetSizer(sizer)
|
||||
frame.Layout()
|
||||
|
||||
self.Activate()
|
||||
return True
|
||||
|
||||
|
||||
def OnNotebookMiddleClick(self, event):
|
||||
index, type = ServiceView.bottomTab.HitTest(event.GetPosition())
|
||||
# 0 tab is always message. This code assumes the rest are run/debug windows
|
||||
if index > 0:
|
||||
page = ServiceView.bottomTab.GetPage(index)
|
||||
if hasattr(page, 'StopAndRemoveUI'):
|
||||
page.StopAndRemoveUI(event)
|
||||
|
||||
|
||||
def OnNotebookRightClick(self, event):
|
||||
index, type = ServiceView.bottomTab.HitTest(event.GetPosition())
|
||||
menu = wx.Menu()
|
||||
x, y = event.GetX(), event.GetY()
|
||||
# 0 tab is always message. This code assumes the rest are run/debug windows
|
||||
if index > 0:
|
||||
page = ServiceView.bottomTab.GetPage(index)
|
||||
id = wx.NewId()
|
||||
menu.Append(id, _("Close"))
|
||||
def OnRightMenuSelect(event):
|
||||
if hasattr(page, 'StopAndRemoveUI'):
|
||||
page.StopAndRemoveUI(event)
|
||||
wx.EVT_MENU(ServiceView.bottomTab, id, OnRightMenuSelect)
|
||||
if ServiceView.bottomTab.GetPageCount() > 1:
|
||||
id = wx.NewId()
|
||||
menu.Append(id, _("Close All but \"Message\""))
|
||||
def OnRightMenuSelect(event):
|
||||
for i in range(ServiceView.bottomTab.GetPageCount()-1, 0, -1): # Go from len-1 to 1
|
||||
page = ServiceView.bottomTab.GetPage(i)
|
||||
if hasattr(page, 'StopAndRemoveUI'):
|
||||
page.StopAndRemoveUI(event)
|
||||
wx.EVT_MENU(ServiceView.bottomTab, id, OnRightMenuSelect)
|
||||
|
||||
ServiceView.bottomTab.PopupMenu(menu, wx.Point(x, y))
|
||||
menu.Destroy()
|
||||
|
||||
|
||||
def OnCloseWindow(self, event):
|
||||
frame = self.GetFrame()
|
||||
config = wx.ConfigBase_Get()
|
||||
|
||||
@@ -2,29 +2,80 @@
|
||||
# Name: UICommon.py
|
||||
# Purpose: Shared UI stuff
|
||||
#
|
||||
# Author: Matt Fryer
|
||||
# Author: Matt Fryer, Morgan Hua
|
||||
#
|
||||
# Created: 3/10/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import os.path
|
||||
import wx
|
||||
import string
|
||||
import ProjectEditor
|
||||
import activegrid.util as utillib
|
||||
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
|
||||
|
||||
def CreateDirectoryControl( parent, fileLabel, dirLabel, fileExtension, startingName="", startingDirectory=""):
|
||||
def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory:"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False, useDirDialog=False):
|
||||
|
||||
if not choiceDirs:
|
||||
choiceDirs = []
|
||||
projectDirs = []
|
||||
|
||||
if appDirDefaultStartDir:
|
||||
appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT)
|
||||
else:
|
||||
appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY)
|
||||
if appDirectory:
|
||||
choiceDirs.append(appDirectory)
|
||||
if appDirDefaultStartDir and not startingDirectory:
|
||||
startingDirectory = appDirectory
|
||||
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
if projectService:
|
||||
curProjectDoc = projectService.GetCurrentProject()
|
||||
if curProjectDoc:
|
||||
homeDir = curProjectDoc.GetAppDocMgr().homeDir
|
||||
if homeDir and (homeDir not in choiceDirs):
|
||||
choiceDirs.append(homeDir)
|
||||
if not startingDirectory:
|
||||
startingDirectory = homeDir
|
||||
|
||||
for projectDoc in projectService.GetOpenProjects():
|
||||
if projectDoc == curProjectDoc:
|
||||
continue
|
||||
homeDir = projectDoc.GetAppDocMgr().homeDir
|
||||
if homeDir and (homeDir not in projectDirs):
|
||||
projectDirs.append(homeDir)
|
||||
projectDirs.sort(CaseInsensitiveCompare)
|
||||
for projectDir in projectDirs:
|
||||
if projectDir not in choiceDirs:
|
||||
choiceDirs.append(projectDir)
|
||||
|
||||
if startingDirectory and (startingDirectory not in choiceDirs):
|
||||
choiceDirs.insert(0, startingDirectory)
|
||||
|
||||
if os.getcwd() not in choiceDirs:
|
||||
choiceDirs.append(os.getcwd())
|
||||
if appdirs.getSystemDir() not in choiceDirs:
|
||||
choiceDirs.append(appdirs.getSystemDir())
|
||||
|
||||
if not startingDirectory:
|
||||
startingDirectory = os.getcwd()
|
||||
|
||||
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
|
||||
nameLabelText = wx.StaticText(parent, -1, fileLabel)
|
||||
dirLabelText = wx.StaticText(parent, -1, dirLabel)
|
||||
dirControl = wx.TextCtrl(parent, -1, startingDirectory, size=(-1,-1))
|
||||
dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs)
|
||||
dirControl.SetToolTipString(startingDirectory)
|
||||
button = wx.Button(parent, -1, _("Browse..."), size=(60,-1))
|
||||
button = wx.Button(parent, -1, _("Browse..."))
|
||||
allControls = [nameControl, nameLabelText, dirLabelText, dirControl, button]
|
||||
|
||||
def OnFindDirClick(event):
|
||||
name = ""
|
||||
@@ -35,54 +86,279 @@ def CreateDirectoryControl( parent, fileLabel, dirLabel, fileExtension, starting
|
||||
name = nameCtrlValue
|
||||
else:
|
||||
name = _("%s.%s") % (nameCtrlValue, fileExtension)
|
||||
path = wx.FileSelector(_("Choose a filename and directory"),
|
||||
"",
|
||||
"%s" % name,
|
||||
wildcard=_("*.%s") % fileExtension ,
|
||||
flags=wx.SAVE,
|
||||
parent=parent)
|
||||
|
||||
|
||||
if not useDirDialog:
|
||||
dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
|
||||
defaultDir = dirControl.GetValue().strip(),
|
||||
defaultFile = name,
|
||||
wildcard= "*.%s" % fileExtension,
|
||||
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:
|
||||
dlg.Destroy()
|
||||
return
|
||||
path = dlg.GetPath()
|
||||
dlg.Destroy()
|
||||
|
||||
if path:
|
||||
dir, filename = os.path.split(path)
|
||||
dirControl.SetValue(dir)
|
||||
dirControl.SetToolTipString(dir)
|
||||
nameControl.SetValue(filename)
|
||||
if not useDirDialog:
|
||||
dir, filename = os.path.split(path)
|
||||
if dirControl.FindString(dir) == wx.NOT_FOUND:
|
||||
dirControl.Insert(dir, 0)
|
||||
dirControl.SetValue(dir)
|
||||
dirControl.SetToolTipString(dir)
|
||||
nameControl.SetValue(filename)
|
||||
else:
|
||||
dirControl.SetValue(path)
|
||||
dirControl.SetToolTipString(path)
|
||||
|
||||
parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
|
||||
|
||||
def Validate(allowOverwriteOnPrompt=False):
|
||||
if nameControl.GetValue() == "":
|
||||
wx.MessageBox(_("Please provide a filename."), _("Provide a Filename"))
|
||||
def Validate(allowOverwriteOnPrompt=False, infoString='', validClassName=False, ignoreFileConflicts=False):
|
||||
projName = nameControl.GetValue().strip()
|
||||
if projName == "":
|
||||
wx.MessageBox(_("Please provide a %sfile name.") % infoString, _("Provide a File Name"))
|
||||
return False
|
||||
if nameControl.GetValue().find(' ') != -1:
|
||||
wx.MessageBox(_("Please provide a filename that does not contains spaces."), _("Spaces in Filename"))
|
||||
if projName.find(' ') != -1:
|
||||
wx.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString, _("Spaces in File Name"))
|
||||
return False
|
||||
if not os.path.exists(dirControl.GetValue()):
|
||||
wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
|
||||
if validClassName:
|
||||
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
|
||||
|
||||
filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(nameControl.GetValue(), "." + fileExtension))
|
||||
if os.path.exists(filePath):
|
||||
if allowOverwriteOnPrompt:
|
||||
res = wx.MessageBox(_("That file already exists. Would you like to overwrite it."), "File Exists", style=wx.YES_NO|wx.NO_DEFAULT)
|
||||
return (res == wx.YES)
|
||||
else:
|
||||
wx.MessageBox(_("That file already exists. Please choose a different name."), "File Exists")
|
||||
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):
|
||||
wx.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString, _("Provide a Valid Directory"))
|
||||
return False
|
||||
if not ignoreFileConflicts:
|
||||
filePath = os.path.join(dirName, MakeNameEndInExtension(projName, "." + fileExtension))
|
||||
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
|
||||
HALF_SPACE = 5
|
||||
flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
|
||||
flexGridSizer.AddGrowableCol(1,1)
|
||||
flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, HALF_SPACE)
|
||||
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
|
||||
if not useDirDialog:
|
||||
flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
|
||||
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)
|
||||
|
||||
if returnAll:
|
||||
return nameControl, dirControl, flexGridSizer, Validate, allControls
|
||||
else:
|
||||
return nameControl, dirControl, flexGridSizer, Validate
|
||||
|
||||
|
||||
def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False):
|
||||
|
||||
if not choiceDirs:
|
||||
choiceDirs = []
|
||||
projectDirs = []
|
||||
|
||||
if appDirDefaultStartDir:
|
||||
appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT)
|
||||
else:
|
||||
appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY)
|
||||
if appDirectory:
|
||||
choiceDirs.append(appDirectory)
|
||||
if appDirDefaultStartDir and not startingDirectory:
|
||||
startingDirectory = appDirectory
|
||||
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
if projectService:
|
||||
curProjectDoc = projectService.GetCurrentProject()
|
||||
if curProjectDoc:
|
||||
homeDir = curProjectDoc.GetAppDocMgr().homeDir
|
||||
if homeDir and (homeDir not in choiceDirs):
|
||||
choiceDirs.append(homeDir)
|
||||
if not startingDirectory:
|
||||
startingDirectory = homeDir
|
||||
|
||||
for projectDoc in projectService.GetOpenProjects():
|
||||
if projectDoc == curProjectDoc:
|
||||
continue
|
||||
homeDir = projectDoc.GetAppDocMgr().homeDir
|
||||
if homeDir and (homeDir not in projectDirs):
|
||||
projectDirs.append(homeDir)
|
||||
projectDirs.sort(CaseInsensitiveCompare)
|
||||
for projectDir in projectDirs:
|
||||
if projectDir not in choiceDirs:
|
||||
choiceDirs.append(projectDir)
|
||||
|
||||
if startingDirectory and (startingDirectory not in choiceDirs):
|
||||
choiceDirs.insert(0, startingDirectory)
|
||||
|
||||
if os.getcwd() not in choiceDirs:
|
||||
choiceDirs.append(os.getcwd())
|
||||
if appdirs.getSystemDir() not in choiceDirs:
|
||||
choiceDirs.append(appdirs.getSystemDir())
|
||||
|
||||
|
||||
if not startingDirectory:
|
||||
startingDirectory = os.getcwd()
|
||||
|
||||
dirLabelText = wx.StaticText(parent, -1, dirLabel)
|
||||
dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs)
|
||||
dirControl.SetToolTipString(startingDirectory)
|
||||
button = wx.Button(parent, -1, _("Browse..."))
|
||||
|
||||
def OnFindDirClick(event):
|
||||
dlg = wx.DirDialog(wx.GetApp().GetTopWindow(),
|
||||
_("Choose a directory:"),
|
||||
defaultPath=dirControl.GetValue().strip(),
|
||||
style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
|
||||
dlg.CenterOnParent()
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
dir = dlg.GetPath()
|
||||
if dirControl.FindString(dir) == wx.NOT_FOUND:
|
||||
dirControl.Insert(dir, 0)
|
||||
dirControl.SetValue(dir)
|
||||
dirControl.SetToolTipString(dir)
|
||||
dlg.Destroy()
|
||||
|
||||
parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
|
||||
|
||||
def Validate(allowOverwriteOnPrompt=False):
|
||||
dirName = dirControl.GetValue().strip()
|
||||
if dirName == "":
|
||||
wx.MessageBox(_("Please provide a directory."), _("Provide a Directory"))
|
||||
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):
|
||||
wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
|
||||
return False
|
||||
return True
|
||||
|
||||
HALF_SPACE = 5
|
||||
flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
|
||||
flexGridSizer.AddGrowableCol(1,1)
|
||||
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.RIGHT, border=HALF_SPACE)
|
||||
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
|
||||
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
|
||||
|
||||
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, border=HALF_SPACE)
|
||||
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
|
||||
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
|
||||
return nameControl, dirControl, flexGridSizer, Validate
|
||||
return dirControl, flexGridSizer, Validate
|
||||
|
||||
def AddFilesToCurrentProject(paths, save=False):
|
||||
|
||||
def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectoryControl=None):
|
||||
|
||||
fileLabelText = wx.StaticText(parent, -1, fileLabel)
|
||||
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
|
||||
|
||||
def Validate(allowOverwriteOnPrompt=False, validClassName=False):
|
||||
projName = nameControl.GetValue().strip()
|
||||
if projName == "":
|
||||
wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name"))
|
||||
return False
|
||||
if projName.find(' ') != -1:
|
||||
wx.MessageBox(_("Spaces in name. Name cannot have spaces."), _("Project Name"))
|
||||
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)
|
||||
if os.path.exists(path):
|
||||
if os.path.isdir(path):
|
||||
message = _("Project '%s' already exists. Would you like to overwrite the contents of the project?") % projName
|
||||
else: # os.path.isfile(path):
|
||||
message = _("'%s' already exists as a file. Would you like to replace it with the project?") % nameControl.GetValue().strip()
|
||||
|
||||
yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
|
||||
message,
|
||||
_("Project Directory Exists"),
|
||||
wx.YES_NO|wx.ICON_QUESTION
|
||||
)
|
||||
yesNoMsg.CenterOnParent()
|
||||
status = yesNoMsg.ShowModal()
|
||||
yesNoMsg.Destroy()
|
||||
if status == wx.ID_NO:
|
||||
return False
|
||||
return True
|
||||
|
||||
HALF_SPACE = 5
|
||||
flexGridSizer = wx.FlexGridSizer(cols = 2, vgap = HALF_SPACE, hgap = HALF_SPACE)
|
||||
flexGridSizer.AddGrowableCol(1,1)
|
||||
flexGridSizer.Add(fileLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, border=HALF_SPACE)
|
||||
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
|
||||
|
||||
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():
|
||||
projectDocument = None
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
if projectService:
|
||||
projectDocument = projectService.GetCurrentProject()
|
||||
return projectDocument
|
||||
|
||||
def AddFilesToCurrentProject(paths, folderPath=None, types=None, names=None, save=False):
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
if projectService:
|
||||
projectDocument = projectService.GetCurrentProject()
|
||||
@@ -92,11 +368,22 @@ def AddFilesToCurrentProject(paths, save=False):
|
||||
if path in files:
|
||||
paths.remove(path)
|
||||
if paths:
|
||||
projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths))
|
||||
projectDocument.GetFirstView().DoSelectFiles([paths[0]])
|
||||
projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, folderPath=folderPath, types=types, names=names))
|
||||
if save:
|
||||
projectDocument.OnSaveDocument(projectDocument.GetFilename())
|
||||
|
||||
def AddFilesToProject(projectDocument, paths, types=None, names=None, save=False):
|
||||
if projectDocument:
|
||||
files = projectDocument.GetFiles()
|
||||
for path in paths:
|
||||
if path in files:
|
||||
paths.remove(path)
|
||||
if paths:
|
||||
projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, types=types, names=names))
|
||||
if save:
|
||||
projectDocument.OnSaveDocument(projectDocument.GetFilename())
|
||||
|
||||
|
||||
def MakeNameEndInExtension(name, extension):
|
||||
if not name:
|
||||
return name
|
||||
@@ -106,23 +393,343 @@ def MakeNameEndInExtension(name, extension):
|
||||
else:
|
||||
return name + extension
|
||||
|
||||
# Lame
|
||||
def PluralName(name):
|
||||
if not name:
|
||||
return name
|
||||
if name.endswith('us'):
|
||||
return name[0:-2] + 'ii'
|
||||
elif name.endswith('s'):
|
||||
return name
|
||||
elif name.endswith('y'):
|
||||
return name[0:-1] + 'ies'
|
||||
else:
|
||||
return name + 's'
|
||||
|
||||
|
||||
def GetPythonExecPath():
|
||||
pythonExecPath = wx.ConfigBase_Get().Read("ActiveGridPythonLocation")
|
||||
if not pythonExecPath:
|
||||
pythonExecPath = utillib.pythonExecPath
|
||||
pythonExecPath = sysutils.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):
|
||||
if path == skipFile:
|
||||
skipped = True
|
||||
elif os.path.isdir(path):
|
||||
for file in os.listdir(path):
|
||||
file_or_dir = os.path.join(path,file)
|
||||
if skipFile == file_or_dir:
|
||||
skipped = True
|
||||
elif os.path.isdir(file_or_dir) and not os.path.islink(file_or_dir):
|
||||
if _DoRemoveRecursive(file_or_dir, skipFile): # it's a directory recursive call to function again
|
||||
skipped = True
|
||||
else:
|
||||
os.remove(file_or_dir) # it's a file, delete it
|
||||
if not skipped:
|
||||
os.rmdir(path) # delete the directory here
|
||||
else:
|
||||
os.remove(path)
|
||||
|
||||
return skipped
|
||||
|
||||
|
||||
def RemoveRecursive(path, skipFile=None):
|
||||
_DoRemoveRecursive(path, skipFile)
|
||||
|
||||
|
||||
def CaseInsensitiveCompare(s1, s2):
|
||||
""" Method used by sort() to sort values in case insensitive order """
|
||||
return strutils.caseInsensitiveCompare(s1, s2)
|
||||
|
||||
|
||||
def GetAnnotation(model, elementName):
|
||||
""" Get an object's annotation used for tooltips """
|
||||
if hasattr(model, "_complexType"):
|
||||
ct = model._complexType
|
||||
elif hasattr(model, "__xsdcomplextype__"):
|
||||
ct = model.__xsdcomplextype__
|
||||
else:
|
||||
ct = None
|
||||
|
||||
if ct:
|
||||
el = ct.findElement(elementName)
|
||||
if el and el.annotation:
|
||||
return el.annotation
|
||||
|
||||
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
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def GetProjectForDoc(doc):
|
||||
""" Given a document find which project it belongs to.
|
||||
Tries to intelligently resolve conflicts if it is in more than one open project.
|
||||
"""
|
||||
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
|
||||
|
||||
projectDoc = projectService.FindProjectFromMapping(doc)
|
||||
if projectDoc:
|
||||
return projectDoc
|
||||
|
||||
projectDoc = projectService.GetCurrentProject()
|
||||
if not projectDoc:
|
||||
return None
|
||||
if projectDoc.IsFileInProject(doc.GetFilename()):
|
||||
return projectDoc
|
||||
|
||||
projects = []
|
||||
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
|
||||
for openDoc in openDocs:
|
||||
if openDoc == projectDoc:
|
||||
continue
|
||||
if(isinstance(openDoc, ProjectEditor.ProjectDocument)):
|
||||
if openDoc.IsFileInProject(doc.GetFilename()):
|
||||
projects.append(openDoc)
|
||||
|
||||
if projects:
|
||||
if len(projects) == 1:
|
||||
return projects[0]
|
||||
else:
|
||||
choices = [os.path.basename(project.GetFilename()) for project in projects]
|
||||
dlg = wx.SingleChoiceDialog(wx.GetApp().GetTopWindow(), _("'%s' found in more than one project.\nWhich project should be used for this operation?") % os.path.basename(doc.GetFilename()), _("Select Project"), choices, wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE)
|
||||
dlg.CenterOnParent()
|
||||
projectDoc = None
|
||||
if dlg.ShowModal() == wx.ID_OK:
|
||||
i = dlg.GetSelection()
|
||||
projectDoc = projects[i]
|
||||
dlg.Destroy()
|
||||
return projectDoc
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def GetAppInfoForDoc(doc):
|
||||
""" Get the AppInfo for a given document """
|
||||
projectDoc = GetProjectForDoc(doc)
|
||||
if projectDoc:
|
||||
return projectDoc.GetAppInfo()
|
||||
return None
|
||||
|
||||
|
||||
def GetAppDocMgrForDoc(doc):
|
||||
""" Get the AppDocMgr for a given document """
|
||||
projectDoc = GetProjectForDoc(doc)
|
||||
if projectDoc:
|
||||
return projectDoc.GetModel()
|
||||
return None
|
||||
|
||||
|
||||
def GetAppInfoLanguage(doc=None):
|
||||
from activegrid.server.projectmodel import LANGUAGE_DEFAULT
|
||||
|
||||
if doc:
|
||||
language = doc.GetAppInfo().language
|
||||
else:
|
||||
language = None
|
||||
|
||||
if not language:
|
||||
config = wx.ConfigBase_Get()
|
||||
language = config.Read(ProjectEditor.APP_LAST_LANGUAGE, LANGUAGE_DEFAULT)
|
||||
|
||||
if doc:
|
||||
doc.GetAppInfo().language = language # once it is selected, it must be set.
|
||||
|
||||
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):
|
||||
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):
|
||||
@@ -109,13 +109,17 @@ class XmlCtrl(CodeEditor.CodeCtrl):
|
||||
# Tag
|
||||
self.StyleSetSpec(wx.stc.STC_H_TAG, "face:%(font)s,fore:#00007F,bold,size:%(size)d" % faces)
|
||||
# Attributes
|
||||
self.StyleSetSpec(wx.stc.STC_H_ATTRIBUTE, "face:%(font)s,fore:#00007F,bold,size:%(size)d" % faces)
|
||||
self.StyleSetSpec(wx.stc.STC_H_ATTRIBUTE, "face:%(font)s,fore:#007F7F,bold,size:%(size)d" % faces)
|
||||
|
||||
|
||||
class XmlOptionsPanel(STCTextEditor.TextOptionsPanel):
|
||||
|
||||
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):
|
||||
return getXMLIcon()
|
||||
|
||||
|
||||
XMLKEYWORDS = [
|
||||
@@ -124,7 +128,6 @@ XMLKEYWORDS = [
|
||||
"xs:complexType", "xs:element", "xs:enumeration", "xs:field", "xs:key", "xs:keyref", "xs:schema", "xs:selector"
|
||||
]
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Icon Bitmaps - generated by encode_bitmaps.py
|
||||
#----------------------------------------------------------------------------
|
||||
@@ -136,19 +139,17 @@ def getXMLData():
|
||||
return \
|
||||
'\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\x01\x1aIDAT8\x8d\xed\x92?N\xc3P\x0c\xc6\x7fv\xf2\x924\xa8E*7\xe1\n\xbd\
|
||||
\x01G\xa8\xd8\x989\x05S/\xd0\x0110\xf4$\xa0J\xdd\x18\x18XY\x82\xa0\xad\xd2\
|
||||
\xfc\xe9{f\x08-\x02\xc1\xd4\x85\x01/\xb6l\xd9\xdf\xf7\xd9\x16\xd1\x88CL\x0f\
|
||||
\xea\xfe\x13\x03\xc4\xae\xcf\x8d\xb6\x84\xba\x84m\x83e\x03\xa8\x96\x88F`\x86\
|
||||
\xf5\x06\xc8\xba\x80\xf4\x08\xda\x1a\xf2cB04q\xcc\xe7\x0bb\xbb\xbf\x85\xd75\
|
||||
\xf2\xb1K\xc9\x12\xa8\x9aO\x84o\x88\xb6\x0bbxx\x04\xc5e\xe0:%\xe5\xd4\xa0j:\
|
||||
\x0f\xd4\x93\x82\xcd\xe9\x19\xf5\xa4\xd8\xd7\x97\xe2\x904\x82D\x89bA\xa5\xad\
|
||||
!\x85\xb0\x82|,\x94S#\x1fw\xb8\xbe?\xc4\x8d.\xf0\xfd\xe1\x9e\x81\x7fk\x91\
|
||||
\xd6\x83\x05\xcc\x0c\xf5\xea\xf0U@\xfb\xec\x9bw\x0c\x00\xe2\xab\xd1\x17\t\
|
||||
\xd9\xcc \x80o\xc1D\x11\xbb<1^\n\xf0\xbf\xacy\x03\xf4~\xc8g0{R\xe2\x9b\xc5\
|
||||
\x8aM\x03\xd4\xe0=\xb8\xb4;\x88\xc6 \nQ\x1e\xe1W\x1e\x89\xc1W\xe0\xb7\xa0=Hr\
|
||||
\xb8{\x0e\xc8\xff+\x1f>\xe0\x1d~\xafr\x13\x04HY"\x00\x00\x00\x00IEND\xaeB`\
|
||||
\x82'
|
||||
\x00\x01\x08IDAT8\x8dc\xdc{\xf6\xde\x7f\x064p\xfb\xd1K\x06\x06\x06\x06\x86\
|
||||
\xd7o\xbf2\xd4\xa5\xb93\xa2\xcb\xa3\x80\xbdg\xef\xfd\xbf\xff\xed?\x1c_\xf9\
|
||||
\x04\xc13\xd6\x1f\xff\xbf\xeb\xf9\xff\xff\xcds\xf6\xfcgdbf\xc0\x85\x99\xb0\
|
||||
\x19\xfa\xe5\x17\x82m\xee\xed\xcc\x90Z\xb7\x08\xc3\x950\xc0\x82\xcc\xf9\xfa\
|
||||
\x07\xc1~\xfd\xf6+\xc3\xeb\xad{\x19\x1e?y\x89\xd7\x07,\xe8\x1aa\xb6\x9b{;300\
|
||||
00(\xfdb`88\x7f\x19N\x03\x98`\x01\x86\xac\xf9\xd3o\xa8+\xa0\xfc\x07\x0f\x1e\
|
||||
\xe3w\x01\xb2\x9f\xd15\xbf\xfa\x8e\xd7\x07\x0cL\xaf\xdf~%[3\xdc\x050\x8d\xa4\
|
||||
jf````LkX\xfa\x7f\x8a\xcdi\xe2T\xe3r\x01\x03\x03\x03\xc3\xa7#\x13H\xd6|\xea1\
|
||||
\x03jB\x12\xae\xffO\x14\x8d\x0cP\x0cx\xdb\xc8\xc8 \\\xff\x9f\xe1m#"\xf9c\xd3\
|
||||
\x84b\xc0\xec\xa68\xb8j\x98fdM\xc8\x86\xc1\xd4 \xcb32213\xfc\xdc\x95\xfb\x9f\
|
||||
\xdc0`A\xe6\x90\x03\x00\x11\x95\x8b;4e.A\x00\x00\x00\x00IEND\xaeB`\x82'
|
||||
|
||||
|
||||
def getXMLBitmap():
|
||||
|
||||
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.
|
||||
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.
|
||||
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 '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:
|
||||
uenv = {}
|
||||
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
|
||||
hProcess, hThread, processId, threadId\
|
||||
= win32process.CreateProcess(appName, cmd, processSA,
|
||||
|
||||
614
wxPython/samples/ide/activegrid/tool/project.py
Normal file
614
wxPython/samples/ide/activegrid/tool/project.py
Normal file
@@ -0,0 +1,614 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: project.py
|
||||
# Purpose: project model for wx.lib.pydocview
|
||||
#
|
||||
# Author: Morgan Hua
|
||||
#
|
||||
# Created: 8/25/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import copy
|
||||
import os
|
||||
import os.path
|
||||
import activegrid.util.xmlutils as xmlutils
|
||||
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:
|
||||
import activegrid.model.basedocmgr as basedocmgr
|
||||
import AppInfo
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Constants
|
||||
#----------------------------------------------------------------------------
|
||||
# Always add new versions, never edit the version number
|
||||
# This allows you to upgrade the file by checking the version number
|
||||
PROJECT_VERSION_050730 = '10'
|
||||
PROJECT_VERSION_050826 = '11'
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class BaseProject(object):
|
||||
|
||||
__xmlname__ = "project"
|
||||
__xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback', '_cacheEnabled')
|
||||
__xmlattributes__ = ("_homeDir", "version")
|
||||
__xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" }
|
||||
__xmlflattensequence__ = { "_files":("file",) }
|
||||
__xmldefaultnamespace__ = xmlutils.AG_NS_URL
|
||||
__xmlattrnamespaces__ = { "ag": ["version", "_homeDir"] }
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.__xmlnamespaces__ = { "ag" : xmlutils.AG_NS_URL }
|
||||
self.version = PROJECT_VERSION_050826
|
||||
self._files = []
|
||||
self._projectDir = None # default for homeDir, set on load
|
||||
self._homeDir = None # user set homeDir for use in calculating relative path
|
||||
self._cacheEnabled = 0
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
self._appInfo = AppInfo.AppInfo()
|
||||
|
||||
|
||||
def initialize(self):
|
||||
for file in self._files:
|
||||
file._parentProj = self
|
||||
|
||||
|
||||
def __copy__(self):
|
||||
clone = Project()
|
||||
clone._files = [copy.copy(file) for file in self._files]
|
||||
clone._projectDir = self._projectDir
|
||||
clone._homeDir = self._homeDir
|
||||
if not ACTIVEGRID_BASE_IDE:
|
||||
clone._appInfo = copy.copy(self._appInfo)
|
||||
return clone
|
||||
|
||||
|
||||
def GetAppInfo(self):
|
||||
return self._appInfo
|
||||
|
||||
|
||||
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
|
||||
self.AddFile(file=xyzFile) # normally used for redo/undo
|
||||
Add newly created file object using filePath and logicalFolder or given file object
|
||||
"""
|
||||
if file:
|
||||
self._files.append(file)
|
||||
else:
|
||||
self._files.append(ProjectFile(self, filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
|
||||
|
||||
|
||||
def RemoveFile(self, file):
|
||||
self._files.remove(file)
|
||||
|
||||
|
||||
def FindFile(self, filePath):
|
||||
if filePath:
|
||||
for file in self._files:
|
||||
if file.filePath == filePath:
|
||||
return file
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _GetFilePaths(self):
|
||||
return [file.filePath for file in self._files]
|
||||
|
||||
|
||||
filePaths = property(_GetFilePaths)
|
||||
|
||||
def _GetProjectFiles(self):
|
||||
return self._files
|
||||
projectFiles = property(_GetProjectFiles)
|
||||
|
||||
|
||||
def _GetLogicalFolders(self):
|
||||
folders = []
|
||||
for file in self._files:
|
||||
if file.logicalFolder and file.logicalFolder not in folders:
|
||||
folders.append(file.logicalFolder)
|
||||
return folders
|
||||
|
||||
|
||||
logicalFolders = property(_GetLogicalFolders)
|
||||
|
||||
|
||||
def _GetPhysicalFolders(self):
|
||||
physicalFolders = []
|
||||
for file in self._files:
|
||||
physicalFolder = file.physicalFolder
|
||||
if physicalFolder and physicalFolder not in physicalFolders:
|
||||
physicalFolders.append(physicalFolder)
|
||||
return physicalFolders
|
||||
|
||||
|
||||
physicalFolders = property(_GetPhysicalFolders)
|
||||
|
||||
|
||||
def _GetHomeDir(self):
|
||||
if self._homeDir:
|
||||
return self._homeDir
|
||||
else:
|
||||
return self._projectDir
|
||||
|
||||
|
||||
def _SetHomeDir(self, parentPath):
|
||||
self._homeDir = parentPath
|
||||
|
||||
|
||||
def _IsDefaultHomeDir(self):
|
||||
return (self._homeDir == None)
|
||||
|
||||
|
||||
isDefaultHomeDir = property(_IsDefaultHomeDir)
|
||||
|
||||
|
||||
homeDir = property(_GetHomeDir, _SetHomeDir)
|
||||
|
||||
|
||||
def GetRelativeFolders(self):
|
||||
relativeFolders = []
|
||||
for file in self._files:
|
||||
relFolder = file.GetRelativeFolder(self.homeDir)
|
||||
if relFolder and relFolder not in relativeFolders:
|
||||
relativeFolders.append(relFolder)
|
||||
return relativeFolders
|
||||
|
||||
|
||||
def AbsToRelativePath(self):
|
||||
for file in self._files:
|
||||
file.AbsToRelativePath(self.homeDir)
|
||||
|
||||
|
||||
def RelativeToAbsPath(self):
|
||||
for file in self._files:
|
||||
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
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def fullPath(self, fileName):
|
||||
fileName = super(BaseProject, self).fullPath(fileName)
|
||||
|
||||
if os.path.isabs(fileName):
|
||||
absPath = fileName
|
||||
elif self.homeDir:
|
||||
absPath = os.path.join(self.homeDir, fileName)
|
||||
else:
|
||||
absPath = os.path.abspath(fileName)
|
||||
return os.path.normpath(absPath)
|
||||
|
||||
|
||||
def documentRefFactory(self, name, fileType, filePath):
|
||||
return ProjectFile(self, filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
|
||||
|
||||
|
||||
def findAllRefs(self):
|
||||
return self._files
|
||||
|
||||
|
||||
def GetXFormsDirectory(self):
|
||||
forms = self.findRefsByFileType(basedocmgr.FILE_TYPE_XFORM)
|
||||
filePaths = map(lambda form: form.filePath, forms)
|
||||
xformdir = os.path.commonprefix(filePaths)
|
||||
if not xformdir:
|
||||
xformdir = self.homeDir
|
||||
return xformdir
|
||||
|
||||
|
||||
def setRefs(self, files):
|
||||
self._files = files
|
||||
|
||||
|
||||
def findRefsByFileType(self, fileType):
|
||||
fileList = []
|
||||
for file in self._files:
|
||||
if fileType == file.type:
|
||||
fileList.append(file)
|
||||
return fileList
|
||||
|
||||
|
||||
def GenerateServiceRefPath(self, wsdlFilePath):
|
||||
# HACK: temporary solution to getting wsdlag path from wsdl path.
|
||||
import wx
|
||||
from WsdlAgEditor import WsdlAgDocument
|
||||
ext = WsdlAgDocument.WSDL_AG_EXT
|
||||
for template in wx.GetApp().GetDocumentManager().GetTemplates():
|
||||
if template.GetDocumentType() == WsdlAgDocument:
|
||||
ext = template.GetDefaultExtension()
|
||||
break;
|
||||
wsdlAgFilePath = os.path.splitext(wsdlFilePath)[0] + ext
|
||||
return wsdlAgFilePath
|
||||
|
||||
|
||||
def SetDocCallback(self, getDocCallback):
|
||||
self._getDocCallback = getDocCallback
|
||||
for file in self._files:
|
||||
file._getDocCallback = getDocCallback
|
||||
|
||||
|
||||
if ACTIVEGRID_BASE_IDE:
|
||||
class Project(BaseProject):
|
||||
pass
|
||||
else:
|
||||
class Project(BaseProject, basedocmgr.BaseDocumentMgr):
|
||||
pass
|
||||
|
||||
|
||||
class ProjectFile(object):
|
||||
__xmlname__ = "file"
|
||||
__xmlexclude__ = ('_parentProj', '_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
|
||||
__xmlattributes__ = ["filePath", "logicalFolder", "type", "name"]
|
||||
__xmldefaultnamespace__ = xmlutils.AG_NS_URL
|
||||
|
||||
|
||||
def __init__(self, parent=None, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
|
||||
self._parentProj = parent
|
||||
self.filePath = filePath
|
||||
self.logicalFolder = logicalFolder
|
||||
self.type = type
|
||||
self.name = name
|
||||
self._getDocCallback = getDocCallback
|
||||
self._docCallbackCacheReturnValue = None
|
||||
self._docModelCallbackCacheReturnValue = None
|
||||
self._doc = None
|
||||
|
||||
|
||||
def _GetDocumentModel(self):
|
||||
if (self._docCallbackCacheReturnValue
|
||||
and (self._parentProj.cacheEnabled or self._docCallbackCacheReturnValue.IsDocumentModificationDateCorrect())):
|
||||
return self._docModelCallbackCacheReturnValue
|
||||
|
||||
if self._getDocCallback:
|
||||
self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
|
||||
return self._docModelCallbackCacheReturnValue
|
||||
|
||||
return None
|
||||
|
||||
|
||||
document = property(_GetDocumentModel)
|
||||
|
||||
|
||||
def _GetDocument(self):
|
||||
# Return the IDE document wrapper that corresponds to the runtime document model
|
||||
if (self._docCallbackCacheReturnValue
|
||||
and (self._parentProj.cacheEnabled or self._docCallbackCacheReturnValue.IsDocumentModificationDateCorrect())):
|
||||
return self._docCallbackCacheReturnValue
|
||||
|
||||
if self._getDocCallback:
|
||||
self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
|
||||
return self._docCallbackCacheReturnValue
|
||||
|
||||
return None
|
||||
|
||||
|
||||
ideDocument = property(_GetDocument)
|
||||
|
||||
|
||||
def ClearCache(self):
|
||||
self._docCallbackCacheReturnValue = None
|
||||
self._docModelCallbackCacheReturnValue = None
|
||||
|
||||
|
||||
def _typeEnumeration(self):
|
||||
return basedocmgr.FILE_TYPE_LIST
|
||||
|
||||
|
||||
def _GetPhysicalFolder(self):
|
||||
dir = None
|
||||
if self.filePath:
|
||||
dir = os.path.dirname(self.filePath)
|
||||
if os.sep != '/':
|
||||
dir = dir.replace(os.sep, '/') # require '/' as delimiter
|
||||
return dir
|
||||
|
||||
|
||||
physicalFolder = property(_GetPhysicalFolder)
|
||||
|
||||
|
||||
def GetRelativeFolder(self, parentPath):
|
||||
parentPathLen = len(parentPath)
|
||||
|
||||
dir = None
|
||||
if self.filePath:
|
||||
dir = os.path.dirname(self.filePath)
|
||||
if dir.startswith(parentPath + os.sep):
|
||||
dir = "." + dir[parentPathLen:] # convert to relative path
|
||||
if os.sep != '/':
|
||||
dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
||||
return dir
|
||||
|
||||
|
||||
def AbsToRelativePath(self, parentPath):
|
||||
""" Used to convert path to relative path for saving (disk format) """
|
||||
parentPathLen = len(parentPath)
|
||||
|
||||
if self.filePath.startswith(parentPath + os.sep):
|
||||
self.filePath = "." + self.filePath[parentPathLen:] # convert to relative path
|
||||
if os.sep != '/':
|
||||
self.filePath = self.filePath.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
|
||||
else:
|
||||
pass # not a decendant of project, use absolute path
|
||||
|
||||
|
||||
def RelativeToAbsPath(self, parentPath):
|
||||
""" Used to convert path to absolute path (for any necessary disk access) """
|
||||
if self.filePath.startswith("./"): # relative to project file
|
||||
self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath)) # also converts '/' to os.sep
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# BaseDocumentMgr methods
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
def _GetDoc(self):
|
||||
# HACK: temporary solution.
|
||||
import wx
|
||||
import wx.lib.docview
|
||||
if not self._doc:
|
||||
docMgr = wx.GetApp().GetDocumentManager()
|
||||
|
||||
try:
|
||||
doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW)
|
||||
if (doc == None): # already open
|
||||
docs = docMgr.GetDocuments()
|
||||
for d in docs:
|
||||
if d.GetFilename() == self.filePath:
|
||||
doc = d
|
||||
break
|
||||
self._doc = doc
|
||||
except Exception,e:
|
||||
aglogging.reportException(e, stacktrace=True)
|
||||
|
||||
return self._doc
|
||||
|
||||
|
||||
def _GetLocalServiceProcessName(self):
|
||||
# HACK: temporary solution to getting process name from wsdlag file.
|
||||
doc = self._GetDoc()
|
||||
if doc:
|
||||
return doc.GetModel().processName
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
processName = property(_GetLocalServiceProcessName)
|
||||
|
||||
|
||||
def _GetStateful(self):
|
||||
# HACK: temporary solution to getting stateful from wsdlag file.
|
||||
return self._GetDoc().GetModel().stateful
|
||||
|
||||
|
||||
def _SetStateful(self, stateful):
|
||||
# HACK: temporary solution to setting stateful from wsdlag file.
|
||||
self._GetDoc().GetModel().stateful = stateful
|
||||
|
||||
|
||||
stateful = property(_GetStateful, _SetStateful)
|
||||
|
||||
|
||||
def _GetLocalServiceCodeFile(self):
|
||||
# HACK: temporary solution to getting class name from wsdlag file.
|
||||
return self._GetDoc().GetModel().localServiceCodeFile
|
||||
|
||||
|
||||
def _SetLocalServiceCodeFile(self, codefile):
|
||||
# HACK: temporary solution to setting class name from wsdlag file.
|
||||
self._GetDoc().GetModel().localServiceCodeFile = codefile
|
||||
|
||||
|
||||
localServiceCodeFile = property(_GetLocalServiceCodeFile, _SetLocalServiceCodeFile)
|
||||
|
||||
|
||||
def _GetLocalServiceClassName(self):
|
||||
# HACK: temporary solution to getting class name from wsdlag file.
|
||||
return self._GetDoc().GetModel().localServiceClassName
|
||||
|
||||
|
||||
def _SetLocalServiceClassName(self, className):
|
||||
# HACK: temporary solution to setting class name from wsdlag file.
|
||||
self._GetDoc().GetModel().localServiceClassName = className
|
||||
|
||||
|
||||
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
|
||||
## def _GetRssServiceBaseURL(self):
|
||||
## return self._GetDoc().GetModel().rssServiceBaseURL
|
||||
##
|
||||
##
|
||||
## def _SetRssServiceBaseURL(self, baseURL):
|
||||
## self._GetDoc().GetModel().rssServiceBaseURL = baseURL
|
||||
##
|
||||
##
|
||||
## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL)
|
||||
##
|
||||
##
|
||||
## def _GetRssServiceRssVersion(self):
|
||||
## return self._GetDoc().GetModel().rssServiceRssVersion
|
||||
##
|
||||
##
|
||||
## def _SetRssServiceRssVersion(self, rssVersion):
|
||||
## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion
|
||||
##
|
||||
##
|
||||
## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion)
|
||||
|
||||
|
||||
def _GetServiceRefServiceType(self):
|
||||
# HACK: temporary solution to getting service type from wsdlag file.
|
||||
doc = self._GetDoc()
|
||||
if not doc:
|
||||
return None
|
||||
model = doc.GetModel()
|
||||
if hasattr(model, 'serviceType'):
|
||||
return model.serviceType
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def _SetServiceRefServiceType(self, serviceType):
|
||||
# HACK: temporary solution to getting service type from wsdlag file.
|
||||
self._GetDoc().GetModel().serviceType = serviceType
|
||||
|
||||
|
||||
serviceType = property(_GetServiceRefServiceType, _SetServiceRefServiceType)
|
||||
|
||||
|
||||
def getExternalPackage(self):
|
||||
# HACK: temporary solution to getting custom code filename from wsdlag file.
|
||||
import activegrid.model.projectmodel as projectmodel
|
||||
import wx
|
||||
import ProjectEditor
|
||||
|
||||
appInfo = self._GetDoc().GetAppInfo()
|
||||
|
||||
if appInfo.language == None:
|
||||
language = wx.ConfigBase_Get().Read(ProjectEditor.APP_LAST_LANGUAGE, projectmodel.LANGUAGE_DEFAULT)
|
||||
else:
|
||||
language = appInfo.language
|
||||
|
||||
if language == projectmodel.LANGUAGE_PYTHON:
|
||||
suffix = ".py"
|
||||
elif language == projectmodel.LANGUAGE_PHP:
|
||||
suffix = ".php"
|
||||
pyFilename = self.name + suffix
|
||||
return self._GetDoc().GetAppDocMgr().fullPath(pyFilename)
|
||||
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Old Classes
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
class Project_10:
|
||||
""" Version 1.0, kept for upgrading to latest version. Over time, this should be deprecated. """
|
||||
__xmlname__ = "project"
|
||||
__xmlrename__ = { "_files":"files"}
|
||||
__xmlexclude__ = ('fileName',)
|
||||
__xmlattributes__ = ["version"]
|
||||
|
||||
|
||||
def __init__(self):
|
||||
self.version = PROJECT_VERSION_050730
|
||||
self._files = []
|
||||
|
||||
|
||||
def initialize(self):
|
||||
""" Required method for xmlmarshaller """
|
||||
pass
|
||||
|
||||
|
||||
def upgradeVersion(self):
|
||||
currModel = Project()
|
||||
for file in self._files:
|
||||
currModel._files.append(ProjectFile(currModel, file))
|
||||
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
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: __init__.py
|
||||
# Purpose: Utilities
|
||||
#
|
||||
# Author: Joel Hare
|
||||
#
|
||||
# Created: 7/28/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import traceback
|
||||
import sys
|
||||
import os
|
||||
|
||||
def isWindows():
|
||||
return os.name == 'nt'
|
||||
|
||||
def _generateMainModuleDir():
|
||||
if sys.executable.find('python') != -1:
|
||||
utilModuleDir = os.path.dirname(__file__)
|
||||
if not os.path.isabs(utilModuleDir):
|
||||
utilModuleDir = os.path.join(os.getcwd(), utilModuleDir)
|
||||
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
|
||||
if mainModuleDir.endswith('.zip'):
|
||||
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
|
||||
else:
|
||||
mainModuleDir = os.path.dirname(sys.executable)
|
||||
return mainModuleDir
|
||||
|
||||
mainModuleDir = _generateMainModuleDir()
|
||||
|
||||
|
||||
def _generatePythonExecPath():
|
||||
if sys.executable.find('python') != -1:
|
||||
pythonExecPath = sys.executable
|
||||
else:
|
||||
pythonExecPath = os.path.join(os.path.dirname(sys.executable), '3rdparty\python2.3\python')
|
||||
return pythonExecPath
|
||||
|
||||
pythonExecPath = _generatePythonExecPath()
|
||||
|
||||
def getCommandNameForExecPath(execPath):
|
||||
if isWindows():
|
||||
return '"%s"' % execPath
|
||||
return execPath
|
||||
|
||||
|
||||
@@ -15,7 +15,11 @@ import os
|
||||
import re
|
||||
import traceback
|
||||
import logging
|
||||
import logging.config
|
||||
from activegrid.util.lang import *
|
||||
import activegrid.util.objutils as objutils
|
||||
import activegrid.util.sysutils as sysutils
|
||||
import activegrid.util.appdirs as appdirs
|
||||
|
||||
LEVEL_FATAL = logging.FATAL
|
||||
LEVEL_ERROR = logging.ERROR
|
||||
@@ -23,6 +27,99 @@ LEVEL_WARN = logging.WARN
|
||||
LEVEL_INFO = logging.INFO
|
||||
LEVEL_DEBUG = logging.DEBUG
|
||||
|
||||
EXCEPTION_INFO = 'exceptionInfo'
|
||||
loggingInitialized = False
|
||||
|
||||
LOG_MODE_IDE = 1
|
||||
LOG_MODE_TESTRUN = 2
|
||||
LOG_MODE_RUN = 3
|
||||
def initLogging(mode, force=False):
|
||||
global ag_debugLogger, loggingInitialized
|
||||
if (force or not loggingInitialized):
|
||||
loggingInitialized = True
|
||||
configFile = None
|
||||
if (mode == LOG_MODE_IDE):
|
||||
configFile = os.getenv("AG_LOGCONFIG_IDE")
|
||||
elif (mode == LOG_MODE_TESTRUN):
|
||||
configFile = os.getenv("AG_LOGCONFIG_PYTESTRUN")
|
||||
else:
|
||||
configFile = os.getenv("AG_LOGCONFIG_RUN")
|
||||
if ((configFile == None) or not os.path.exists(configFile)):
|
||||
if (mode == LOG_MODE_IDE):
|
||||
configFile = "IDELog"
|
||||
elif (mode == LOG_MODE_TESTRUN):
|
||||
configFile = "TestRunLog"
|
||||
else:
|
||||
configFile = "RunLog"
|
||||
configFile = os.path.join(appdirs.getSystemDir(appdirs.AG_LOGS_DIR), "py" + configFile + ".ini")
|
||||
if (os.path.exists(configFile)):
|
||||
print "Using logging configuration file: %s" % configFile
|
||||
fileConfig(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")
|
||||
|
||||
def log(logger, level, msg, *params):
|
||||
if (logger == None):
|
||||
logger = ag_debugLogger
|
||||
apply(logger.log, (level, msg) + params)
|
||||
|
||||
def fatal(logger, msg, *params):
|
||||
apply(logger.fatal, (msg,) + params)
|
||||
|
||||
def error(logger, msg, *params):
|
||||
apply(logger.error, (msg,) + params)
|
||||
|
||||
def warn(logger, msg, *params):
|
||||
apply(logger.warn, (msg,) + params)
|
||||
|
||||
def info(logger, msg, *params):
|
||||
apply(logger.info, (msg,) + params)
|
||||
|
||||
def debug(logger, msg, *params):
|
||||
if (logger == None):
|
||||
logger = ag_debugLogger
|
||||
apply(logger.debug, (msg,) + params)
|
||||
|
||||
def setLevelFatal(logger):
|
||||
logger.setLevel(LEVEL_FATAL)
|
||||
|
||||
def setLevelError(logger):
|
||||
logger.setLevel(LEVEL_ERROR)
|
||||
|
||||
def setLevelWarn(logger):
|
||||
logger.setLevel(LEVEL_WARN)
|
||||
|
||||
def setLevelInfo(logger):
|
||||
logger.setLevel(LEVEL_INFO)
|
||||
|
||||
def setLevelDebug(logger):
|
||||
logger.setLevel(LEVEL_DEBUG)
|
||||
|
||||
def isEnabledForError(logger):
|
||||
return logger.isEnabledFor(LEVEL_ERROR)
|
||||
|
||||
def isEnabledForWarn(logger):
|
||||
return logger.isEnabledFor(LEVEL_WARN)
|
||||
|
||||
def isEnabledForInfo(logger):
|
||||
return logger.isEnabledFor(LEVEL_INFO)
|
||||
|
||||
def isEnabledForDebug(logger):
|
||||
return logger.isEnabledFor(LEVEL_DEBUG)
|
||||
|
||||
TEST_MODE_NONE = 0
|
||||
TEST_MODE_DETERMINISTIC = 1
|
||||
TEST_MODE_NON_DETERMINISTIC = 2
|
||||
@@ -38,8 +135,11 @@ def getTestMode():
|
||||
global agTestMode
|
||||
return agTestMode
|
||||
|
||||
def testMode(normalObj, testObj=None):
|
||||
if getTestMode() > TEST_MODE_NONE:
|
||||
def testMode(normalObj, testObj=None, nonDeterministicObj=None):
|
||||
testMode = getTestMode()
|
||||
if testMode > TEST_MODE_NONE:
|
||||
if ((nonDeterministicObj != None) and (testMode == TEST_MODE_NON_DETERMINISTIC)):
|
||||
return nonDeterministicObj
|
||||
return testObj
|
||||
return normalObj
|
||||
|
||||
@@ -68,36 +168,208 @@ def _fileNameReplacement(match):
|
||||
def _fileNameReplacementPHP(match):
|
||||
return "%s...%s" % (match.group(1), match.group(2).replace(os.sep, "/"))
|
||||
|
||||
def getTraceback():
|
||||
extype, val, tb = sys.exc_info()
|
||||
tbs = "\n"
|
||||
for s in traceback.format_tb(tb):
|
||||
tbs += s
|
||||
def formatTraceback(tb=None):
|
||||
if (tb == None):
|
||||
extype, val, tb = sys.exc_info()
|
||||
tbs = "\n" + "".join(traceback.format_tb(tb))
|
||||
return tbs
|
||||
|
||||
def reportException(out=None, stacktrace=False, diffable=False, exception=None):
|
||||
if (True): # exception == None):
|
||||
extype, val, t = sys.exc_info()
|
||||
def formatExceptionCause(cause, stacktrace=False):
|
||||
if (cause == None):
|
||||
return ""
|
||||
tbs = ""
|
||||
if (stacktrace):
|
||||
tbs = formatTraceback()
|
||||
return "Caused by %s.%s: %s%s" % (cause.__module__, cause.__class__.__name__, str(cause), tbs)
|
||||
|
||||
def addExceptionInfo(e, key, value):
|
||||
if not hasattr(e, EXCEPTION_INFO):
|
||||
try:
|
||||
setattr(e, EXCEPTION_INFO, {})
|
||||
except:
|
||||
return # Make sure we still report the real exception even if we can't add the extra info
|
||||
if not e.exceptionInfo.has_key(key): # Never overwrite exception info since we assume earlier info is more specific
|
||||
e.exceptionInfo[key] = value
|
||||
|
||||
def reportException(exception, out=None, stacktrace=False, diffable=False):
|
||||
exstr = exceptionToString(exception, stacktrace, diffable)
|
||||
if (out == None):
|
||||
print exstr
|
||||
else:
|
||||
extype = type(exception)
|
||||
val = exception
|
||||
if (stacktrace):
|
||||
e,v,t = sys.exc_info()
|
||||
print >> out, exstr
|
||||
|
||||
def exceptionToString(exception, stacktrace=False, diffable=False):
|
||||
extype = objutils.typeToString(exception)
|
||||
val = exception
|
||||
if (stacktrace):
|
||||
e,v,t = sys.exc_info()
|
||||
if (diffable):
|
||||
exstr = removeFileRefs(str(val))
|
||||
else:
|
||||
exstr = str(val)
|
||||
if (out == None):
|
||||
print "Got Exception = %s: %s" % (extype, exstr)
|
||||
else:
|
||||
print >> out, "Got Exception = %s: %s" % (extype, exstr)
|
||||
if hasattr(val, EXCEPTION_INFO):
|
||||
firstTime = True
|
||||
for infoKey, infoValue in getattr(val, EXCEPTION_INFO).items():
|
||||
if firstTime:
|
||||
prefix = " EXTRA INFO:"
|
||||
firstTime = False
|
||||
else:
|
||||
prefix = ","
|
||||
exstr += ("%s %s=%s" % (prefix, infoKey, infoValue))
|
||||
result = "Got Exception = %s: %s" % (extype, exstr)
|
||||
if (stacktrace):
|
||||
fmt = traceback.format_exception(extype, val, t)
|
||||
for s in fmt:
|
||||
if (diffable):
|
||||
s = removeFileRefs(s)
|
||||
if (out == None):
|
||||
print s
|
||||
result = result + "\n" + s
|
||||
return result
|
||||
|
||||
def fileConfig(fname, defaults=None):
|
||||
"""
|
||||
This is copied from logging.config so that we could fix the class lookup of
|
||||
handlers. Previously handlers had to be defined in logging.handlers and we
|
||||
need to be able to define our own.
|
||||
"""
|
||||
import ConfigParser, string
|
||||
|
||||
cp = ConfigParser.ConfigParser(defaults)
|
||||
if hasattr(cp, 'readfp') and hasattr(fname, 'readline'):
|
||||
cp.readfp(fname)
|
||||
else:
|
||||
cp.read(fname)
|
||||
#first, do the formatters...
|
||||
flist = cp.get("formatters", "keys")
|
||||
if len(flist):
|
||||
flist = string.split(flist, ",")
|
||||
formatters = {}
|
||||
for form in flist:
|
||||
sectname = "formatter_%s" % form
|
||||
opts = cp.options(sectname)
|
||||
if "format" in opts:
|
||||
fs = cp.get(sectname, "format", 1)
|
||||
else:
|
||||
print >> out, s
|
||||
|
||||
fs = None
|
||||
if "datefmt" in opts:
|
||||
dfs = cp.get(sectname, "datefmt", 1)
|
||||
else:
|
||||
dfs = None
|
||||
f = logging.Formatter(fs, dfs)
|
||||
formatters[form] = f
|
||||
#next, do the handlers...
|
||||
#critical section...
|
||||
logging._acquireLock()
|
||||
try:
|
||||
## try:
|
||||
#first, lose the existing handlers...
|
||||
logging._handlers.clear()
|
||||
#now set up the new ones...
|
||||
hlist = cp.get("handlers", "keys")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
handlers = {}
|
||||
fixups = [] #for inter-handler references
|
||||
for hand in hlist:
|
||||
## try:
|
||||
sectname = "handler_%s" % hand
|
||||
classname = cp.get(sectname, "class")
|
||||
opts = cp.options(sectname)
|
||||
if "formatter" in opts:
|
||||
fmt = cp.get(sectname, "formatter")
|
||||
else:
|
||||
fmt = ""
|
||||
klass = None
|
||||
try:
|
||||
klass = eval(classname, vars(logging))
|
||||
except:
|
||||
pass
|
||||
if (klass == None):
|
||||
klass = objutils.classForName(classname)
|
||||
args = cp.get(sectname, "args")
|
||||
args = eval(args, vars(logging))
|
||||
h = apply(klass, args)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
h.setLevel(logging._levelNames[level])
|
||||
if len(fmt):
|
||||
h.setFormatter(formatters[fmt])
|
||||
#temporary hack for FileHandler and MemoryHandler.
|
||||
if klass == logging.handlers.MemoryHandler:
|
||||
if "target" in opts:
|
||||
target = cp.get(sectname,"target")
|
||||
else:
|
||||
target = ""
|
||||
if len(target): #the target handler may not be loaded yet, so keep for later...
|
||||
fixups.append((h, target))
|
||||
handlers[hand] = h
|
||||
## except Exception, e: #if an error occurs when instantiating a handler, too bad
|
||||
## pass #this could happen e.g. because of lack of privileges
|
||||
#now all handlers are loaded, fixup inter-handler references...
|
||||
for fixup in fixups:
|
||||
h = fixup[0]
|
||||
t = fixup[1]
|
||||
h.setTarget(handlers[t])
|
||||
#at last, the loggers...first the root...
|
||||
llist = cp.get("loggers", "keys")
|
||||
llist = string.split(llist, ",")
|
||||
llist.remove("root")
|
||||
sectname = "logger_root"
|
||||
root = logging.root
|
||||
log = root
|
||||
opts = cp.options(sectname)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
log.setLevel(logging._levelNames[level])
|
||||
for h in root.handlers[:]:
|
||||
root.removeHandler(h)
|
||||
hlist = cp.get(sectname, "handlers")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
for hand in hlist:
|
||||
log.addHandler(handlers[hand])
|
||||
#and now the others...
|
||||
#we don't want to lose the existing loggers,
|
||||
#since other threads may have pointers to them.
|
||||
#existing is set to contain all existing loggers,
|
||||
#and as we go through the new configuration we
|
||||
#remove any which are configured. At the end,
|
||||
#what's left in existing is the set of loggers
|
||||
#which were in the previous configuration but
|
||||
#which are not in the new configuration.
|
||||
existing = root.manager.loggerDict.keys()
|
||||
#now set up the new ones...
|
||||
for log in llist:
|
||||
sectname = "logger_%s" % log
|
||||
qn = cp.get(sectname, "qualname")
|
||||
opts = cp.options(sectname)
|
||||
if "propagate" in opts:
|
||||
propagate = cp.getint(sectname, "propagate")
|
||||
else:
|
||||
propagate = 1
|
||||
logger = logging.getLogger(qn)
|
||||
if qn in existing:
|
||||
existing.remove(qn)
|
||||
if "level" in opts:
|
||||
level = cp.get(sectname, "level")
|
||||
logger.setLevel(logging._levelNames[level])
|
||||
for h in logger.handlers[:]:
|
||||
logger.removeHandler(h)
|
||||
logger.propagate = propagate
|
||||
logger.disabled = 0
|
||||
hlist = cp.get(sectname, "handlers")
|
||||
if len(hlist):
|
||||
hlist = string.split(hlist, ",")
|
||||
for hand in hlist:
|
||||
logger.addHandler(handlers[hand])
|
||||
#Disable any old loggers. There's no point deleting
|
||||
#them as other threads may continue to hold references
|
||||
#and by disabling them, you stop them doing any logging.
|
||||
for log in existing:
|
||||
root.manager.loggerDict[log].disabled = 1
|
||||
## except:
|
||||
## import traceback
|
||||
## ei = sys.exc_info()
|
||||
## traceback.print_exception(ei[0], ei[1], ei[2], None, sys.stderr)
|
||||
## del ei
|
||||
finally:
|
||||
logging._releaseLock()
|
||||
|
||||
126
wxPython/samples/ide/activegrid/util/appdirs.py
Normal file
126
wxPython/samples/ide/activegrid/util/appdirs.py
Normal file
@@ -0,0 +1,126 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: appdirs.py
|
||||
# Purpose: Utilities for retrieving special application dirs
|
||||
#
|
||||
# Author: Kevin Ollivier, Jeff Norton
|
||||
#
|
||||
# Created: 8/27/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
from activegrid.util.lang import *
|
||||
import sys
|
||||
import os
|
||||
import string
|
||||
import activegrid.util.sysutils as sysutils
|
||||
|
||||
def _getSystemDir(kind):
|
||||
if (kind == AG_LOGS_DIR):
|
||||
return os.path.join(getSystemDir(AG_SYSTEM_DIR) , "logs")
|
||||
elif (kind == AG_DEMOS_DIR):
|
||||
return os.path.join(getSystemDir(AG_SYSTEM_DIR), "demos")
|
||||
else:
|
||||
path = ""
|
||||
if (sysutils.isServer()):
|
||||
path = os.getenv("ACTIVEGRID_SERVER_HOME")
|
||||
if ((path is None) or (len(path) < 1)):
|
||||
path = sysutils.mainModuleDir
|
||||
else:
|
||||
path = os.getenv("AG_DOCUMENTS_DIR")
|
||||
if ((path is None) or (len(path) < 1)):
|
||||
if sysutils.isWindows():
|
||||
ifDefPy()
|
||||
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")
|
||||
|
||||
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
|
||||
# application object. This makes sure the wxApp will always be created when
|
||||
# we get the folder.
|
||||
ifDefPy()
|
||||
def getAppDataFolder():
|
||||
try:
|
||||
# NOTE: cannot import wx from the server
|
||||
import wx
|
||||
# wxStandardPaths requires a running app
|
||||
if wx.GetApp() and wx.Platform != "__WXGTK__":
|
||||
data_folder = wx.StandardPaths.Get().GetUserDataDir()
|
||||
if not os.path.exists(data_folder):
|
||||
os.mkdir(data_folder)
|
||||
return data_folder
|
||||
except:
|
||||
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()
|
||||
|
||||
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
|
||||
431
wxPython/samples/ide/activegrid/util/fileutils.py
Normal file
431
wxPython/samples/ide/activegrid/util/fileutils.py
Normal file
@@ -0,0 +1,431 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: fileutils.py
|
||||
# Purpose: Active grid miscellaneous utilities
|
||||
#
|
||||
# Author: Jeff Norton
|
||||
#
|
||||
# Created: 12/10/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import logging
|
||||
import copy
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
import activegrid.util.aglogging as aglogging
|
||||
import activegrid.util.sysutils as sysutils
|
||||
import activegrid.util.utillang as utillang
|
||||
from activegrid.util.lang import *
|
||||
|
||||
global fileutilsLogger
|
||||
fileutilsLogger = logging.getLogger("activegrid.util.fileutils")
|
||||
# FATAL : No logging
|
||||
# ERROR : No logging
|
||||
# WARN : No logging
|
||||
# INFO : No logging
|
||||
# DEBUG : debugging
|
||||
aglogging.setLevelFatal(fileutilsLogger)
|
||||
#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):
|
||||
d = os.path.dirname(filename)
|
||||
if (not os.path.exists(d)):
|
||||
os.makedirs(d)
|
||||
|
||||
def createFile(filename, mode='w'):
|
||||
f = None
|
||||
if (not os.path.exists(filename)):
|
||||
makeDirsForFile(filename)
|
||||
f = file(filename, mode)
|
||||
return f
|
||||
|
||||
def compareFiles(file1, file2, ignore=None):
|
||||
## result = filecmp.cmp(file1, file2)
|
||||
## if result:
|
||||
## return 0
|
||||
## return -1
|
||||
file1.seek(0)
|
||||
file2.seek(0)
|
||||
while True:
|
||||
line1 = file1.readline()
|
||||
line2 = file2.readline()
|
||||
if (len(line1) == 0):
|
||||
if (len(line2) == 0):
|
||||
return 0
|
||||
else:
|
||||
return -1
|
||||
elif (len(line2) == 0):
|
||||
return -1
|
||||
elif (line1 != line2):
|
||||
if (ignore != None):
|
||||
if (line1.startswith(ignore) or line2.startswith(ignore)):
|
||||
continue
|
||||
line1 = line1.replace(" ", "")
|
||||
line2 = line2.replace(" ", "")
|
||||
if (line1 != line2):
|
||||
len1 = len(line1)
|
||||
len2 = len(line2)
|
||||
if ((abs(len1 - len2) == 1) and (len1 > 0) and (len2 > 0)
|
||||
and (line1[-1] == "\n") and (line2[-1] == "\n")):
|
||||
if (len1 > len2):
|
||||
longer = line1
|
||||
shorter = line2
|
||||
else:
|
||||
shorter = line1
|
||||
longer = line2
|
||||
if ((longer[-2] == "\r") and (longer[:-2] == shorter[:-1])):
|
||||
continue
|
||||
if ((longer[-2:] == shorter[-2:]) and (longer[-3] == "\r") and (longer[:-3] == shorter[:-2])):
|
||||
continue
|
||||
return -1
|
||||
|
||||
def expandKnownAGVars(value):
|
||||
return expandVars(value, includeEnv=False)
|
||||
|
||||
def expandVars(value, includeEnv=True):
|
||||
"""Syntax: ${myvar,default="default value"}"""
|
||||
import activegrid.runtime as runtime
|
||||
sx = value.find("${")
|
||||
if (sx >= 0):
|
||||
result = asString(value[:sx])
|
||||
endx = value.find("}")
|
||||
if (endx > 1):
|
||||
defaultValue = None
|
||||
defsx = value.find(",default=\"")
|
||||
if ((defsx > sx) and (defsx < endx)):
|
||||
varname = value[sx+2:defsx]
|
||||
if (value[endx-1] == '"'):
|
||||
defaultValue = value[defsx+10:endx-1]
|
||||
if (defaultValue == None):
|
||||
varname = value[sx+2:endx]
|
||||
if (varname == AG_SYSTEM_VAR):
|
||||
varval = runtime.appInfo.getSystemDir()
|
||||
elif (varname == AG_SYSTEM_STATIC_VAR):
|
||||
varval = runtime.appInfo.getSystemStaticDir()
|
||||
elif (varname == AG_APP_VAR):
|
||||
varval = runtime.appInfo.getAppDir()
|
||||
elif (varname == AG_APP_STATIC_VAR):
|
||||
varval = runtime.appInfo.getAppStaticDir()
|
||||
else:
|
||||
if (includeEnv):
|
||||
varval = os.getenv(varname)
|
||||
else:
|
||||
varval = None
|
||||
if ((varval == None) and (defaultValue != None)):
|
||||
varval = defaultValue
|
||||
if (varval == None):
|
||||
result += value[sx:endx+1]
|
||||
else:
|
||||
result += varval
|
||||
return result + expandVars(value[endx+1:])
|
||||
return value
|
||||
|
||||
def toPHPpath(path, otherdir=None):
|
||||
return convertSourcePath(path, "php", otherdir=otherdir)
|
||||
|
||||
def toPythonpath(path, otherdir=None):
|
||||
return convertSourcePath(path, "python", otherdir=otherdir)
|
||||
|
||||
def toUnixPath(path):
|
||||
if (path != None and os.sep != '/'):
|
||||
path = path.replace(os.sep, '/')
|
||||
return path
|
||||
|
||||
def convertSourcePath(path, to, otherdir=None):
|
||||
fromname = "python"
|
||||
if (to == "python"):
|
||||
fromname = "php"
|
||||
pythonNode = os.sep + fromname + os.sep
|
||||
ix = path.find(pythonNode)
|
||||
if (ix < 0):
|
||||
ix = path.find(fromname) - 1
|
||||
if ((ix < 0) or (len(path) <= ix+7)
|
||||
or (path[ix] not in ("\\", "/")) or (path[ix+7] not in ("\\", "/"))):
|
||||
raise Exception("Not in a %s source tree. Cannot create file name for %s." % (fromname, path))
|
||||
if (otherdir == None):
|
||||
return path[:ix+1] + to + path[ix+7:]
|
||||
else:
|
||||
return otherdir + path[ix+7:]
|
||||
if (otherdir == None):
|
||||
return path.replace(pythonNode, os.sep + to + os.sep)
|
||||
else:
|
||||
return otherdir + path[ix+7:]
|
||||
|
||||
|
||||
def visit(directory, files, extension, maxLevel=None, level=1):
|
||||
testdirs = os.listdir(directory)
|
||||
for thing in testdirs:
|
||||
fullpath = os.path.join(directory, thing)
|
||||
if (os.path.isdir(fullpath) and (maxLevel == None or level < maxLevel)):
|
||||
visit(fullpath, files, extension, maxLevel, level+1)
|
||||
elif thing.endswith(extension):
|
||||
fullname = os.path.normpath(os.path.join(directory, thing))
|
||||
if not fullname in files:
|
||||
files.append(fullname)
|
||||
|
||||
def listFilesByExtensionInPath(path=[], extension='.lyt', maxLevel=None):
|
||||
retval = []
|
||||
for directory in path:
|
||||
visit(directory, retval, extension, maxLevel)
|
||||
return retval
|
||||
|
||||
def getFileLastModificationTime(fileName):
|
||||
return os.path.getmtime(fileName)
|
||||
|
||||
def findFileLocation(location, fileName):
|
||||
i = fileName.rfind(os.sep)
|
||||
if i > 0:
|
||||
fileName = fileName[:i]
|
||||
while location[0:2] == '..' and location[2:3] == os.sep:
|
||||
location = location[3:]
|
||||
i = fileName.rfind(os.sep)
|
||||
fileName = fileName[:i]
|
||||
absPath = fileName + os.sep + location
|
||||
return absPath
|
||||
|
||||
def getAllExistingFiles(files, basepath=None, forceForwardSlashes=False):
|
||||
"""For each file in files, if it exists, adds its absolute path to the rtn list. If file is a dir, calls this function recursively on all child files in the dir.
|
||||
If basepath is set, and if the file being processed is relative to basedir, adds that relative path to rtn list instead of the abs path.
|
||||
Is this is Windows, and forceForwardSlashes is True, make sure returned paths only have forward slashes."""
|
||||
if isinstance(files, basestring):
|
||||
files = [files]
|
||||
rtn = []
|
||||
for file in files:
|
||||
if os.path.exists(file):
|
||||
if os.path.isfile(file):
|
||||
if basepath and hasAncestorDir(file, basepath):
|
||||
rtn.append(getRelativePath(file, basepath))
|
||||
else:
|
||||
rtn.append(os.path.abspath(str(file)))
|
||||
elif os.path.isdir(file):
|
||||
dircontent = [os.path.join(file, f) for f in os.listdir(file)]
|
||||
rtn.extend(getAllExistingFiles(dircontent, basepath))
|
||||
|
||||
if forceForwardSlashes and sysutils.isWindows():
|
||||
newRtn = []
|
||||
for f in rtn:
|
||||
newRtn.append(f.replace("\\", "/"))
|
||||
rtn = newRtn
|
||||
|
||||
return rtn
|
||||
|
||||
def hasAncestorDir(file, parent):
|
||||
"""Returns true if file has the dir 'parent' as some parent in its path."""
|
||||
return getRelativePath(file, parent) != None
|
||||
|
||||
def getRelativePath(file, basedir):
|
||||
"""Returns relative path from 'basedir' to 'file', assuming 'file' lives beneath 'basedir'. If it doesn't, returns None."""
|
||||
file = os.path.abspath(file)
|
||||
parent = os.path.abspath(basedir)
|
||||
|
||||
if file == parent:
|
||||
return None
|
||||
|
||||
if file.startswith(parent):
|
||||
return file[len(parent)+1:]
|
||||
|
||||
return None
|
||||
|
||||
def isEmptyDir(dir):
|
||||
if not os.path.isdir(dir):
|
||||
return False
|
||||
return len(os.listdir(dir)) == 0
|
||||
|
||||
ifDefPy()
|
||||
def zip(zipfilepath, basedir=None, files=None):
|
||||
"""Zip all files in files and save zip as zipfilepath. If files is None, zip all files in basedir. For all files to be zipped, if they are relative to basedir, include the relative path in the archive."""
|
||||
|
||||
if not files and not basedir:
|
||||
raise AssertionError("Either 'basedir' or 'files' must be set")
|
||||
|
||||
if not files:
|
||||
aglogging.debug(fileutilsLogger,\
|
||||
"Looking for files to zip in %s" % basedir)
|
||||
files = getAllExistingFiles(basedir)
|
||||
else:
|
||||
# removes files that don't exist and gets abs for each
|
||||
files = getAllExistingFiles(files)
|
||||
|
||||
if len(files) == 0:
|
||||
aglogging.debug(fileutilsLogger, "No files to zip, nothing to do")
|
||||
return
|
||||
|
||||
z = zipfile.ZipFile(zipfilepath, mode="w", compression=zipfile.ZIP_DEFLATED)
|
||||
|
||||
try:
|
||||
for file in files:
|
||||
arcname = None
|
||||
if basedir:
|
||||
arcname = getRelativePath(file, basedir)
|
||||
if not arcname:
|
||||
arcname = file
|
||||
aglogging.debug(fileutilsLogger,\
|
||||
"%s: adding %s with arcname %s" %\
|
||||
(zipfilepath, file, arcname))
|
||||
z.write(file, arcname)
|
||||
finally:
|
||||
z.close()
|
||||
endIfDef()
|
||||
|
||||
|
||||
ifDefPy()
|
||||
def unzip(zipfilepath, extractdir):
|
||||
"""Unzip zipfilepath into extractdir."""
|
||||
z = zipfile.ZipFile(zipfilepath, mode="r")
|
||||
for info in z.infolist():
|
||||
filename = os.path.join(extractdir, info.filename)
|
||||
try:
|
||||
dir = os.path.dirname(filename)
|
||||
aglogging.debug(fileutilsLogger, "Creating dir %s" % dir)
|
||||
os.makedirs(dir) # do we have to worry about permissions?
|
||||
except:
|
||||
pass
|
||||
if os.path.isdir(filename):
|
||||
continue
|
||||
aglogging.debug(fileutilsLogger,\
|
||||
("Writing arcfile %s to %s" % (info.filename, filename)))
|
||||
f = open(filename, "w")
|
||||
f.write(z.read(info.filename))
|
||||
f.close()
|
||||
endIfDef()
|
||||
|
||||
ifDefPy()
|
||||
def copyFile(src, dest):
|
||||
"""Copies file src to dest. Creates directories in 'dest' path if necessary."""
|
||||
destdir = os.path.dirname(dest)
|
||||
if not os.path.exists(destdir):
|
||||
os.makedirs(destdir)
|
||||
shutil.copy(src, dest)
|
||||
endIfDef()
|
||||
|
||||
ifDefPy()
|
||||
def copyDir(src, dest):
|
||||
"""Copies dir 'src' into dir 'dest'. Creates 'dest' if it does not exist."""
|
||||
shutil.copytree(src, dest)
|
||||
endIfDef()
|
||||
|
||||
ifDefPy()
|
||||
def remove(file):
|
||||
if not os.path.exists(file):
|
||||
return
|
||||
if os.path.isfile(file):
|
||||
os.remove(file)
|
||||
elif os.path.isdir(file):
|
||||
shutil.rmtree(file)
|
||||
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()
|
||||
import warnings
|
||||
warnings.filterwarnings("ignore", message="tmpnam is a potential security risk to your program")
|
||||
def getTmpFile():
|
||||
return os.tmpnam()
|
||||
endIfDef()
|
||||
|
||||
ifDefPy()
|
||||
#@accepts str, dict, str, str, boolean
|
||||
def replaceToken(infilepath, tokens={}, outfilepath=None, delim="@@",\
|
||||
useEnv=False):
|
||||
"""Replaces tokens of form 'delim'<tokenname>'delim' in file at 'infilepath', using values in dict 'tokens'. If 'outfilepath' is set, writes output to 'outfilepath', if not set, overwrites original file. If 'useEnv' is True, adds os.environ to 'tokens'. This makes it possible to define an env var FOO=BLAH, and have @@FOO@@ be replaced with BLAH, without explicitly passing FOO=BLAH in 'tokens'. Note that entries in 'tokens' take precedence over entries in os.environ."""
|
||||
|
||||
if useEnv:
|
||||
for key, val in os.environ.items():
|
||||
# passed in tokens take precedence
|
||||
if not tokens.has_key(key):
|
||||
tokens[key] = val
|
||||
|
||||
f = open(infilepath, "r")
|
||||
try:
|
||||
content = f.read()
|
||||
finally:
|
||||
if f: f.close()
|
||||
|
||||
for token, value in tokens.items():
|
||||
content = content.replace("%s%s%s" % (delim, token , delim), str(value))
|
||||
|
||||
if not outfilepath: outfilepath = infilepath
|
||||
f = open(outfilepath, "w")
|
||||
try:
|
||||
f.write(content)
|
||||
finally:
|
||||
if f: f.close()
|
||||
endIfDef()
|
||||
@@ -65,3 +65,9 @@ def ifDefPy(comment=False):
|
||||
|
||||
def endIfDef():
|
||||
pass
|
||||
|
||||
def ag_isPHP():
|
||||
return False
|
||||
|
||||
def ag_isPython():
|
||||
return True
|
||||
|
||||
@@ -14,36 +14,222 @@ import logging
|
||||
import traceback
|
||||
import sys
|
||||
import os
|
||||
import __builtin__
|
||||
import types
|
||||
import activegrid.util.utillang as utillang
|
||||
import activegrid.util.datetimeparser as datetimeparser
|
||||
from types import *
|
||||
from activegrid.util.lang import *
|
||||
|
||||
FUNCTION_HAS_ATTR = '_hasAttr'
|
||||
FUNCTION_GET_ATTR = '_getAttr'
|
||||
FUNCTION_SET_ATTR = '_setAttr'
|
||||
FUNCTION_DEL_ATTR = '_delAttr'
|
||||
|
||||
def hasRawAttr(obj, name):
|
||||
if obj == None:
|
||||
return False
|
||||
if name != FUNCTION_HAS_ATTR and hasattr(obj, FUNCTION_HAS_ATTR):
|
||||
return obj._hasAttr(name)
|
||||
return obj.__dict__.has_key(name)
|
||||
|
||||
def getRawAttr(obj, name):
|
||||
if name != FUNCTION_GET_ATTR and hasattr(obj, FUNCTION_GET_ATTR):
|
||||
return obj._getAttr(name)
|
||||
return obj.__dict__.get(name)
|
||||
|
||||
def setRawAttr(obj, name, value):
|
||||
if name != FUNCTION_SET_ATTR and hasattr(obj, FUNCTION_SET_ATTR):
|
||||
obj._setAttr(name, value)
|
||||
else:
|
||||
obj.__dict__[name] = value
|
||||
|
||||
def delRawAttr(obj, name):
|
||||
if name != FUNCTION_DEL_ATTR and hasattr(obj, FUNCTION_DEL_ATTR):
|
||||
obj._delAttr(name)
|
||||
else:
|
||||
del obj.__dict__[name]
|
||||
|
||||
def getStaticAttr(obj, attr):
|
||||
if (isinstance(obj, types.TypeType)):
|
||||
classDesc = obj
|
||||
else:
|
||||
classDesc = obj.__class__
|
||||
if (hasattr(classDesc, attr)):
|
||||
return getattr(classDesc, attr)
|
||||
return None
|
||||
|
||||
def setStaticAttr(obj, attr, value):
|
||||
if (isinstance(obj, types.TypeType)):
|
||||
classDesc = obj
|
||||
else:
|
||||
classDesc = obj.__class__
|
||||
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):
|
||||
module = None
|
||||
pathList = moduleName.split('.')
|
||||
if (len(moduleName) > 0):
|
||||
module = __import__(moduleName)
|
||||
for name in pathList[1:]:
|
||||
if (name in module.__dict__):
|
||||
module = module.__dict__[name]
|
||||
else:
|
||||
module = None
|
||||
break
|
||||
return module
|
||||
|
||||
def typeForName(typeName):
|
||||
i = typeName.rfind('.')
|
||||
if (i >= 0):
|
||||
module = moduleForName(typeName[:i])
|
||||
if (module != None):
|
||||
name = typeName[i+1:]
|
||||
if (name in module.__dict__):
|
||||
return module.__dict__[name]
|
||||
elif __builtin__.__dict__.has_key(typeName):
|
||||
return __builtin__.__dict__[typeName]
|
||||
return None
|
||||
|
||||
def functionForName(functionName):
|
||||
ftype = typeForName(functionName)
|
||||
if (isinstance(ftype, (types.FunctionType, types.MethodType, types.BuiltinFunctionType, types.BuiltinMethodType))):
|
||||
return ftype
|
||||
return None
|
||||
|
||||
def classForName(className):
|
||||
pathList = className.split('.')
|
||||
moduleName = '.'.join(pathList[:-1])
|
||||
code = __import__(moduleName)
|
||||
for name in pathList[1:]:
|
||||
code = code.__dict__[name]
|
||||
return code
|
||||
ctype = typeForName(className)
|
||||
if (isinstance(ctype, (types.ClassType, types.TypeType))):
|
||||
return ctype
|
||||
return None
|
||||
|
||||
def hasPropertyValue(obj, attr):
|
||||
hasProp = False
|
||||
try:
|
||||
prop = obj.__class__.__dict__[attr]
|
||||
if (isinstance(prop, property)):
|
||||
hasProp = hasattr(obj, attr)
|
||||
if (hasProp):
|
||||
# It's a property and it has a value but sometimes we don't want it.
|
||||
# If there is a _hasattr method execute it and the
|
||||
# result will tell us whether to include this value
|
||||
try:
|
||||
hasProp = obj._hasattr(attr)
|
||||
except:
|
||||
pass
|
||||
except KeyError:
|
||||
pass
|
||||
return hasProp
|
||||
def newInstance(className, objargs=None):
|
||||
"dynamically create an object based on the className and return it."
|
||||
|
||||
def toDiffableString(value):
|
||||
s = str(value)
|
||||
if not isinstance(objargs, list):
|
||||
objargs = [objargs]
|
||||
|
||||
if className == "None":
|
||||
return None
|
||||
elif className == "bool":
|
||||
if ((len(objargs) < 1) or (objargs[0].lower() == "false") or (not objargs[0])):
|
||||
return False
|
||||
return True
|
||||
if className == "str" or className == "unicode": # don't strip: blanks are significant
|
||||
if len(objargs) > 0:
|
||||
try:
|
||||
return utillang.unescape(objargs[0]).encode()
|
||||
except:
|
||||
return "?"
|
||||
else:
|
||||
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)
|
||||
if (classtype == None):
|
||||
raise Exception("Could not find class %s" % className)
|
||||
|
||||
if (len(objargs) > 0):
|
||||
return classtype(*objargs)
|
||||
else:
|
||||
return classtype()
|
||||
|
||||
def getClassProperty(classType, propertyName):
|
||||
return getattr(classType, propertyName)
|
||||
|
||||
def toDiffableRepr(value, maxLevel=None):
|
||||
if (value == 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__")):
|
||||
## if (exclude == None):
|
||||
## exclude = []
|
||||
## s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, exclude))
|
||||
if (not isinstance(value, (BooleanType, ClassType, ComplexType, DictType, DictionaryType,
|
||||
FloatType, IntType, ListType, LongType, StringType, TupleType,
|
||||
UnicodeType, BufferType, BuiltinFunctionType, BuiltinMethodType,
|
||||
CodeType, FrameType, FunctionType, GeneratorType, InstanceType,
|
||||
LambdaType, MethodType, ModuleType, SliceType, TracebackType,
|
||||
TypeType, XRangeType))):
|
||||
if (hasattr(value, "_toDiffableString")):
|
||||
s = value._toDiffableString(maxLevel)
|
||||
elif (hasattr(value, "__str__")):
|
||||
s = str(value)
|
||||
elif (hasattr(value, "__dict__")):
|
||||
s = "%s(%s)" % (type(value), toDiffableString(value.__dict__, maxLevel))
|
||||
else:
|
||||
s = str(type(value))
|
||||
ix2 = s.find(" object at 0x")
|
||||
if (ix2 > 0):
|
||||
ix = s.rfind(".")
|
||||
if (ix > 0):
|
||||
s = "<class %s>" %s[ix+1:ix2]
|
||||
elif (isinstance(value, bool)):
|
||||
if (value):
|
||||
return "True"
|
||||
else:
|
||||
return "False"
|
||||
elif (isinstance(value, (tuple, list))):
|
||||
items = []
|
||||
for v in value:
|
||||
if (isinstance(v, basestring)):
|
||||
if (v.find("'") >= 0):
|
||||
items.append('"%s"' % v)
|
||||
else:
|
||||
items.append("'%s'" % v)
|
||||
else:
|
||||
items.append(toDiffableString(v, maxLevel))
|
||||
s = "[" + ", ".join(items) + "]"
|
||||
elif (isinstance(value, dict)):
|
||||
items = []
|
||||
for key, val in value.iteritems():
|
||||
if (isinstance(val, UnicodeType)):
|
||||
items.append("'%s': u'%s'" % (key, toDiffableString(val, maxLevel)))
|
||||
elif (isinstance(val, basestring)):
|
||||
items.append("'%s': '%s'" % (key, toDiffableString(val, maxLevel)))
|
||||
else:
|
||||
items.append("'%s': %s" % (key, toDiffableString(val, maxLevel)))
|
||||
s = "{" + ", ".join(items) + "}"
|
||||
else:
|
||||
s = str(value)
|
||||
return s
|
||||
|
||||
def toDiffableString(value, maxLevel=None):
|
||||
## if (value == None):
|
||||
## return "None"
|
||||
## if ((exclude != None) and not isinstance(value, (basestring, int))):
|
||||
## for v in exclude:
|
||||
## if (v is value):
|
||||
## return "<recursive reference>"
|
||||
## exclude.append(value)
|
||||
s = toDiffableRepr(value, maxLevel)
|
||||
ds = ""
|
||||
i = s.find(" at 0x")
|
||||
start = 0
|
||||
@@ -54,22 +240,43 @@ def toDiffableString(value):
|
||||
ds += s[start:i]
|
||||
start = j
|
||||
i = s.find(" at 0x", start)
|
||||
return ds + s[start:]
|
||||
|
||||
ds = ds + s[start:]
|
||||
i = ds.find("\\src\\")
|
||||
if (i < 0):
|
||||
i = ds.find("/src/")
|
||||
else:
|
||||
ds = ds.replace("\\", "/")
|
||||
if (i > 0):
|
||||
i += 4
|
||||
if (ds[i:i+5] == "\\php\\"):
|
||||
i += 4
|
||||
elif (ds[i:i+8] == "\\python\\"):
|
||||
i += 7
|
||||
ds = "filepath: ..." + ds[i:]
|
||||
return ds
|
||||
|
||||
def toString(value, options=0):
|
||||
if ((options & PRINT_OBJ_DIFFABLE) > 0):
|
||||
return toDiffableString(value)
|
||||
elif (not isinstance(value, basestring)):
|
||||
return str(value)
|
||||
return value
|
||||
|
||||
def toTypeString(obj):
|
||||
def typeToString(obj, options=0):
|
||||
if (isinstance(obj, BooleanType)):
|
||||
return "bool"
|
||||
elif (isinstance(obj, UnicodeType)):
|
||||
if ((options & PRINT_OBJ_DIFFABLE) > 0):
|
||||
return "string"
|
||||
return "unicode"
|
||||
elif (isinstance(obj, basestring)):
|
||||
return "string"
|
||||
elif (isinstance(obj, IntType)):
|
||||
return "int"
|
||||
elif (isinstance(obj, LongType)):
|
||||
if ((options & PRINT_OBJ_DIFFABLE) > 0):
|
||||
return "int"
|
||||
return "long"
|
||||
elif (isinstance(obj, FloatType)):
|
||||
return "float"
|
||||
elif (type(obj) == ListType):
|
||||
@@ -79,18 +286,46 @@ def toTypeString(obj):
|
||||
elif (isinstance(obj, TupleType)):
|
||||
return "tuple"
|
||||
elif (isinstance(obj, InstanceType)):
|
||||
return type(obj)
|
||||
## ds = str(type(obj))
|
||||
ds = "<class %s.%s> " % (obj.__module__, obj.__class__.__name__)
|
||||
else:
|
||||
return type(obj)
|
||||
ds = str(type(obj))
|
||||
if (options == 0):
|
||||
import activegrid.util.aglogging
|
||||
options = activegrid.util.aglogging.testMode(0, PRINT_OBJ_DIFFABLE)
|
||||
if ((options & PRINT_OBJ_DIFFABLE) > 0):
|
||||
if (ds.startswith("<class ")):
|
||||
ix = ds.rfind(".")
|
||||
if (ix < 0):
|
||||
ix = 8
|
||||
ds = "<class %s>" % ds[ix+1:-2]
|
||||
return ds
|
||||
|
||||
def nameToString(name, options=0):
|
||||
if (name.startswith("_v_")):
|
||||
return name[3:]
|
||||
if ((options & PRINT_OBJ_DIFFABLE) > 0):
|
||||
ix = name.find("__")
|
||||
if ((ix > 1) and name.startswith("_")):
|
||||
name = name[ix:]
|
||||
return toDiffableString(name)
|
||||
return name
|
||||
|
||||
PRINT_OBJ_GETATTR = 1
|
||||
PRINT_OBJ_HIDE_INTERNAL = 2
|
||||
PRINT_OBJ_COMPACT = 4
|
||||
PRINT_OBJ_NONONE = 8
|
||||
PRINT_OBJ_DIFFABLE = 16
|
||||
PRINT_OBJ_HIDE_EXCLUDED = 32
|
||||
PRINT_OBJ_INTERNAL = 512
|
||||
|
||||
def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent=30):
|
||||
def printObject(out, object, name=None, indent=0, flags=0, exclude=None, remove=None, maxIndent=30):
|
||||
if (name == None):
|
||||
name = ""
|
||||
## elif (name.endswith("_") and not name.endswith("__")):
|
||||
## name = name[:-1]
|
||||
if ((remove != None) and (name in asDict(remove))):
|
||||
return False
|
||||
if ((maxIndent != None) and (indent > maxIndent)):
|
||||
print >> out, " "*indent, "%s: %s" % (name, toString(str(object), flags)),
|
||||
if ((flags & PRINT_OBJ_INTERNAL) == 0):
|
||||
@@ -98,12 +333,11 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
|
||||
return True
|
||||
finalNewLine = False
|
||||
printed = True
|
||||
## if (exclude == None):
|
||||
## exclude = []
|
||||
if ((flags & PRINT_OBJ_COMPACT) > 0):
|
||||
if (exclude and object in exclude):
|
||||
if ((flags & (PRINT_OBJ_COMPACT | PRINT_OBJ_HIDE_EXCLUDED)) > 0):
|
||||
if ((exclude != None) and ((object in exclude) or (name in exclude))):
|
||||
return
|
||||
indent = 0
|
||||
if ((flags & PRINT_OBJ_COMPACT) > 0):
|
||||
indent = 0
|
||||
if ((flags & PRINT_OBJ_INTERNAL) == 0):
|
||||
finalNewLine = True
|
||||
flags |= PRINT_OBJ_INTERNAL
|
||||
@@ -113,23 +347,23 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
|
||||
else:
|
||||
finalNewLine = False
|
||||
printed = False
|
||||
elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
|
||||
elif (name.startswith("_") and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0) and not name.startswith("_v_")):
|
||||
finalNewLine = False
|
||||
printed = False
|
||||
elif (isinstance(object, (list, tuple))):
|
||||
if ((exclude != None) and object in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (already printed)",
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (already printed)",
|
||||
elif ((exclude != None) and name in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)",
|
||||
else:
|
||||
if ((exclude != None) and (len(object) > 0)): exclude.append(object)
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = %d" % len(object),
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = %d" % len(object),
|
||||
for i, o in enumerate(object):
|
||||
print >> out
|
||||
printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||
printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
|
||||
elif (isinstance(object, dict)):
|
||||
if ((exclude != None) and object in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)",
|
||||
else:
|
||||
if ((exclude != None) and (len(object) > 0)): exclude.append(object)
|
||||
if (len(name) > 0):
|
||||
@@ -147,51 +381,62 @@ def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent
|
||||
n = key
|
||||
if (not (isinstance(n, basestring))):
|
||||
n = str(n)
|
||||
else:
|
||||
n = nameToString(n, flags)
|
||||
if ((not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))):
|
||||
if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, maxIndent=maxIndent):
|
||||
if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, remove=remove, maxIndent=maxIndent):
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
print >> out
|
||||
else:
|
||||
print >> out, ",",
|
||||
print >> out, " "*indent, "}",
|
||||
elif (hasattr(object, "__dict__")):
|
||||
if ((exclude != None) and object in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed) = ", toDiffableString(object),
|
||||
if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags),
|
||||
elif ((exclude != None) and ((object in exclude) or (object.__dict__ in exclude))):
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " (already printed)",
|
||||
else:
|
||||
if (exclude != None): exclude.append(object)
|
||||
if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object),
|
||||
elif ((exclude != None) and object.__dict__ in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags),
|
||||
if ((flags & PRINT_OBJ_GETATTR) == 0):
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
print >> out
|
||||
printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
|
||||
else:
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object),
|
||||
if ((flags & PRINT_OBJ_GETATTR) == 0):
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
print >> out
|
||||
## indent += 2
|
||||
print >> out, " "*indent, "{",
|
||||
keys = object.__dict__.keys()
|
||||
keys.sort()
|
||||
printed = True
|
||||
for key in keys:
|
||||
if ((exclude != None) and (key in exclude)):
|
||||
continue
|
||||
if (printed and ((flags & PRINT_OBJ_COMPACT) == 0)):
|
||||
print >> out
|
||||
printObject(out, object.__dict__, indent=indent, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||
else:
|
||||
keys = object.__dict__.keys()
|
||||
keys.sort()
|
||||
for n in keys:
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
print >> out
|
||||
printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
|
||||
n = nameToString(key, flags)
|
||||
printed = printObject(out, getattr(object, n), name=n, indent=indent+2, flags=flags, exclude=exclude, remove=remove, maxIndent=maxIndent)
|
||||
if ((flags & PRINT_OBJ_COMPACT) == 0):
|
||||
print >> out
|
||||
print >> out, " "*indent, "}",
|
||||
elif (indent < 0):
|
||||
print >> out, object,
|
||||
elif isinstance(object, basestring):
|
||||
if ((exclude != None) and name in exclude):
|
||||
print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
|
||||
print >> out, " "*indent, name, " : ", typeToString(object, flags), " of length = ", len(object), " (excluded)",
|
||||
elif (len(object) > 100):
|
||||
print >> out, " "*indent, name, ":", toTypeString(object), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]),
|
||||
object = toString(object, flags)
|
||||
print >> out, " "*indent, name, ":", typeToString(object, flags), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]),
|
||||
else:
|
||||
print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
|
||||
print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags),
|
||||
## elif (isinstance(object, float)):
|
||||
## val = str(object)
|
||||
## if (len(val) > 17):
|
||||
## val = val[:17]
|
||||
## print >> out, " "*indent, name, ":", type(object), "=", val,
|
||||
else:
|
||||
print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
|
||||
print >> out, " "*indent, name, ":", typeToString(object, flags), "=", toString(object, flags),
|
||||
if (finalNewLine):
|
||||
print >> out
|
||||
return printed
|
||||
|
||||
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
|
||||
111
wxPython/samples/ide/activegrid/util/strutils.py
Normal file
111
wxPython/samples/ide/activegrid/util/strutils.py
Normal file
@@ -0,0 +1,111 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: strutils.py
|
||||
# Purpose: String Utilities
|
||||
#
|
||||
# Author: Morgan Hua
|
||||
#
|
||||
# Created: 11/3/05
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
|
||||
def caseInsensitiveCompare(s1, s2):
|
||||
""" Method used by sort() to sort values in case insensitive order """
|
||||
s1L = s1.lower()
|
||||
s2L = s2.lower()
|
||||
if s1L == s2L:
|
||||
return 0
|
||||
elif s1L < s2L:
|
||||
return -1
|
||||
else:
|
||||
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
|
||||
116
wxPython/samples/ide/activegrid/util/sysutils.py
Normal file
116
wxPython/samples/ide/activegrid/util/sysutils.py
Normal file
@@ -0,0 +1,116 @@
|
||||
#----------------------------------------------------------------------------
|
||||
# Name: sysutils.py
|
||||
# Purpose: System Utilities
|
||||
#
|
||||
# Author: Joel Hare
|
||||
#
|
||||
# Created: 7/28/04
|
||||
# CVS-ID: $Id$
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
import sys
|
||||
import os
|
||||
import time
|
||||
|
||||
# this will be set to true in IDE.py when we are running release builds.
|
||||
isRelease = False
|
||||
|
||||
# Commented out for now.....
|
||||
# Required for Unicode support with python
|
||||
# Put over here because of py2exe problems
|
||||
# Python suggests modifying site.py
|
||||
#if hasattr(sys,"setdefaultencoding"):
|
||||
# sys.setdefaultencoding("UTF-8")
|
||||
|
||||
|
||||
MAINMODULE_DIR = "AG_MAINMODULE_DIR"
|
||||
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():
|
||||
return 'true' == (str(os.getenv(IS_RELEASE)).lower())
|
||||
|
||||
def setRelease(value):
|
||||
if value:
|
||||
os.environ[IS_RELEASE]= "TRUE"
|
||||
else:
|
||||
os.environ[IS_RELEASE]= "FALSE"
|
||||
|
||||
def isWindows():
|
||||
return os.name == 'nt'
|
||||
|
||||
__isServer = False
|
||||
|
||||
def setServerMode(isServer):
|
||||
global __isServer
|
||||
__isServer = isServer
|
||||
|
||||
def isServer():
|
||||
global __isServer
|
||||
return __isServer
|
||||
|
||||
def _generateMainModuleDir():
|
||||
mainModuleDir = os.getenv(MAINMODULE_DIR)
|
||||
if mainModuleDir: # if environment variable set, return it
|
||||
return mainModuleDir
|
||||
|
||||
# On Mac, the python executable sometimes has a capital "P" so we need to
|
||||
# lower the string first
|
||||
sysExecLower = sys.executable.lower()
|
||||
if sysExecLower == "/" or sysExecLower.find('python') != -1 or sysExecLower.find('apache') != -1:
|
||||
utilModuleDir = os.path.dirname(__file__)
|
||||
if not os.path.isabs(utilModuleDir):
|
||||
utilModuleDir = os.path.join(os.getcwd(), utilModuleDir)
|
||||
mainModuleDir = os.path.normpath(os.path.join(utilModuleDir, os.path.join(os.path.pardir, os.path.pardir)))
|
||||
if mainModuleDir.endswith('.zip'):
|
||||
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
|
||||
else:
|
||||
mainModuleDir = os.path.dirname(sys.executable)
|
||||
|
||||
os.environ[MAINMODULE_DIR] = mainModuleDir # pythonBug: os.putenv doesn't work, set environment variable
|
||||
|
||||
return mainModuleDir
|
||||
|
||||
mainModuleDir = _generateMainModuleDir()
|
||||
|
||||
def _generatePythonExecPath():
|
||||
# On Mac, the python executable sometimes has a capital "P" so we need to
|
||||
# lower the string first
|
||||
sysExecLower = sys.executable.lower()
|
||||
if sysExecLower.find('python') != -1 or sysExecLower.find('apache') != -1:
|
||||
pythonExecPath = sys.executable
|
||||
else:
|
||||
# this is where py2app puts the Python executable
|
||||
if sys.platform == "darwin":
|
||||
pythonExecPath = os.path.join(os.path.dirname(sys.executable), "../Frameworks/Python.Framework/Versions/2.4/Python/bin")
|
||||
else:
|
||||
pythonExecPath = os.path.join(os.path.dirname(sys.executable), '3rdparty\python2.4\python')
|
||||
return pythonExecPath
|
||||
|
||||
pythonExecPath = _generatePythonExecPath()
|
||||
|
||||
def getCommandNameForExecPath(execPath):
|
||||
if isWindows():
|
||||
return '"%s"' % 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)
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,8 +9,10 @@
|
||||
# Copyright: (c) 2004-2005 ActiveGrid, Inc.
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
import xml.sax
|
||||
from activegrid.util.lang import *
|
||||
ifDefPy()
|
||||
import xml.sax
|
||||
endIfDef()
|
||||
|
||||
class XMLPrettyPrinter(xml.sax.ContentHandler):
|
||||
def __init__(self, indentationChar=' ', newlineChar='\n'):
|
||||
|
||||
@@ -10,80 +10,258 @@
|
||||
# License: wxWindows License
|
||||
#----------------------------------------------------------------------------
|
||||
|
||||
from activegrid.util.lang import *
|
||||
import os
|
||||
import time
|
||||
import urllib
|
||||
import logging
|
||||
from activegrid.util.lang import *
|
||||
import activegrid.util.objutils as objutils
|
||||
import activegrid.util.xmlmarshaller as xmlmarshaller
|
||||
import activegrid.util.aglogging as aglogging
|
||||
|
||||
agKnownTypes = None
|
||||
|
||||
def defaultLoad(fileObject, knownTypes=None):
|
||||
xml = fileObject.read()
|
||||
loadedObject = unmarshal(xml, knownTypes=knownTypes)
|
||||
if hasattr(fileObject, 'name'):
|
||||
loadedObject.fileName = os.path.abspath(fileObject.name)
|
||||
loadedObject.initialize()
|
||||
xmlLogger = logging.getLogger("activegrid.util.xml")
|
||||
|
||||
def load(fileName, knownTypes=None, knownNamespaces=None, createGenerics=False):
|
||||
loadedObject = None
|
||||
fileObject = file(fileName)
|
||||
timeStart = time.time()
|
||||
xml = ""
|
||||
try:
|
||||
xml = fileObject.read()
|
||||
loadedObject = unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=fileName, createGenerics=createGenerics)
|
||||
loadedObject.fileName = os.path.abspath(fileName)
|
||||
if hasattr(loadedObject, 'initialize'):
|
||||
loadedObject.initialize()
|
||||
finally:
|
||||
fileObject.close()
|
||||
if xmlLogger.isEnabledFor(aglogging.LEVEL_INFO):
|
||||
timeDone = time.time()
|
||||
aglogging.info(xmlLogger, ('Load statistics for file %s (%d bytes): elapsed time = %f secs' % (fileName, len(xml), timeDone-timeStart)))
|
||||
return loadedObject
|
||||
|
||||
def unmarshal(xml, knownTypes=None):
|
||||
if not knownTypes: knownTypes = getAgKnownTypes()
|
||||
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
||||
def loadURI(uri, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||
loadedObject = None
|
||||
timeStart = time.time()
|
||||
xml = ""
|
||||
try:
|
||||
xml = urllib.urlopen(uri).read()
|
||||
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
|
||||
|
||||
def defaultSave(fileObject, objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
|
||||
xml = marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
|
||||
fileObject.write(xml)
|
||||
fileObject.flush()
|
||||
def unmarshal(xml, knownTypes=None, knownNamespaces=None, xmlSource=None, createGenerics=False):
|
||||
if (knownTypes == None):
|
||||
knownTypes, knownNamespaces = getAgKnownTypes()
|
||||
return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces, xmlSource=xmlSource, createGenerics=createGenerics)
|
||||
|
||||
def marshal(objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
|
||||
if not knownTypes: knownTypes = getAgKnownTypes()
|
||||
return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
|
||||
def save(fileName, objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
|
||||
if hasattr(objectToSave, '_xmlReadOnly') and objectToSave._xmlReadOnly == True:
|
||||
raise xmlmarshaller.MarshallerException('Error marshalling object to file "%s": object is marked "readOnly" and cannot be written' % (fileName))
|
||||
timeStart = time.time()
|
||||
xml = marshal(objectToSave, prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
|
||||
fileObject = file(fileName, 'w')
|
||||
try:
|
||||
fileObject.write(xml)
|
||||
fileObject.flush()
|
||||
except Exception, errorData:
|
||||
fileObject.close()
|
||||
raise xmlmarshaller.MarshallerException('Error marshalling object to file "%s": %s' % (fileName, str(errorData)))
|
||||
fileObject.close()
|
||||
timeDone = time.time()
|
||||
aglogging.info(xmlLogger, ('Save statistics for file %s: elapsed time = %f secs' % (fileName, timeDone-timeStart)))
|
||||
|
||||
def cloneObject(objectToClone, knownTypes=None, encoding='utf-8'):
|
||||
if not knownTypes: knownTypes = getAgKnownTypes()
|
||||
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
|
||||
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
|
||||
def marshal(objectToSave, prettyPrint=True, marshalType=True, knownTypes=None, knownNamespaces=None, encoding='utf-8'):
|
||||
if (knownTypes == None):
|
||||
knownTypes, knownNamespaces = getAgKnownTypes()
|
||||
return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
|
||||
|
||||
def addNSAttribute(xmlDoc, shortNamespace, longNamespace):
|
||||
if not hasattr(xmlDoc, "__xmlnamespaces__"):
|
||||
xmlDoc.__xmlnamespaces__ = {shortNamespace:longNamespace}
|
||||
elif shortNamespace not in xmlDoc.__xmlnamespaces__:
|
||||
if (hasattr(xmlDoc.__class__, "__xmlnamespaces__")
|
||||
and (xmlDoc.__xmlnamespaces__ is xmlDoc.__class__.__xmlnamespaces__)):
|
||||
xmlDoc.__xmlnamespaces__ = dict(xmlDoc.__xmlnamespaces__)
|
||||
xmlDoc.__xmlnamespaces__[shortNamespace] = longNamespace
|
||||
|
||||
def genShortNS(xmlDoc, longNamespace=None):
|
||||
if not hasattr(xmlDoc, "__xmlnamespaces__"):
|
||||
return "ns1"
|
||||
elif longNamespace != None and longNamespace in xmlDoc.__xmlnamespaces__.items():
|
||||
for key, value in xmlDoc.__xmlnamespaces__.iteritems():
|
||||
if value == longNamespace:
|
||||
return key
|
||||
i = 1
|
||||
while ("ns%d" % i) in xmlDoc.__xmlnamespaces__:
|
||||
i += 1
|
||||
return ("ns%d" % i)
|
||||
|
||||
def genTargetNS(fileName, applicationName=None, type=None):
|
||||
if (applicationName != None):
|
||||
if (type != None):
|
||||
tns = "urn:%s:%s:%s" % (applicationName, type, fileName)
|
||||
else:
|
||||
tns = "urn:%s:%s" % (applicationName, fileName)
|
||||
else:
|
||||
tns = "urn:%s" % fileName
|
||||
return tns
|
||||
|
||||
def splitType(typeName):
|
||||
index = typeName.rfind(':')
|
||||
if index != -1:
|
||||
ns = typeName[:index]
|
||||
complexTypeName = typeName[index+1:]
|
||||
else:
|
||||
ns = None
|
||||
complexTypeName = typeName
|
||||
return (ns, complexTypeName)
|
||||
|
||||
def cloneObject(objectToClone, knownTypes=None, marshalType=True, knownNamespaces=None, encoding='utf-8'):
|
||||
if (knownTypes == None):
|
||||
knownTypes, knownNamespaces = getAgKnownTypes()
|
||||
xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, marshalType=marshalType, knownTypes=knownTypes, knownNamespaces=knownNamespaces, encoding=encoding)
|
||||
clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes, knownNamespaces=knownNamespaces)
|
||||
if hasattr(objectToClone, 'fileName'):
|
||||
clonedObject.fileName = objectToClone.fileName
|
||||
if hasattr(objectToClone, "_parentDoc"):
|
||||
clonedObject._parentDoc = objectToClone._parentDoc
|
||||
try:
|
||||
clonedObject.initialize()
|
||||
except AttributeError:
|
||||
pass
|
||||
return clonedObject
|
||||
|
||||
def getAgKnownTypes():
|
||||
import activegrid.model.processmodel
|
||||
import activegrid.model.schema
|
||||
import activegrid.data.dataservice
|
||||
import activegrid.server.deployment
|
||||
global agKnownTypes
|
||||
if agKnownTypes == None:
|
||||
tmpAgKnownTypes = {}
|
||||
AG_TYPE_MAPPING = {
|
||||
def getAgVersion(fileName):
|
||||
fileObject = file(fileName)
|
||||
try:
|
||||
xml = fileObject.read()
|
||||
finally:
|
||||
fileObject.close()
|
||||
i = xml.find(' ag:version=')
|
||||
if i >= 0:
|
||||
i += 12
|
||||
else:
|
||||
i2 = xml.find('<ag:')
|
||||
if i2 >= 0:
|
||||
i = xml.find(' version=', i2)
|
||||
if i > 0:
|
||||
i += 9
|
||||
elif xml.find('<project version="10"') >= 0:
|
||||
return "10"
|
||||
else:
|
||||
return None
|
||||
version = None
|
||||
if xml[i:i+1] == '"':
|
||||
j = xml.find('"', i+1)
|
||||
if (j > i+1):
|
||||
version = xml[i+1:j]
|
||||
return version
|
||||
|
||||
|
||||
AG_NS_URL = "http://www.activegrid.com/ag.xsd"
|
||||
BPEL_NS_URL = "http://schemas.xmlsoap.org/ws/2003/03/business-process"
|
||||
HTTP_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/http/"
|
||||
MIME_WSDL_NS_URL = "http://schemas.xmlsoap.org/wsdl/mime/"
|
||||
SOAP_NS_URL = "http://schemas.xmlsoap.org/wsdl/soap/"
|
||||
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/"
|
||||
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"
|
||||
XMLSCHEMA_NS_URL = "http://www.w3.org/2001/XMLSchema"
|
||||
XSI_NS_URL = "http://www.w3.org/2001/XMLSchema-instance"
|
||||
XACML_NS_URL = "urn:oasis:names:tc:xacml:2.0:policy:schema:os"
|
||||
|
||||
KNOWN_NAMESPACES = { AG_NS_URL : "ag",
|
||||
BPEL_NS_URL : "bpws",
|
||||
HTTP_WSDL_NS_URL : "http",
|
||||
MIME_WSDL_NS_URL : "mime",
|
||||
SOAP_NS_URL : "soap",
|
||||
SOAP12_NS_URL : "soap12",
|
||||
WSDL_NS_URL : "wsdl",
|
||||
WSSE_NS_URL : "wsse",
|
||||
XFORMS_NS_URL : "xforms",
|
||||
XMLSCHEMA_NS_URL : "xs",
|
||||
XACML_NS_URL : "xacml",
|
||||
}
|
||||
|
||||
global agXsdToClassName
|
||||
agXsdToClassName = None
|
||||
def getAgXsdToClassName():
|
||||
global agXsdToClassName
|
||||
if (agXsdToClassName == None):
|
||||
agXsdToClassName = {
|
||||
"ag:append" : "activegrid.model.processmodel.AppendOperation",
|
||||
"ag:attribute" : "activegrid.model.identitymodel.Attribute",
|
||||
"ag:body" : "activegrid.model.processmodel.Body",
|
||||
"ag:cssRule" : "activegrid.model.processmodel.CssRule",
|
||||
"ag:category_substitutions" : "activegrid.server.layoutrenderer.CategorySubstitutions",
|
||||
"ag:command" : "activegrid.model.wsdl.Command",
|
||||
"ag:setElement" : "activegrid.model.processmodel.SetElementOperation",
|
||||
"ag:css" : "activegrid.server.layoutrenderer.CSS",
|
||||
"ag:databaseService" : "activegrid.server.deployment.DatabaseService",
|
||||
"ag:datasource" : "activegrid.data.dataservice.DataSource",
|
||||
"ag:dataObjectList" : "activegrid.data.datalang.DataObjectList",
|
||||
"ag:debug" : "activegrid.model.processmodel.DebugOperation",
|
||||
"ag:deployment" : "activegrid.server.deployment.Deployment",
|
||||
"ag:glue" : "activegrid.model.processmodel.Glue",
|
||||
"ag:formData" : "activegrid.model.processmodel.FormData",
|
||||
"ag:formVar" : "activegrid.model.processmodel.FormVar",
|
||||
"ag:generator" : "activegrid.server.layoutrenderer.SerializableGenerator",
|
||||
"ag:head" : "activegrid.server.layoutrenderer.Head",
|
||||
"ag:hr" : "activegrid.model.processmodel.HorizontalRow",
|
||||
"ag:identity" : "activegrid.model.identitymodel.Identity",
|
||||
"ag:identityref" : "activegrid.server.deployment.IdentityRef",
|
||||
"ag:image" : "activegrid.model.processmodel.Image",
|
||||
"ag:inputs" : "activegrid.model.processmodel.Inputs",
|
||||
"ag:inputPart" : "activegrid.model.processmodel.InputPart",
|
||||
"ag:keystore" : "activegrid.model.identitymodel.KeyStore",
|
||||
"ag:label" : "activegrid.model.processmodel.Label",
|
||||
"ag:processmodel" : "activegrid.model.processmodel.ProcessModel",
|
||||
"ag:processmodelref" : "activegrid.server.deployment.ProcessModelRef",
|
||||
"ag:layout" : "activegrid.server.layoutrenderer.Layout",
|
||||
"ag:layouts" : "activegrid.server.layoutrenderer.Layouts",
|
||||
"ag:ldapsource" : "activegrid.model.identitymodel.LDAPSource",
|
||||
"ag:localService" : "activegrid.server.deployment.LocalService",
|
||||
"ag:parameter" : "activegrid.server.layoutrenderer.Parameter",
|
||||
"ag:parameters" : "activegrid.server.layoutrenderer.Parameters",
|
||||
"ag:postInitialize" : "activegrid.model.processmodel.PostInitialize",
|
||||
"ag:processref" : "activegrid.server.deployment.ProcessRef",
|
||||
"ag:query" : "activegrid.model.processmodel.Query",
|
||||
"ag:restParameter" : "activegrid.server.deployment.RestParameter",
|
||||
"ag:soapService" : "activegrid.server.deployment.SoapService",
|
||||
"ag:redirect" : "activegrid.server.layoutrenderer.Redirect",
|
||||
"ag:requiredFile" : "activegrid.server.layoutrenderer.RequiredFile",
|
||||
"ag:resource" : "activegrid.model.identitymodel.IDResource",
|
||||
"ag:restService" : "activegrid.server.deployment.RestService",
|
||||
"ag:rewrite" : "activegrid.model.wsdl.Rewrite",
|
||||
"ag:role" : "activegrid.model.identitymodel.IDRole",
|
||||
"ag:roledefn" : "activegrid.model.identitymodel.RoleDefn",
|
||||
"ag:rssService" : "activegrid.server.deployment.RssService",
|
||||
"ag:rule" : "activegrid.model.identitymodel.IDRule",
|
||||
"ag:schemaOptions" : "activegrid.model.schema.SchemaOptions",
|
||||
"ag:schemaref" : "activegrid.server.deployment.SchemaRef",
|
||||
"ag:serviceCache" : "activegrid.server.deployment.ServiceCache",
|
||||
"ag:serviceExtension": "activegrid.model.wsdl.ServiceExtension",
|
||||
"ag:serviceExtensions": "activegrid.model.wsdl.ServiceExtensions",
|
||||
"ag:serviceParameter": "activegrid.server.deployment.ServiceParameter",
|
||||
"ag:serviceref" : "activegrid.server.deployment.ServiceRef",
|
||||
"ag:set" : "activegrid.model.processmodel.SetOperation",
|
||||
"ag:skinref" : "activegrid.server.deployment.SkinRef",
|
||||
"ag:skin" : "activegrid.server.layoutrenderer.Skin",
|
||||
"ag:skin_element_ref": "activegrid.server.layoutrenderer.SkinElementRef",
|
||||
"ag:skin_element" : "activegrid.server.layoutrenderer.SkinElement",
|
||||
"ag:skins" : "activegrid.server.layoutrenderer.Skins",
|
||||
"ag:substitution" : "activegrid.server.layoutrenderer.Substitution",
|
||||
"ag:text" : "activegrid.model.processmodel.Text",
|
||||
"ag:title" : "activegrid.model.processmodel.Title",
|
||||
"ag:view" : "activegrid.model.processmodel.View",
|
||||
"ag:usertemplate" : "activegrid.model.identitymodel.UserTemplate",
|
||||
"ag:xformref" : "activegrid.server.deployment.XFormRef",
|
||||
"bpws:case" : "activegrid.model.processmodel.BPELCase",
|
||||
"bpws:catch" : "activegrid.model.processmodel.BPELCatch",
|
||||
"bpws:faultHandlers" : "activegrid.model.processmodel.BPELFaultHandlers",
|
||||
"bpws:flow" : "activegrid.model.processmodel.BPELFlow",
|
||||
"bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
|
||||
"bpws:onMessage" : "activegrid.model.processmodel.BPELOnMessage",
|
||||
"bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
|
||||
@@ -98,31 +276,128 @@ def getAgKnownTypes():
|
||||
"bpws:variable" : "activegrid.model.processmodel.BPELVariable",
|
||||
"bpws:variables" : "activegrid.model.processmodel.BPELVariables",
|
||||
"bpws:while" : "activegrid.model.processmodel.BPELWhile",
|
||||
"wsdl:message" : "activegrid.model.processmodel.WSDLMessage",
|
||||
"wsdl:part" : "activegrid.model.processmodel.WSDLPart",
|
||||
"http:address" : "activegrid.model.wsdl.HttpAddress",
|
||||
"http:binding" : "activegrid.model.wsdl.HttpBinding",
|
||||
"http:operation" : "activegrid.model.wsdl.HttpOperation",
|
||||
"http:urlEncoded" : "activegrid.model.wsdl.HttpUrlEncoded",
|
||||
"mime:content" : "activegrid.model.wsdl.MimeContent",
|
||||
"mime:mimeXml" : "activegrid.model.wsdl.MimeMimeXml",
|
||||
"soap:address" : "activegrid.model.wsdl.SoapAddress",
|
||||
"soap:binding" : "activegrid.model.wsdl.SoapBinding",
|
||||
"soap:body" : "activegrid.model.wsdl.SoapBody",
|
||||
"soap:fault" : "activegrid.model.wsdl.SoapFault",
|
||||
"soap:header" : "activegrid.model.wsdl.SoapHeader",
|
||||
"soap:operation" : "activegrid.model.wsdl.SoapOperation",
|
||||
"soap12:address" : "activegrid.model.wsdl.Soap12Address",
|
||||
"soap12:binding" : "activegrid.model.wsdl.Soap12Binding",
|
||||
"soap12:body" : "activegrid.model.wsdl.Soap12Body",
|
||||
"soap12:fault" : "activegrid.model.wsdl.Soap12Fault",
|
||||
"soap12:header" : "activegrid.model.wsdl.Soap12Header",
|
||||
"soap12:operation" : "activegrid.model.wsdl.Soap12Operation",
|
||||
"wsdl:binding" : "activegrid.model.wsdl.WsdlBinding",
|
||||
"wsdl:definitions" : "activegrid.model.wsdl.WsdlDocument",
|
||||
"wsdl:documentation" : "activegrid.model.wsdl.WsdlDocumentation",
|
||||
"wsdl:fault" : "activegrid.model.wsdl.WsdlFault",
|
||||
"wsdl:import" : "activegrid.model.wsdl.WsdlImport",
|
||||
"wsdl:input" : "activegrid.model.wsdl.WsdlInput",
|
||||
"wsdl:message" : "activegrid.model.wsdl.WsdlMessage",
|
||||
"wsdl:operation" : "activegrid.model.wsdl.WsdlOperation",
|
||||
"wsdl:output" : "activegrid.model.wsdl.WsdlOutput",
|
||||
"wsdl:part" : "activegrid.model.wsdl.WsdlPart",
|
||||
"wsdl:port" : "activegrid.model.wsdl.WsdlPort",
|
||||
"wsdl:portType" : "activegrid.model.wsdl.WsdlPortType",
|
||||
"wsdl:service" : "activegrid.model.wsdl.WsdlService",
|
||||
"wsdl:types" : "activegrid.model.wsdl.WsdlTypes",
|
||||
"xacml:Action" : "activegrid.model.identitymodel.XACMLAction",
|
||||
"xacml:ActionAttributeDesignator" : "activegrid.model.identitymodel.XACMLActionAttributeDesignator",
|
||||
"xacml:ActionMatch" : "activegrid.model.identitymodel.XACMLActionMatch",
|
||||
"xacml:Actions" : "activegrid.model.identitymodel.XACMLActions",
|
||||
"xacml:AttributeValue" : "activegrid.model.identitymodel.XACMLAttributeValue",
|
||||
"xacml:Policy" : "activegrid.model.identitymodel.XACMLPolicy",
|
||||
"xacml:Resource" : "activegrid.model.identitymodel.XACMLResource",
|
||||
"xacml:ResourceAttributeDesignator" : "activegrid.model.identitymodel.XACMLResourceAttributeDesignator",
|
||||
"xacml:ResourceMatch" : "activegrid.model.identitymodel.XACMLResourceMatch",
|
||||
"xacml:Resources" : "activegrid.model.identitymodel.XACMLResources",
|
||||
"xacml:Rule" : "activegrid.model.identitymodel.XACMLRule",
|
||||
"xacml:Target" : "activegrid.model.identitymodel.XACMLTarget",
|
||||
"xforms:copy" : "activegrid.model.processmodel.XFormsCopy",
|
||||
"xforms:group" : "activegrid.model.processmodel.XFormsGroup",
|
||||
"xforms:include" : "activegrid.model.processmodel.XFormsInclude",
|
||||
"xforms:input" : "activegrid.model.processmodel.XFormsInput",
|
||||
"xforms:item" : "activegrid.model.processmodel.XFormsItem",
|
||||
"xforms:itemset" : "activegrid.model.processmodel.XFormsItemset",
|
||||
"xforms:label" : "activegrid.model.processmodel.XFormsLabel",
|
||||
"xforms:model" : "activegrid.model.processmodel.XFormsModel",
|
||||
"xforms:output" : "activegrid.model.processmodel.XFormsOutput",
|
||||
"xforms:secret" : "activegrid.model.processmodel.XFormsSecret",
|
||||
"xforms:select1" : "activegrid.model.processmodel.XFormsSelect1",
|
||||
"xforms:submission" : "activegrid.model.processmodel.XFormsSubmission",
|
||||
"xforms:submit" : "activegrid.model.processmodel.XFormsSubmit",
|
||||
"xforms:value" : "activegrid.model.processmodel.XFormsValue",
|
||||
"xforms:xform" : "activegrid.model.processmodel.View",
|
||||
"xforms:xforms" : "activegrid.model.processmodel.XFormsRoot",
|
||||
"xs:all" : "activegrid.model.schema.XsdSequence",
|
||||
"xs:any" : "activegrid.model.schema.XsdAny",
|
||||
"xs:anyAttribute" : "activegrid.model.schema.XsdAnyAttribute",
|
||||
"xs:attribute" : "activegrid.model.schema.XsdAttribute",
|
||||
"xs:choice" : "activegrid.model.schema.XsdChoice",
|
||||
"xs:complexContent" : "activegrid.model.schema.XsdComplexContent",
|
||||
"xs:complexType" : "activegrid.model.schema.XsdComplexType",
|
||||
"xs:documentation" : "activegrid.model.schema.XsdDocumentation",
|
||||
"xs:element" : "activegrid.model.schema.XsdElement",
|
||||
"xs:enumeration" : "activegrid.model.schema.XsdFacetEnumeration",
|
||||
"xs:extension" : "activegrid.model.schema.XsdExtension",
|
||||
"xs:fractionDigits" : "activegrid.model.schema.XsdFacetFractionDigits",
|
||||
"xs:field" : "activegrid.model.schema.XsdKeyField",
|
||||
"xs:import" : "activegrid.model.schema.XsdInclude",
|
||||
"xs:include" : "activegrid.model.schema.XsdInclude",
|
||||
"xs:key" : "activegrid.model.schema.XsdKey",
|
||||
"xs:keyref" : "activegrid.model.schema.XsdKeyRef",
|
||||
"xs:length" : "activegrid.model.schema.XsdFacetLength",
|
||||
"xs:list" : "activegrid.model.schema.XsdList",
|
||||
"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:schema" : "activegrid.model.schema.Schema",
|
||||
"xs:selector" : "activegrid.model.schema.XsdKeySelector",
|
||||
"xs:sequence" : "activegrid.model.schema.XsdSequence",
|
||||
}
|
||||
|
||||
for keyName, className in AG_TYPE_MAPPING.iteritems():
|
||||
try:
|
||||
tmpAgKnownTypes[keyName] = objutils.classForName(className)
|
||||
except KeyError:
|
||||
print "Error mapping knownType", className
|
||||
pass
|
||||
if len(tmpAgKnownTypes) > 0:
|
||||
agKnownTypes = tmpAgKnownTypes
|
||||
return agKnownTypes
|
||||
"xs:simpleContent" : "activegrid.model.schema.XsdSimpleContent",
|
||||
"xs:simpleType" : "activegrid.model.schema.XsdSimpleType",
|
||||
"xs:totalDigits" : "activegrid.model.schema.XsdFacetTotalDigits",
|
||||
"xs:whiteSpace" : "activegrid.model.schema.XsdFacetWhiteSpace",
|
||||
}
|
||||
return agXsdToClassName
|
||||
|
||||
global agKnownTypes
|
||||
agKnownTypes = None
|
||||
def getAgKnownTypes():
|
||||
global agKnownTypes
|
||||
if agKnownTypes == None:
|
||||
try:
|
||||
tmpAgKnownTypes = {}
|
||||
import activegrid.model.processmodel
|
||||
import activegrid.model.schema
|
||||
import activegrid.server.deployment
|
||||
import activegrid.model.wsdl
|
||||
ifDefPy()
|
||||
import activegrid.data.dataservice
|
||||
endIfDef()
|
||||
for keyName, className in getAgXsdToClassName().iteritems():
|
||||
classType = objutils.classForName(className)
|
||||
if (classType == None):
|
||||
raise Exception("Cannot get class type for %s" % className)
|
||||
else:
|
||||
tmpAgKnownTypes[keyName] = classType
|
||||
if len(tmpAgKnownTypes) > 0:
|
||||
agKnownTypes = tmpAgKnownTypes
|
||||
except ImportError:
|
||||
agKnownTypes = {}
|
||||
if len(agKnownTypes) == 0: # standalone IDE and XmlMarshaller don't contain known AG types
|
||||
noKnownNamespaces = {}
|
||||
return agKnownTypes, noKnownNamespaces
|
||||
return agKnownTypes, KNOWN_NAMESPACES
|
||||
|
||||
Reference in New Issue
Block a user