DocView and ActiveGrid IDE updates from Morgan Hua:

New Features: In Tab-View mode, Ctrl-number will take the user to
    the numbered tab view.  Modified files now show an '*' astrisk in
    the view title.  Debugger framework can now support PHP debugging.
    Not important for python development, but at least that means the
    debugger framework is more generalized.


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@38852 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-04-20 06:26:03 +00:00
parent ea5449ae51
commit aca310e5cc
41 changed files with 11425 additions and 4018 deletions

View File

@@ -5,7 +5,7 @@
# Author: Morgan Hua
#
# Created: 3/22/05
# Copyright: (c) 2005 ActiveGrid, Inc.
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
# CVS-ID: $Id$
# License: wxWindows License
#----------------------------------------------------------------------------
@@ -30,23 +30,25 @@ licenseData = [ # add licenses for base IDE features
("Python 2.4", "Python Software Foundation License", "http://www.python.org/2.4/license.html"),
("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"),
("pychecker", "MetaSlash - BSD", "http://pychecker.sourceforge.net/COPYRIGHT"),
("process.py", "See file", "http://starship.python.net/~tmick/"),
("pysvn", "Apache License, Version 2.0", "http://pysvn.tigris.org/"),
]
if not ACTIVEGRID_BASE_IDE: # add licenses for non-base IDE features such as database connections
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://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__': # add Windows only licenses
@@ -70,7 +72,7 @@ class AboutDialog(wx.Dialog):
else:
splash_bmp = getIDESplashBitmap()
# find version number from
# find version number from
versionFilepath = os.path.join(sysutilslib.mainModuleDir, "version.txt")
if os.path.exists(versionFilepath):
versionfile = open(versionFilepath, 'r')
@@ -82,7 +84,7 @@ class AboutDialog(wx.Dialog):
image = wx.StaticBitmap(aboutPage, -1, splash_bmp, (0,0), (splash_bmp.GetWidth(), splash_bmp.GetHeight()))
sizer.Add(image, 0, wx.ALIGN_CENTER|wx.ALL, 0)
sizer.Add(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\n%s\n\nCopyright (c) 2003-2005 ActiveGrid Incorporated and Contributors. All rights reserved.") % version), 0, wx.ALIGN_LEFT|wx.ALL, 10)
sizer.Add(wx.StaticText(aboutPage, -1, wx.GetApp().GetAppName() + _("\n%s\n\nCopyright (c) 2003-2006 ActiveGrid Incorporated and Contributors. All rights reserved.") % version), 0, wx.ALIGN_LEFT|wx.ALL, 10)
sizer.Add(wx.StaticText(aboutPage, -1, _("http://www.activegrid.com")), 0, wx.ALIGN_LEFT|wx.LEFT|wx.BOTTOM, 10)
aboutPage.SetSizer(sizer)
nb.AddPage(aboutPage, _("Copyright"))
@@ -90,15 +92,14 @@ 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
@@ -115,7 +116,7 @@ class AboutDialog(wx.Dialog):
grid.SetCellValue(row, 0, license)
if url:
grid.SetCellValue(row, 1, url)
grid.EnableEditing(False)
grid.EnableDragGridSize(False)
grid.EnableDragColSize(False)
@@ -132,10 +133,10 @@ class AboutDialog(wx.Dialog):
creditsPage = wx.Panel(nb, -1)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(wx.StaticText(creditsPage, -1, _("ActiveGrid Development Team:\n\nLarry Abrahams\nLawrence Bruhmuller\nEric Chu\nBeth Fryer\nMatt Fryer\nJoel Hare\nMorgan Hua\nMatt McNulty\nPratik Mehta\nAlan Mullendore\nJeff Norton\nSimon Toens\nKevin Wang\nPeter Yared")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
sizer.Add(wx.StaticText(creditsPage, -1, _("ActiveGrid Development Team:\n\nLarry Abrahams\nLawrence Bruhmuller\nEric Chu\nBeth Fryer\nMatt Fryer\nFrankie Fu\nJoel Hare\nMorgan Hua\nMatt McNulty\nPratik Mehta\nAlan Mullendore\nJeff Norton\nKevin Ollivier\nMatt Small\nSimon Toens\nKevin Wang\nPeter Yared\nJeremy Yun")), 0, wx.ALIGN_LEFT|wx.ALL, 10)
creditsPage.SetSizer(sizer)
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)
@@ -145,5 +146,5 @@ class AboutDialog(wx.Dialog):
self.Layout()
self.Fit()
grid.ForceRefresh() # wxBug: Get rid of unnecessary scrollbars

View File

@@ -36,6 +36,7 @@ PARKING_VERTICAL = 1
PARKING_HORIZONTAL = 2
PARKING_OFFSET = 30 # space between shapes
FORCE_REDRAW_METHOD = "ForceRedraw"
def GetRawModel(model):
if hasattr(model, "GetRawModel"):
@@ -85,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):
@@ -195,6 +197,16 @@ class CanvasView(wx.lib.docview.View):
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:
@@ -211,6 +223,7 @@ class CanvasView(wx.lib.docview.View):
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
@@ -260,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)
@@ -274,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)
@@ -401,8 +418,20 @@ class CanvasView(wx.lib.docview.View):
dc.EndDrawing()
def SetValetParking(self, enable=True):
""" If valet parking is enabled, remember last parking spot and try for a spot near it """
self._valetParking = enable
if enable:
self._valetPosition = None
def FindParkingSpot(self, width, height, parking=PARKING_HORIZONTAL, x=PARKING_OFFSET, y=PARKING_OFFSET):
""" given a width and height, find a upper left corner where shape can be parked without overlapping other shape """
"""
Given a width and height, find a upper left corner where shape can be parked without overlapping other shape
"""
if self._valetParking and self._valetPosition:
x, y = self._valetPosition
max = 700 # max distance to the right where we'll place tables
noParkingSpot = True
@@ -422,6 +451,9 @@ class CanvasView(wx.lib.docview.View):
else:
noParkingSpot = False
if self._valetParking:
self._valetPosition = (x, y)
return x, y
@@ -518,7 +550,8 @@ class CanvasView(wx.lib.docview.View):
self._diagram.RemoveShape(line)
line.Delete()
shape.RemoveFromCanvas(self._canvas)
if self._canvas:
shape.RemoveFromCanvas(self._canvas)
self._diagram.RemoveShape(shape)
shape.Delete()
@@ -698,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()

