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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user