View File

@@ -19,7 +19,6 @@ import os
import re
import string
import sys
import DebuggerService
import MarkerService
from UICommon import CaseInsensitiveCompare
_ = wx.GetTranslation
@@ -120,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
@@ -140,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())
@@ -210,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
@@ -232,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
@@ -467,6 +481,9 @@ 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":
@@ -474,6 +491,7 @@ class CodeView(STCTextEditor.TextView):
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)
@@ -623,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)
@@ -635,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)
@@ -657,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)
@@ -693,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()
@@ -715,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)
@@ -859,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

View File

@@ -6,7 +6,7 @@
#
# Created: 5/23/05
# CVS-ID: $ID:$
# Copyright: (c) 2005 ActiveGrid, Inc.
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
@@ -17,27 +17,22 @@ import ProjectEditor
import os
import os.path
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=None):
self.menuItemName = menuItemName
@@ -48,7 +43,7 @@ class Extension:
self.commandPostArgs = ''
self.fileExt = None
self.opOnSelectedFile = True
class ExtensionService(wx.lib.pydocview.DocService):
@@ -60,8 +55,8 @@ class ExtensionService(wx.lib.pydocview.DocService):
def __getExtensionKeyName(extensionName):
return "%s/%s" % (ExtensionService.EXTENSIONS_KEY, extensionName)
__getExtensionKeyName = staticmethod(__getExtensionKeyName)
@@ -79,7 +74,7 @@ class ExtensionService(wx.lib.pydocview.DocService):
cont, value, index = config.GetNextEntry(index)
finally:
config.SetPath(path)
for extensionName in extensionNames:
extensionData = config.Read(self.__getExtensionKeyName(extensionName))
if extensionData:
@@ -112,10 +107,10 @@ class ExtensionService(wx.lib.pydocview.DocService):
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()
@@ -192,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:
@@ -207,24 +202,24 @@ 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.VERTICAL)
extOptionsPanelSizer = wx.BoxSizer(wx.HORIZONTAL)
extCtrlSizer = wx.BoxSizer(wx.VERTICAL)
extCtrlSizer.Add(wx.StaticText(self, -1, _("External Tools:")), 0, wx.BOTTOM, HALF_SPACE)
self._extListBox = wx.ListBox(self, -1, size=(-1,160), style=wx.LB_SINGLE)
self._extListBox = wx.ListBox(self, -1, style=wx.LB_SINGLE)
self.Bind(wx.EVT_LISTBOX, self.OnListBoxSelect, self._extListBox)
extCtrlSizer.Add(self._extListBox, 1, wx.BOTTOM | wx.EXPAND, SPACE)
buttonSizer = wx.GridSizer(cols=2, vgap=5, hgap=10)
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, 1, wx.EXPAND)
@@ -243,21 +238,21 @@ class ExtensionOptionsPanel(wx.Panel):
self._extDetailPanel = wx.Panel(self)
staticBox = wx.StaticBox(self, label=_("Selected External Tool"))
staticBoxSizer = wx.StaticBoxSizer(staticBox, wx.VERTICAL)
extDetailSizer = wx.FlexGridSizer(cols=2, hgap=5, vgap=3)
extDetailSizer = wx.FlexGridSizer(cols=2, vgap=5, hgap=5)
extDetailSizer.AddGrowableCol(1,1)
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")))
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")), flag=wx.ALIGN_CENTER_VERTICAL)
self._menuItemNameTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
extDetailSizer.Add(self._menuItemNameTextCtrl, 0, wx.EXPAND)
self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Description:")))
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Description:")), flag=wx.ALIGN_CENTER_VERTICAL)
self._menuItemDescTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
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.FILE_MUST_EXIST|wx.HIDE_READONLY|wx.CHANGE_DIR)
@@ -276,26 +271,26 @@ class ExtensionOptionsPanel(wx.Panel):
hsizer.Add(findFileButton, 0, wx.LEFT, HALF_SPACE)
extDetailSizer.Add(hsizer, 0, wx.EXPAND)
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Args:")))
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Args:")), flag=wx.ALIGN_CENTER_VERTICAL)
self._commandPreArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
extDetailSizer.Add(self._commandPreArgsTextCtrl, 0, wx.EXPAND)
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Args:")))
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Args:")), flag=wx.ALIGN_CENTER_VERTICAL)
self._commandPostArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
extDetailSizer.Add(self._commandPostArgsTextCtrl, 0, wx.EXPAND)
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions:")))
extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions:")), flag=wx.ALIGN_CENTER_VERTICAL)
self._fileExtTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
self._fileExtTextCtrl.SetToolTipString(_("""For example: "txt, text" (comma separated) or "*" for all files"""))
extDetailSizer.Add(self._fileExtTextCtrl, 0, wx.EXPAND)
self._selFileCtrl = wx.CheckBox(self._extDetailPanel, -1, _("Operate on Selected File"))
extDetailSizer.Add(self._selFileCtrl)
extDetailSizer.Add(self._selFileCtrl, 0, wx.ALIGN_CENTER_VERTICAL|wx.TOP, SPACE)
self._selFileCtrl.SetToolTipString(_("If focus is in the project, instead of operating on the project file, operate on the selected file."))
self._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)
@@ -306,8 +301,8 @@ class ExtensionOptionsPanel(wx.Panel):
self.OnListBoxSelect()
self.Layout()
parent.AddPage(self, _("External Tools"))
parent.AddPage(self, _("External Tools"))
def OnOK(self, optionsDialog):
@@ -323,7 +318,7 @@ class ExtensionOptionsPanel(wx.Panel):
msgTitle,
wx.OK | wx.ICON_INFORMATION,
self.GetParent())
def PopulateItems(self):
extensionsService = wx.GetApp().GetService(ExtensionService)
@@ -335,7 +330,7 @@ class ExtensionOptionsPanel(wx.Panel):
self._currentItem = None
self._currentItemIndex = -1
return len(self._extensions)
def OnListBoxSelect(self, event=None):
self.SaveCurrentItem()
@@ -370,7 +365,7 @@ class ExtensionOptionsPanel(wx.Panel):
else:
extension.fileExt = fileExt.split(',')
extension.opOnSelectedFile = self._selFileCtrl.GetValue()
def LoadItem(self, extension):
if extension:
@@ -401,8 +396,8 @@ class ExtensionOptionsPanel(wx.Panel):
self._fileExtTextCtrl.SetValue('')
self._selFileCtrl.SetValue(True)
self._extDetailPanel.Enable(False)
def OnAdd(self, event):
self.SaveCurrentItem()
name = _("Untitled")
@@ -417,11 +412,11 @@ class ExtensionOptionsPanel(wx.Panel):
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)

View File

@@ -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,7 +89,14 @@ 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)
if projectService.GetFilesFromCurrentProject():
event.Enable(True)
@@ -90,7 +109,7 @@ 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(wx.GetApp().GetTopWindow(), -1, _("Find in Directory"), size= (320,200))
@@ -105,7 +124,7 @@ 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()
@@ -126,10 +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:
@@ -192,13 +211,13 @@ class FindInDirService(FindService.FindService):
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()
@@ -206,52 +225,23 @@ class FindInDirService(FindService.FindService):
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
frame.Destroy()
if status == wx.ID_OK:
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()
@@ -259,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)
@@ -267,27 +257,186 @@ 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:
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(wx.GetApp().GetTopWindow(), -1, _("Find in Project"), size= (320,200))
@@ -336,97 +485,80 @@ class FindInDirService(FindService.FindService):
self.SaveFindConfig(findString, wholeWord, matchCase, regExpr)
frame.Destroy()
if status == wx.ID_OK:
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:
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:
@@ -435,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)
@@ -464,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)

View File

@@ -119,7 +119,7 @@ class HtmlCtrl(CodeEditor.CodeCtrl):
def SetViewDefaults(self):
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = True, hasTabs = True)
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix = "Html", hasWordWrap = True, hasTabs = True, hasFolding=True)
def GetFontAndColorFromConfig(self):
@@ -156,7 +156,7 @@ 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):

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -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,8 +254,110 @@ 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()

View File

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

File diff suppressed because it is too large Load Diff

View File

@@ -25,6 +25,7 @@ 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
@@ -143,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):
@@ -369,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 = True, hasTabs = True)
CodeEditor.CodeCtrl.SetViewDefaults(self, configPrefix="Python", hasWordWrap=True, hasTabs=True, hasFolding=True)
def GetFontAndColorFromConfig(self):
@@ -567,7 +604,7 @@ class PythonOptionsPanel(wx.Panel):
mainSizer = wx.BoxSizer(wx.VERTICAL)
mainSizer.Add(pathSizer, 0, wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, SPACE)
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "Python", label = "Python", hasWordWrap = True, hasTabs = True, addPage=False)
self._otherOptions = STCTextEditor.TextOptionsPanel(self, -1, configPrefix = "Python", label = "Python", hasWordWrap = True, hasTabs = True, addPage=False, hasFolding=True)
mainSizer.Add(self._otherOptions, 0, wx.EXPAND|wx.BOTTOM, SPACE)
self.SetSizer(mainSizer)
parent.AddPage(self, _("Python"))
@@ -577,7 +614,7 @@ class PythonOptionsPanel(wx.Panel):
defaultDir = os.path.dirname(self._pathTextCtrl.GetValue().strip())
defaultFile = os.path.basename(self._pathTextCtrl.GetValue().strip())
if _WINDOWS:
wildcard = _("Executable (*.exe)|*.exe|All (*.*)|*.*")
wildcard = _("Executable (*.exe)|*.exe|All|*.*")
if not defaultFile:
defaultFile = "python.exe"
else:

View File

@@ -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,24 +63,31 @@ 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
@@ -142,6 +155,8 @@ class TextView(wx.lib.docview.View):
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)
@@ -149,6 +164,10 @@ 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)
@@ -161,6 +180,9 @@ class TextView(wx.lib.docview.View):
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":
@@ -571,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.
@@ -813,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()
@@ -854,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))
@@ -874,6 +902,8 @@ 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)
@@ -947,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())
@@ -1062,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
@@ -1237,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

File diff suppressed because it is too large Load Diff

View File

@@ -6,7 +6,7 @@
#
# Created: 3/10/05
# CVS-ID: $Id$
# Copyright: (c) 2005 ActiveGrid, Inc.
# Copyright: (c) 2005-2006 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
@@ -15,12 +15,14 @@ import os.path
import wx
import string
import ProjectEditor
import activegrid.util.sysutils as sysutils
import activegrid.util.strutils as strutils
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=_("File Name:"), dirLabel=_("Directory"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False):
def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory:"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False, useDirDialog=False):
if not choiceDirs:
choiceDirs = []
@@ -61,8 +63,8 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
if os.getcwd() not in choiceDirs:
choiceDirs.append(os.getcwd())
if appdirs.documents_folder not in choiceDirs:
choiceDirs.append(appdirs.documents_folder)
if appdirs.getSystemDir() not in choiceDirs:
choiceDirs.append(appdirs.getSystemDir())
if not startingDirectory:
startingDirectory = os.getcwd()
@@ -85,12 +87,18 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
else:
name = _("%s.%s") % (nameCtrlValue, fileExtension)
dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
if not useDirDialog:
dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
defaultDir = dirControl.GetValue().strip(),
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
@@ -98,49 +106,78 @@ def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Direc
dlg.Destroy()
if path:
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)
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, infoString='', noFirstCharDigit=False):
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 noFirstCharDigit and projName[0].isdigit():
wx.MessageBox(_("File name cannot start with a number. Please enter a different name."), _("Invalid File Name"))
return False
if projName.find(' ') != -1:
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 %sdirectory does not exist. Please choose an existing directory.") % infoString, _("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(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
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)
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
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)
flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
if returnAll:
return nameControl, dirControl, flexGridSizer, Validate, allControls
else:
@@ -188,8 +225,8 @@ def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirecto
if os.getcwd() not in choiceDirs:
choiceDirs.append(os.getcwd())
if appdirs.documents_folder not in choiceDirs:
choiceDirs.append(appdirs.documents_folder)
if appdirs.getSystemDir() not in choiceDirs:
choiceDirs.append(appdirs.getSystemDir())
if not startingDirectory:
@@ -221,6 +258,9 @@ def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirecto
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
@@ -241,17 +281,25 @@ def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectory
fileLabelText = wx.StaticText(parent, -1, fileLabel)
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
def Validate(allowOverwriteOnPrompt=False, noFirstCharDigit=False):
def Validate(allowOverwriteOnPrompt=False, validClassName=False):
projName = nameControl.GetValue().strip()
if projName == "":
wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name"))
return False
if noFirstCharDigit and projName[0].isdigit():
wx.MessageBox(_("Name cannot start with a number. Please enter a valid name."), _("Project Name"))
return False
if projName.find(' ') != -1:
wx.MessageBox(_("Spaces in name. Name cannot have spaces.") % infoString, _("Project Name"))
wx.MessageBox(_("Spaces in name. Name cannot have spaces."), _("Project Name"))
return False
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):
@@ -280,6 +328,29 @@ def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectory
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)
@@ -330,6 +401,16 @@ def GetPythonExecPath():
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
@@ -362,16 +443,62 @@ def CaseInsensitiveCompare(s1, s2):
def GetAnnotation(model, elementName):
""" Get an object's annotation used for tooltips """
if hasattr(model, "__xsdcomplextype__"):
if hasattr(model, "_complexType"):
ct = model._complexType
elif hasattr(model, "__xsdcomplextype__"):
ct = model.__xsdcomplextype__
if ct:
el = ct.findElement(elementName)
if el and el.annotation:
return el.annotation
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
#----------------------------------------------------------------------------
@@ -435,7 +562,8 @@ def GetAppDocMgrForDoc(doc):
def GetAppInfoLanguage(doc=None):
from activegrid.server.deployment import LANGUAGE_DEFAULT
from activegrid.server.projectmodel import LANGUAGE_DEFAULT
if doc:
language = doc.GetAppInfo().language
else:
@@ -449,3 +577,159 @@ def GetAppInfoLanguage(doc=None):
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

View File

@@ -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):
@@ -115,7 +115,7 @@ class XmlCtrl(CodeEditor.CodeCtrl):
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):

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 KiB

View File

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

View File

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

View File

@@ -14,7 +14,16 @@ import copy
import os
import os.path
import activegrid.util.xmlutils as xmlutils
from IDE import ACTIVEGRID_BASE_IDE
import activegrid.util.aglogging as aglogging
# REVIEW 07-Mar-06 stoens@activegrid.com -- Ideally move the pieces required
# to generate the .dpl file out of this module so there's no dependency on wx,
# instead of doing this try/catch (IDE drags in wx).
try:
from IDE import ACTIVEGRID_BASE_IDE
except:
ACTIVEGRID_BASE_IDE = False
if not ACTIVEGRID_BASE_IDE:
import activegrid.model.basedocmgr as basedocmgr
import AppInfo
@@ -27,64 +36,6 @@ if not ACTIVEGRID_BASE_IDE:
PROJECT_VERSION_050730 = '10'
PROJECT_VERSION_050826 = '11'
#----------------------------------------------------------------------------
# XML Marshalling Methods
#----------------------------------------------------------------------------
def load(fileObject):
version = xmlutils.getAgVersion(fileObject.name)
# most current versions on top
if version == PROJECT_VERSION_050826:
fileObject.seek(0)
if ACTIVEGRID_BASE_IDE:
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
else:
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
project = xmlutils.load(fileObject.name, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
elif version == PROJECT_VERSION_050730:
fileObject.seek(0)
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
project = project.upgradeVersion()
else:
# assume it is old version without version number
fileObject.seek(0)
project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
if project:
project = project.upgradeVersion()
else:
print "Project, unknown version:", version
return None
if project:
project._projectDir = os.path.dirname(fileObject.name)
project.RelativeToAbsPath()
return project
def save(fileObject, project, productionDeployment=False):
if not project._projectDir:
project._projectDir = os.path.dirname(fileObject.name)
project.AbsToRelativePath() # temporarily change it to relative paths for saving
if ACTIVEGRID_BASE_IDE:
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
else:
KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
savedHomeDir = project.homeDir
if productionDeployment:
# for deployments, we don't want an abs path in homeDir since that
# would tie the app to the current filesystem. So unset it.
project.homeDir = None
xmlutils.save(fileObject.name, project, prettyPrint=True, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
if productionDeployment:
project.homeDir = savedHomeDir
project.RelativeToAbsPath() # swap it back to absolute path
#----------------------------------------------------------------------------
# Classes
@@ -93,7 +44,7 @@ def save(fileObject, project, productionDeployment=False):
class BaseProject(object):
__xmlname__ = "project"
__xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback')
__xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback', '_cacheEnabled')
__xmlattributes__ = ("_homeDir", "version")
__xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" }
__xmlflattensequence__ = { "_files":("file",) }
@@ -107,9 +58,15 @@ class BaseProject(object):
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()
@@ -117,18 +74,13 @@ class BaseProject(object):
clone._projectDir = self._projectDir
clone._homeDir = self._homeDir
if not ACTIVEGRID_BASE_IDE:
clone._appInfo = self._appInfo
clone._appInfo = copy.copy(self._appInfo)
return clone
def initialize(self):
""" Required method for xmlmarshaller """
pass
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
@@ -138,7 +90,7 @@ class BaseProject(object):
if file:
self._files.append(file)
else:
self._files.append(ProjectFile(filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
self._files.append(ProjectFile(self, filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
def RemoveFile(self, file):
@@ -150,7 +102,7 @@ class BaseProject(object):
for file in self._files:
if file.filePath == filePath:
return file
return None
@@ -160,6 +112,10 @@ class BaseProject(object):
filePaths = property(_GetFilePaths)
def _GetProjectFiles(self):
return self._files
projectFiles = property(_GetProjectFiles)
def _GetLogicalFolders(self):
folders = []
@@ -170,7 +126,7 @@ class BaseProject(object):
logicalFolders = property(_GetLogicalFolders)
def _GetPhysicalFolders(self):
physicalFolders = []
@@ -189,11 +145,11 @@ class BaseProject(object):
return self._homeDir
else:
return self._projectDir
def _SetHomeDir(self, parentPath):
self._homeDir = parentPath
def _IsDefaultHomeDir(self):
return (self._homeDir == None)
@@ -212,7 +168,7 @@ class BaseProject(object):
if relFolder and relFolder not in relativeFolders:
relativeFolders.append(relFolder)
return relativeFolders
def AbsToRelativePath(self):
for file in self._files:
@@ -224,6 +180,33 @@ class BaseProject(object):
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
#----------------------------------------------------------------------------
@@ -231,7 +214,7 @@ class BaseProject(object):
def fullPath(self, fileName):
fileName = super(BaseProject, self).fullPath(fileName)
if os.path.isabs(fileName):
absPath = fileName
elif self.homeDir:
@@ -242,7 +225,7 @@ class BaseProject(object):
def documentRefFactory(self, name, fileType, filePath):
return ProjectFile(filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
return ProjectFile(self, filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
def findAllRefs(self):
@@ -256,8 +239,8 @@ class BaseProject(object):
if not xformdir:
xformdir = self.homeDir
return xformdir
def setRefs(self, files):
self._files = files
@@ -295,16 +278,17 @@ if ACTIVEGRID_BASE_IDE:
else:
class Project(BaseProject, basedocmgr.BaseDocumentMgr):
pass
class ProjectFile(object):
__xmlname__ = "file"
__xmlexclude__ = ('_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
__xmlexclude__ = ('_parentProj', '_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
__xmlattributes__ = ["filePath", "logicalFolder", "type", "name"]
__xmldefaultnamespace__ = xmlutils.AG_NS_URL
def __init__(self, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
def __init__(self, parent=None, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
self._parentProj = parent
self.filePath = filePath
self.logicalFolder = logicalFolder
self.type = type
@@ -316,35 +300,44 @@ class ProjectFile(object):
def _GetDocumentModel(self):
# possible bug is if document gets replaced outside of IDE, where we'll return previous doc.
# originally added a timestamp check but that increased the time again to 4x
if self._docModelCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
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):
# Hack, just return the IDE document wrapper that corresponds to the runtime document model
# callers should have called ".document" before calling ".ideDocument"
if self._docCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
# 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
@@ -356,7 +349,7 @@ class ProjectFile(object):
physicalFolder = property(_GetPhysicalFolder)
def GetRelativeFolder(self, parentPath):
parentPathLen = len(parentPath)
@@ -364,7 +357,7 @@ class ProjectFile(object):
dir = None
if self.filePath:
dir = os.path.dirname(self.filePath)
if dir.startswith(parentPath):
if dir.startswith(parentPath + os.sep):
dir = "." + dir[parentPathLen:] # convert to relative path
if os.sep != '/':
dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
@@ -375,7 +368,7 @@ class ProjectFile(object):
""" Used to convert path to relative path for saving (disk format) """
parentPathLen = len(parentPath)
if self.filePath.startswith(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.
@@ -385,8 +378,8 @@ class ProjectFile(object):
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))
if self.filePath.startswith("./"): # relative to project file
self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath)) # also converts '/' to os.sep
#----------------------------------------------------------------------------
@@ -399,21 +392,29 @@ class ProjectFile(object):
import wx.lib.docview
if not self._doc:
docMgr = wx.GetApp().GetDocumentManager()
doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW)
if (doc == None): # already open
docs = docMgr.GetDocuments()
for d in docs:
if d.GetFilename() == self.filePath:
doc = d
break
self._doc = doc
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.
return self._GetDoc().GetModel().processName
doc = self._GetDoc()
if doc:
return doc.GetModel().processName
else:
return None
processName = property(_GetLocalServiceProcessName)
@@ -458,33 +459,39 @@ class ProjectFile(object):
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.
model = self._GetDoc().GetModel()
doc = self._GetDoc()
if not doc:
return None
model = doc.GetModel()
if hasattr(model, 'serviceType'):
return model.serviceType
else:
@@ -494,25 +501,27 @@ class ProjectFile(object):
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.server.deployment as deploymentlib
import activegrid.model.projectmodel as projectmodel
import wx
import ProjectEditor
appInfo = self._GetDoc().GetAppInfo()
if appInfo.language == None:
language = deploymentlib.LANGUAGE_DEFAULT
language = wx.ConfigBase_Get().Read(ProjectEditor.APP_LAST_LANGUAGE, projectmodel.LANGUAGE_DEFAULT)
else:
language = appInfo.language
if language == deploymentlib.LANGUAGE_PYTHON:
if language == projectmodel.LANGUAGE_PYTHON:
suffix = ".py"
elif language == deploymentlib.LANGUAGE_PHP:
elif language == projectmodel.LANGUAGE_PHP:
suffix = ".php"
pyFilename = self.name + suffix
return self._GetDoc().GetAppDocMgr().fullPath(pyFilename)
@@ -543,7 +552,63 @@ class Project_10:
def upgradeVersion(self):
currModel = Project()
for file in self._files:
currModel._files.append(ProjectFile(file))
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