Fix for bug #1217874, Error in parameter name in DocManager.CreateView
+Added wrappers for the wx.RendererNative class.
+
Added the wx.lib.splitter module, which contains the
MultiSplitterWindow class. This class is much like the standard
wx.SplitterWindow class, except it allows more than one split, so it
can manage more than two child windows.
+Docview and IDE patch from Morag Hua with fix for bug #1217890
+"Closing view crashes Python" plus some new features::
+
+ New feature added to the IDE is 'Extensions'. Under
+ Tools|Options|Extensions, you can add calls to external programs.
+ For example you can add a "Notepad" extension (under windows) that
+ will exec Notepad on the currently open file. A new "Notepad"
+ menu item will appear under the Tools menu.
+
+
def OnDraw(self, dc):
+ """ For Print and Print Preview """
pass
def OnFocus(self, event):
- self.SetFocus()
self.FocusColorPropertyShape(True)
event.Skip()
+ def FocusOnClick(self, event):
+ self.SetFocus()
+ event.Skip()
+
+
def OnKillFocus(self, event):
self.FocusColorPropertyShape(False)
event.Skip()
wx.EVT_KEY_DOWN(self._canvas, self.OnKeyPressed)
# need this otherwise mouse clicks don't set focus to this view
- wx.EVT_LEFT_DOWN(self._canvas, self.OnFocus)
- wx.EVT_LEFT_DCLICK(self._canvas, self.OnFocus)
- wx.EVT_RIGHT_DOWN(self._canvas, self.OnFocus)
- wx.EVT_RIGHT_DCLICK(self._canvas, self.OnFocus)
- wx.EVT_MIDDLE_DOWN(self._canvas, self.OnFocus)
- wx.EVT_MIDDLE_DCLICK(self._canvas, self.OnFocus)
+ wx.EVT_LEFT_DOWN(self._canvas, self.FocusOnClick)
+ wx.EVT_LEFT_DCLICK(self._canvas, self.FocusOnClick)
+ wx.EVT_RIGHT_DOWN(self._canvas, self.FocusOnClick)
+ wx.EVT_RIGHT_DCLICK(self._canvas, self.FocusOnClick)
+ wx.EVT_MIDDLE_DOWN(self._canvas, self.FocusOnClick)
+ wx.EVT_MIDDLE_DCLICK(self._canvas, self.FocusOnClick)
wx.EVT_KILL_FOCUS(self._canvas, self.OnKillFocus)
wx.EVT_SET_FOCUS(self._canvas, self.OnFocus)
shape.SetBrush(brush)
if text:
shape.AddText(text)
- shape.SetShadowMode(ogl.SHADOW_RIGHT)
+ shape.SetShadowMode(ogl.SHADOW_NONE)
self._diagram.AddShape(shape)
shape.Show(True)
if not eventHandler:
if shape:
shape.Select(False)
+ for line in shape.GetLines():
+ shape.RemoveLine(line)
+ self._diagram.RemoveShape(line)
+ for obj in self._diagram.GetShapeList():
+ for line in obj.GetLines():
+ if self.IsShapeContained(shape, line.GetTo()) or self.IsShapeContained(shape, line.GetFrom()):
+ obj.RemoveLine(line)
+ self._diagram.RemoveShape(line)
+ if line == shape:
+ obj.RemoveLine(line)
+
+ shape.RemoveFromCanvas(self._canvas)
self._diagram.RemoveShape(shape)
- if isinstance(shape, ogl.CompositeShape):
- shape.RemoveFromCanvas(self._canvas)
+
+
+ def IsShapeContained(self, parent, shape):
+ if parent == shape:
+ return True
+ elif shape.GetParent():
+ return self.IsShapeContained(parent, shape.GetParent())
+
+ return False
def UpdateShape(self, model):
sys.stdout = output
sys.stderr = output
try:
- exec command in frame.f_globals, frame.f_locals
+ code = compile(command, '<string>', 'single')
+ exec code in frame.f_globals, frame.f_locals
return output.getvalue()
sys.stdout = out
sys.stderr = err
import DebuggerHarness
import traceback
import StringIO
-
+import UICommon
if wx.Platform == '__WXMSW__':
try:
import win32api
class Executor:
def GetPythonExecutablePath():
- config = wx.ConfigBase_Get()
- path = config.Read("ActiveGridPythonLocation")
+ path = UICommon.GetPythonExecPath()
if path:
return path
wx.MessageBox(_("To proceed I need to know the location of the python.exe you would like to use.\nTo set this, go to Tools-->Options and use the 'Python' tab to enter a value.\n"), _("Python Executable Location Unknown"))
path = Executor.GetPythonExecutablePath()
self._cmd = '"' + path + '" -u \"' + fileName + '\"'
#Better way to do this? Quotes needed for windows file paths.
+ def spaceAndQuote(text):
+ if text.startswith("\"") and text.endswith("\""):
+ return ' ' + text
+ else:
+ return ' \"' + text + '\"'
if(arg1 != None):
- self._cmd += ' \"' + arg1 + '\"'
+ self._cmd += spaceAndQuote(arg1)
if(arg2 != None):
- self._cmd += ' \"' + arg2 + '\"'
+ self._cmd += spaceAndQuote(arg2)
if(arg3 != None):
- self._cmd += ' \"' + arg3 + '\"'
+ self._cmd += spaceAndQuote(arg3)
if(arg4 != None):
- self._cmd += ' \"' + arg4 + '\"'
+ self._cmd += spaceAndQuote(arg4)
if(arg5 != None):
- self._cmd += ' \"' + arg5 + '\"'
+ self._cmd += spaceAndQuote(arg5)
if(arg6 != None):
- self._cmd += ' \"' + arg6 + '\"'
+ self._cmd += spaceAndQuote(arg6)
if(arg7 != None):
- self._cmd += ' \"' + arg7 + '\"'
+ self._cmd += spaceAndQuote(arg7)
if(arg8 != None):
- self._cmd += ' \"' + arg8 + '\"'
+ self._cmd += spaceAndQuote(arg8)
if(arg9 != None):
- self._cmd += ' \"' + arg9 + '\"'
+ self._cmd += spaceAndQuote(arg9)
self._stdOutReader = None
self._stdErrReader = None
self._tb.EnableTool(self.BREAK_INTO_DEBUGGER_ID, False)
self._tb.EnableTool(self.KILL_PROCESS_ID, False)
- def SynchCurrentLine(self, filename, lineNum):
+ def SynchCurrentLine(self, filename, lineNum, noArrow=False):
# FACTOR THIS INTO DocManager
self.DeleteCurrentLineMarkers()
foundView.Activate()
foundView.GotoLine(lineNum)
startPos = foundView.PositionFromLine(lineNum)
-
- foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
+
+ if not noArrow:
+ foundView.GetCtrl().MarkerAdd(lineNum -1, CodeEditor.CodeCtrl.CURRENT_LINE_MARKER_NUM)
def DeleteCurrentLineMarkers(self):
openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
list = self._bpListCtrl
fileName = list.GetItem(self.currentItem, 2).GetText()
lineNumber = list.GetItem(self.currentItem, 1).GetText()
- self._ui.SynchCurrentLine( fileName, int(lineNumber) )
+ self._ui.SynchCurrentLine( fileName, int(lineNumber) , noArrow=True)
def ClearBreakPoint(self, event):
if self.currentItem >= 0:
wsService = wx.GetApp().GetService(WebServerService.WebServerService)
fileName, args = wsService.StopAndPrepareToDebug()
try:
- page = DebugCommandUI(Service.ServiceView.bottomTab, -1, str(fileName), self)
+ page = DebugCommandUI(Service.ServiceView.bottomTab, -1, fileName, self)
count = Service.ServiceView.bottomTab.GetPageCount()
Service.ServiceView.bottomTab.AddPage(page, _("Debugging: Internal WebServer"))
Service.ServiceView.bottomTab.SetSelection(count)
flexGridSizer.Add(self._pythonPathEntry, 1, wx.EXPAND)
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
- if debugging:
+ if debugging and _WINDOWS:
self._postpendCheckBox = wx.CheckBox(self, -1, postpendStaticText)
checked = bool(config.ReadInt("PythonPathPostpend", 1))
self._postpendCheckBox.SetValue(checked)
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: ExtensionService.py
+# Purpose: Extension Service for IDE
+#
+# Author: Peter Yared
+#
+# Created: 5/23/05
+# CVS-ID: $ID:$
+# Copyright: (c) 2005 ActiveGrid, Inc.
+# License: wxWindows License
+#----------------------------------------------------------------------------
+
+import wx
+import wx.lib.pydocview
+import MessageService
+import os
+import os.path
+import pickle
+
+_ = wx.GetTranslation
+
+
+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):
+ self.menuItemName = menuItemName
+ self.id = 0
+ self.menuItemDesc = ''
+ self.command = ''
+ self.commandPreArgs = ''
+ self.commandPostArgs = ''
+ self.fileExt = None
+
+
+class ExtensionService(wx.lib.pydocview.DocService):
+
+
+ def __init__(self):
+ self.LoadExtensions()
+
+
+ def LoadExtensions(self):
+ config = wx.ConfigBase_Get()
+ pickledExtensions = config.Read(EXTENSIONS_CONFIG_STRING)
+ if pickledExtensions:
+ try:
+ self._extensions = pickle.loads(pickledExtensions.encode('ascii'))
+ except:
+ tp, val, tb = sys.exc_info()
+ traceback.print_exception(tp,val,tb)
+ self._extensions = []
+ else:
+ self._extensions = []
+
+
+ def SaveExtensions(self):
+ config = wx.ConfigBase_Get()
+ config.Write(EXTENSIONS_CONFIG_STRING, pickle.dumps(self._extensions))
+
+
+ def GetExtensions(self):
+ return self._extensions
+
+
+ def SetExtensions(self, extensions):
+ self._extensions = extensions
+
+
+ def InstallControls(self, frame, menuBar = None, toolBar = None, statusBar = None, document = None):
+ toolsMenuIndex = menuBar.FindMenu(_("&Tools"))
+ if toolsMenuIndex > -1:
+ toolsMenu = menuBar.GetMenu(toolsMenuIndex)
+ else:
+ toolsMenu = wx.Menu()
+
+ if self._extensions:
+ if toolsMenu.GetMenuItems():
+ toolsMenu.AppendSeparator()
+ for ext in self._extensions:
+ # Append a tool menu item for each extension
+ ext.id = wx.NewId()
+ toolsMenu.Append(ext.id, ext.menuItemName)
+ wx.EVT_MENU(frame, ext.id, frame.ProcessEvent)
+ wx.EVT_UPDATE_UI(frame, ext.id, frame.ProcessUpdateUIEvent)
+
+ if toolsMenuIndex == -1:
+ formatMenuIndex = menuBar.FindMenu(_("&Format"))
+ menuBar.Insert(formatMenuIndex + 1, toolsMenu, _("&Tools"))
+
+ def ProcessEvent(self, event):
+ id = event.GetId()
+ for extension in self._extensions:
+ if id == extension.id:
+ self.OnExecuteExtension(extension)
+ return True
+ return False
+
+
+ def ProcessUpdateUIEvent(self, event):
+ id = event.GetId()
+ for extension in self._extensions:
+ if id == extension.id:
+ if extension.fileExt:
+ doc = wx.GetApp().GetDocumentManager().GetCurrentDocument()
+ if doc and '*' in extension.fileExt:
+ event.Enable(True)
+ return True
+ if doc:
+ for fileExt in extension.fileExt:
+ if fileExt in doc.GetDocumentTemplate().GetFileFilter():
+ event.Enable(True)
+ return True
+ event.Enable(False)
+ return False
+ return False
+
+
+ def OnExecuteExtension(self, extension):
+ if extension.fileExt:
+ doc = wx.GetApp().GetDocumentManager().GetCurrentDocument()
+ if not doc:
+ return
+ filename = doc.GetFilename()
+ ext = os.path.splitext(filename)[1]
+ if not '*' in extension.fileExt:
+ if not ext or ext[1:] not in extension.fileExt:
+ return
+ cmds = [extension.command]
+ if extension.commandPreArgs:
+ cmds.append(extension.commandPreArgs)
+ cmds.append(filename)
+ if extension.commandPostArgs:
+ cmds.append(extension.commandPostArgs)
+ os.spawnv(os.P_NOWAIT, extension.command, cmds)
+
+ else:
+ cmd = extension.command
+ if extension.commandPreArgs:
+ cmd = cmd + ' ' + extension.commandPreArgs
+ if extension.commandPostArgs:
+ cmd = cmd + ' ' + extension.commandPostArgs
+ f = os.popen(cmd)
+ messageService = wx.GetApp().GetService(MessageService.MessageService)
+ messageService.ShowWindow()
+ view = messageService.GetView()
+ for line in f.readlines():
+ view.AddLines(line)
+ view.GetControl().EnsureCaretVisible()
+ f.close()
+
+
+class ExtensionOptionsPanel(wx.Panel):
+
+
+ def __init__(self, parent, id):
+ wx.Panel.__init__(self, parent, id)
+
+ extOptionsPanelBorderSizer = wx.BoxSizer(wx.HORIZONTAL)
+
+ extOptionsPanelSizer = wx.FlexGridSizer(cols=2, hgap=SPACE, vgap=HALF_SPACE)
+
+ extCtrlSizer = wx.BoxSizer(wx.VERTICAL)
+ extCtrlSizer.Add(wx.StaticText(self, -1, _("Extensions:")), 0)
+ self._extListBox = wx.ListBox(self, -1, size=(-1,185), style=wx.LB_SINGLE)
+ self.Bind(wx.EVT_LISTBOX, self.OnListBoxSelect, self._extListBox)
+ extCtrlSizer.Add(self._extListBox, 1, wx.TOP | wx.BOTTOM | wx.EXPAND, SPACE)
+ buttonSizer = wx.GridSizer(rows=1, hgap=10, vgap=5)
+ self._moveUpButton = wx.Button(self, -1, _("Move Up"))
+ self.Bind(wx.EVT_BUTTON, self.OnMoveUp, self._moveUpButton)
+ buttonSizer.Add(self._moveUpButton, 0)
+ self._moveDownButton = wx.Button(self, -1, _("Move Down"))
+ self.Bind(wx.EVT_BUTTON, self.OnMoveDown, self._moveDownButton)
+ buttonSizer.Add(self._moveDownButton, 0)
+ extCtrlSizer.Add(buttonSizer, 0, wx.ALIGN_CENTER | wx.BOTTOM, HALF_SPACE)
+ buttonSizer = wx.GridSizer(rows=1, hgap=10, vgap=5)
+ self._addButton = wx.Button(self, -1, _("Add"))
+ self.Bind(wx.EVT_BUTTON, self.OnAdd, self._addButton)
+ buttonSizer.Add(self._addButton, 0)
+ self._deleteButton = wx.Button(self, wx.ID_DELETE)
+ self.Bind(wx.EVT_BUTTON, self.OnDelete, self._deleteButton)
+ buttonSizer.Add(self._deleteButton, 0)
+ extCtrlSizer.Add(buttonSizer, 0, wx.ALIGN_CENTER)
+ extOptionsPanelSizer.Add(extCtrlSizer, 0)
+
+ self._extDetailPanel = wx.Panel(self)
+ staticBox = wx.StaticBox(self._extDetailPanel, label=_("Selected Extension"))
+ staticBoxSizer = wx.StaticBoxSizer(staticBox)
+ self._extDetailPanel.SetSizer(staticBoxSizer)
+ extDetailSizer = wx.FlexGridSizer(cols=1, hgap=5, vgap=3)
+ staticBoxSizer.AddSizer(extDetailSizer, 0, wx.ALL, 5)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Name:")))
+ self._menuItemNameTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ extDetailSizer.Add(self._menuItemNameTextCtrl, 1, wx.EXPAND)
+ self.Bind(wx.EVT_TEXT, self.SaveCurrentItem, self._menuItemNameTextCtrl)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Menu Item Description:")))
+ self._menuItemDescTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ extDetailSizer.Add(self._menuItemDescTextCtrl, 1, wx.EXPAND)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Path:")))
+ self._commandTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ findFileButton = wx.Button(self._extDetailPanel, -1, _("Browse..."))
+ def OnBrowseButton(event):
+ fileDlg = wx.FileDialog(self, _("Choose an Executable:"), style=wx.OPEN | wx.HIDE_READONLY)
+ path = self._commandTextCtrl.GetValue()
+ if path:
+ fileDlg.SetPath(path)
+ if fileDlg.ShowModal() == wx.ID_OK:
+ self._commandTextCtrl.SetValue(fileDlg.GetPath())
+ self._commandTextCtrl.SetInsertionPointEnd()
+ fileDlg.Destroy()
+ wx.EVT_BUTTON(findFileButton, -1, OnBrowseButton)
+ hsizer = wx.BoxSizer(wx.HORIZONTAL)
+ hsizer.Add(self._commandTextCtrl, 1, wx.EXPAND)
+ hsizer.Add(findFileButton, 0, wx.LEFT, HALF_SPACE)
+ extDetailSizer.Add(hsizer, 0)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Pre Arguments:")))
+ self._commandPreArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ extDetailSizer.Add(self._commandPreArgsTextCtrl, 1, wx.EXPAND)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("Command Post Arguments:")))
+ self._commandPostArgsTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ extDetailSizer.Add(self._commandPostArgsTextCtrl, 1, wx.EXPAND)
+
+ extDetailSizer.Add(wx.StaticText(self._extDetailPanel, -1, _("File Extensions (Comma Separated):")))
+ self._fileExtTextCtrl = wx.TextCtrl(self._extDetailPanel, -1, size = (-1, -1))
+ self._fileExtTextCtrl.SetToolTipString(_("""For example: "txt, text" or "*" for all files"""))
+ extDetailSizer.Add(self._fileExtTextCtrl, 1, wx.EXPAND)
+
+ extOptionsPanelSizer.Add(self._extDetailPanel, 0)
+
+ extOptionsPanelBorderSizer.Add(extOptionsPanelSizer, 0, wx.ALL | wx.EXPAND, SPACE)
+ self.SetSizer(extOptionsPanelBorderSizer)
+ self.Layout()
+ parent.AddPage(self, _("Extensions"))
+
+ if self.PopulateItems():
+ self._extListBox.SetSelection(0)
+ self.OnListBoxSelect(None)
+
+
+ def OnOK(self, optionsDialog):
+ self.SaveCurrentItem()
+ extensionsService = wx.GetApp().GetService(ExtensionService)
+ oldExtensions = extensionsService.GetExtensions()
+ extensionsService.SetExtensions(self._extensions)
+ extensionsService.SaveExtensions()
+ if oldExtensions.__repr__() != self._extensions.__repr__():
+ msgTitle = wx.GetApp().GetAppName()
+ if not msgTitle:
+ msgTitle = _("Document Options")
+ wx.MessageBox(_("Extension changes will not appear until the application is restarted."),
+ msgTitle,
+ wx.OK | wx.ICON_INFORMATION,
+ self.GetParent())
+
+
+ def PopulateItems(self):
+ extensionsService = wx.GetApp().GetService(ExtensionService)
+ import copy
+ self._extensions = copy.deepcopy(extensionsService.GetExtensions())
+ for extension in self._extensions:
+ self._extListBox.Append(extension.menuItemName, extension)
+ self._currentItem = None
+ self._currentItemIndex = -1
+ return len(self._extensions)
+
+
+ def OnListBoxSelect(self, event):
+ self.SaveCurrentItem()
+ if not self._extListBox.GetSelections():
+ self._currentItemIndex = -1
+ self._currentItem = None
+ self._deleteButton.Enable(False)
+ self._moveUpButton.Enable(False)
+ self._moveDownButton.Enable(False)
+ else:
+ self._currentItemIndex = self._extListBox.GetSelection()
+ self._currentItem = self._extListBox.GetClientData(self._currentItemIndex)
+ self._deleteButton.Enable()
+ self._moveUpButton.Enable(self._extListBox.GetCount() > 1 and self._currentItemIndex > 0)
+ self._moveDownButton.Enable(self._extListBox.GetCount() > 1 and self._currentItemIndex < self._extListBox.GetCount() - 1)
+ self.LoadItem(self._currentItem)
+
+
+ def SaveCurrentItem(self, event=None):
+ extension = self._currentItem
+ if extension:
+ if extension.menuItemName != self._menuItemNameTextCtrl.GetValue():
+ extension.menuItemName = self._menuItemNameTextCtrl.GetValue()
+ self._extListBox.SetString(self._currentItemIndex, extension.menuItemName)
+ extension.menuItemDesc = self._menuItemDescTextCtrl.GetValue()
+ extension.command = self._commandTextCtrl.GetValue()
+ extension.commandPreArgs = self._commandPreArgsTextCtrl.GetValue()
+ extension.commandPostArgs = self._commandPostArgsTextCtrl.GetValue()
+ fileExt = self._fileExtTextCtrl.GetValue().replace(' ','')
+ if not fileExt:
+ extension.fileExt = None
+ else:
+ extension.fileExt = fileExt.split(',')
+
+
+ def LoadItem(self, extension):
+ if extension:
+ self._menuItemDescTextCtrl.SetValue(extension.menuItemDesc or '')
+ self._commandTextCtrl.SetValue(extension.command or '')
+ self._commandPreArgsTextCtrl.SetValue(extension.commandPreArgs or '')
+ self._commandPostArgsTextCtrl.SetValue(extension.commandPostArgs or '')
+ if extension.fileExt:
+ self._fileExtTextCtrl.SetValue(extension.fileExt.__repr__()[1:-1].replace("'","")) # Make the list a string, strip the brakcet on either side
+ else:
+ self._fileExtTextCtrl.SetValue('')
+ self._menuItemNameTextCtrl.SetValue(extension.menuItemName or '') # Do the name last since it triggers the write event that updates the entire item
+ self._extDetailPanel.Enable()
+ else:
+ self._menuItemNameTextCtrl.SetValue('')
+ self._menuItemDescTextCtrl.SetValue('')
+ self._commandTextCtrl.SetValue('')
+ self._commandPreArgsTextCtrl.SetValue('')
+ self._commandPostArgsTextCtrl.SetValue('')
+ self._fileExtTextCtrl.SetValue('')
+ self._extDetailPanel.Enable(False)
+
+
+ def OnAdd(self, event):
+ self.SaveCurrentItem()
+ extensionNames = map(lambda extension: extension.menuItemName, self._extensions)
+ name = _("Untitled")
+ count = 1
+ while name in extensionNames:
+ count = count + 1
+ name = _("Untitled %s") % count
+ extension = Extension(name)
+ self._extensions.append(extension)
+ self._extListBox.Append(extension.menuItemName, extension)
+ self._extListBox.SetSelection(self._extListBox.GetCount() - 1)
+ self.OnListBoxSelect(None)
+ self._menuItemNameTextCtrl.SetFocus()
+ self._menuItemNameTextCtrl.SetSelection(-1, -1)
+
+
+ def OnDelete(self, event):
+ self._extListBox.Delete(self._currentItemIndex)
+ self._extensions.remove(self._currentItem)
+ self._currentItemIndex = min(self._currentItemIndex, self._extListBox.GetCount() - 1)
+ if self._currentItemIndex > -1:
+ self._extListBox.SetSelection(self._currentItemIndex)
+ self._currentItem = None # Don't update it since it no longer exists
+ self.OnListBoxSelect(None)
+
+
+ def OnMoveUp(self, event):
+ itemAboveString = self._extListBox.GetString(self._currentItemIndex - 1)
+ itemAboveData = self._extListBox.GetClientData(self._currentItemIndex - 1)
+ self._extListBox.Delete(self._currentItemIndex - 1)
+ self._extListBox.Insert(itemAboveString, self._currentItemIndex)
+ self._extListBox.SetClientData(self._currentItemIndex, itemAboveData)
+ self._currentItemIndex = self._currentItemIndex - 1
+ self.OnListBoxSelect(None) # Reset buttons
+
+
+ def OnMoveDown(self, event):
+ itemBelowString = self._extListBox.GetString(self._currentItemIndex + 1)
+ itemBelowData = self._extListBox.GetClientData(self._currentItemIndex + 1)
+ self._extListBox.Delete(self._currentItemIndex + 1)
+ self._extListBox.Insert(itemBelowString, self._currentItemIndex)
+ self._extListBox.SetClientData(self._currentItemIndex, itemBelowData)
+ self._currentItemIndex = self._currentItemIndex + 1
+ self.OnListBoxSelect(None) # Reset buttons
import DebuggerService
import AboutDialog
import SVNService
+ import ExtensionService
if not ACTIVEGRID_BASE_IDE:
import DataModelEditor
deploymentService = self.InstallService(DeploymentService.DeploymentService())
dataModelService = self.InstallService(DataModelEditor.DataModelService())
welcomeService = self.InstallService(WelcomeService.WelcomeService())
+ extensionService = self.InstallService(ExtensionService.ExtensionService())
optionsService = self.InstallService(wx.lib.pydocview.DocOptionsService(supportedModes=wx.lib.docview.DOC_MDI))
aboutService = self.InstallService(wx.lib.pydocview.AboutService(AboutDialog.AboutDialog))
svnService = self.InstallService(SVNService.SVNService())
optionsService.AddOptionsPanel(STCTextEditor.TextOptionsPanel)
optionsService.AddOptionsPanel(HtmlEditor.HtmlOptionsPanel)
optionsService.AddOptionsPanel(SVNService.SVNOptionsPanel)
+ optionsService.AddOptionsPanel(ExtensionService.ExtensionOptionsPanel)
filePropertiesService.AddCustomEventHandler(projectService)
if os.path.exists(tips_path):
wx.CallAfter(self.ShowTip, docManager.FindSuitableParent(), wx.CreateFileTipProvider(tips_path, 0))
- wx.UpdateUIEvent.SetUpdateInterval(200) # Overhead of updating menus was too much. Change to update every 200 milliseconds.
+ wx.UpdateUIEvent.SetUpdateInterval(400) # Overhead of updating menus was too much. Change to update every 400 milliseconds.
return True
import time
import Service
import sys
-import activegrid.util.objutils
+import activegrid.util.xmlutils
import UICommon
import Wizard
import SVNService
#----------------------------------------------------------------------------
def load(fileObject):
- return activegrid.util.objutils.defaultLoad(fileObject)
+ return activegrid.util.xmlutils.defaultLoad(fileObject, knownTypes={"projectmodel" : ProjectModel})
def save(fileObject, projectModel):
- activegrid.util.objutils.defaultSave(fileObject, projectModel, prettyPrint=True)
+ activegrid.util.xmlutils.defaultSave(fileObject, projectModel, prettyPrint=True, knownTypes={"projectmodel" : ProjectModel})
#----------------------------------------------------------------------------
descr = template.GetDescription() + _(" (") + template.GetFileFilter() + _(")")
choices.append(descr)
allfilter = allfilter + template.GetFileFilter()
- choices.insert(0, _("All (%s)") % allfilter)
+ choices.insert(0, _("All (%s)") % allfilter) # first item
+ choices.append(_("Any (*.*)")) # last item
filterChoice = wx.Choice(frame, -1, size=(250, -1), choices=choices)
filterChoice.SetSelection(0)
filterChoice.SetToolTipString(_("Select file type filter."))
paths = []
index = filterChoice.GetSelection()
- if index:
+ lastIndex = filterChoice.GetCount()-1
+ if index and index != lastIndex: # if not All or Any
template = visibleTemplates[index-1]
# do search in files on disk
break
for name in files:
- if index == 0: # all
+ if index == 0: # All
for template in visibleTemplates:
if template.FileMatchesTemplate(name):
filename = os.path.join(root, name)
paths.append(filename)
break
+ elif index == lastIndex: # Any
+ filename = os.path.join(root, name)
+ # if already in project, don't add it, otherwise undo will remove it from project even though it was already in it.
+ if not doc.IsFileInProject(filename):
+ paths.append(filename)
else: # use selected filter
if template.FileMatchesTemplate(name):
filename = os.path.join(root, name)
import os.path
import wx
import ProjectEditor
+import activegrid.util as utillib
_ = wx.GetTranslation
def CreateDirectoryControl( parent, fileLabel, dirLabel, fileExtension, startingName="", startingDirectory=""):
return name[0:-1] + 'ies'
else:
return name + 's'
-
\ No newline at end of file
+
+def GetPythonExecPath():
+ pythonExecPath = wx.ConfigBase_Get().Read("ActiveGridPythonLocation")
+ if not pythonExecPath:
+ pythonExecPath = utillib.pythonExecPath
+ return pythonExecPath
+
+
import sys
import os
-def _registerMainModuleDir():
- global mainModuleDir
+def isWindows():
+ return os.name == 'nt'
+
+def _generateMainModuleDir():
if sys.executable.find('python') != -1:
utilModuleDir = os.path.dirname(__file__)
if not os.path.isabs(utilModuleDir):
mainModuleDir = os.path.dirname(mainModuleDir) # Get rid of library.zip
else:
mainModuleDir = os.path.dirname(sys.executable)
+ return mainModuleDir
+
+mainModuleDir = _generateMainModuleDir()
+
+
+def _generatePythonExecPath():
+ if sys.executable.find('python') != -1:
+ pythonExecPath = sys.executable
+ else:
+ pythonExecPath = os.path.join(os.path.dirname(sys.executable), '3rdparty\python2.3\python')
+ return pythonExecPath
+
+pythonExecPath = _generatePythonExecPath()
+
+def getCommandNameForExecPath(execPath):
+ if isWindows():
+ return '"%s"' % execPath
+ return execPath
-_registerMainModuleDir()
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: aglogging.py
+# Purpose: Utilities to help with logging
+#
+# Author: Jeff Norton
+#
+# Created: 01/04/05
+# CVS-ID: $Id$
+# Copyright: (c) 2005 ActiveGrid, Inc.
+# License: wxWindows License
+#----------------------------------------------------------------------------
+
+import sys
+import os
+import re
+import traceback
+import logging
+from activegrid.util.lang import *
+
+LEVEL_FATAL = logging.FATAL
+LEVEL_ERROR = logging.ERROR
+LEVEL_WARN = logging.WARN
+LEVEL_INFO = logging.INFO
+LEVEL_DEBUG = logging.DEBUG
+
+TEST_MODE_NONE = 0
+TEST_MODE_DETERMINISTIC = 1
+TEST_MODE_NON_DETERMINISTIC = 2
+
+global agTestMode
+agTestMode = TEST_MODE_NONE
+
+def setTestMode(mode):
+ global agTestMode
+ agTestMode = mode
+
+def getTestMode():
+ global agTestMode
+ return agTestMode
+
+def testMode(normalObj, testObj=None):
+ if getTestMode() > TEST_MODE_NONE:
+ return testObj
+ return normalObj
+
+pythonFileRefPattern = asString(r'(?<=File ")[^"]*(#[^#]*")(, line )[0-9]*')
+phpFileRefPattern = asString(r'( in ).*#([^#]*#[^ ]*)(?= on line )')
+pathSepPattern = os.sep
+if (pathSepPattern == "\\"):
+ pathSepPattern = "\\\\"
+pythonFileRefPattern = pythonFileRefPattern.replace("#", pathSepPattern)
+pythonFileRefPattern = re.compile(pythonFileRefPattern)
+phpFileRefPattern = phpFileRefPattern.replace("#", pathSepPattern)
+phpFileRefPattern = re.compile(phpFileRefPattern)
+
+def removeFileRefs(str):
+ str = pythonFileRefPattern.sub(_fileNameReplacement, str)
+ str = phpFileRefPattern.sub(_fileNameReplacementPHP, str)
+ return str
+
+def removePHPFileRefs(str):
+ str = phpFileRefPattern.sub(_fileNameReplacementPHP, str)
+ return str
+
+def _fileNameReplacement(match):
+ return "...%s" % match.group(1).replace(os.sep, "/")
+
+def _fileNameReplacementPHP(match):
+ return "%s...%s" % (match.group(1), match.group(2).replace(os.sep, "/"))
+
+def getTraceback():
+ extype, val, tb = sys.exc_info()
+ tbs = "\n"
+ for s in traceback.format_tb(tb):
+ tbs += s
+ return tbs
+
+def reportException(out=None, stacktrace=False, diffable=False, exception=None):
+ if (True): # exception == None):
+ extype, val, t = sys.exc_info()
+ else:
+ extype = type(exception)
+ val = exception
+ if (stacktrace):
+ e,v,t = sys.exc_info()
+ if (diffable):
+ exstr = removeFileRefs(str(val))
+ else:
+ exstr = str(val)
+ if (out == None):
+ print "Got Exception = %s: %s" % (extype, exstr)
+ else:
+ print >> out, "Got Exception = %s: %s" % (extype, exstr)
+ if (stacktrace):
+ fmt = traceback.format_exception(extype, val, t)
+ for s in fmt:
+ if (diffable):
+ s = removeFileRefs(s)
+ if (out == None):
+ print s
+ else:
+ print >> out, s
+
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: lang.py
+# Purpose: Active grid language specific utilities -- provides portability
+# for common idiom's that have language specific implementations
+#
+# Author: Jeff Norton
+#
+# Created: 04/27/05
+# CVS-ID: $Id$
+# Copyright: (c) 2004-2005 ActiveGrid, Inc.
+# License: wxWindows License
+#----------------------------------------------------------------------------
+
+def isMain(caller):
+ return caller == '__main__'
+
+def ag_className(obj):
+ return obj.__class__.__name__
+
+def asDict(src):
+ return src
+
+def asList(src):
+ return src
+
+def asTuple(src):
+ return src
+
+def asString(src):
+ return src
+
+def asInt(src):
+ return src
+
+def asBool(src):
+ return src
+
+def asObject(src):
+ return src
+
+def cast(src, type):
+ return src
+
+def asRef(src):
+ return src
+
+def asClass(src):
+ return src
+
+def localize(text):
+ return text
+
+# Pass in Python code as a string. The cross-compiler will convert to PHP
+# and in-line the result.
+def pyToPHP(expr):
+ pass
+
+# Pass in PHP code as a string. The cross-compiler will drop it in-line verbatim.
+def PHP(expr):
+ pass
+
+# Bracket Python only code. The Cross-compiler will ignore the bracketed code.
+def ifDefPy(comment=False):
+ pass
+
+def endIfDef():
+ pass
import traceback
import sys
import os
-import xmlmarshaller
-
-AG_TYPE_MAPPING = { "ag:append" : "activegrid.model.processmodel.AppendOperation",
- "ag:body" : "activegrid.model.processmodel.Body",
- "ag:copy" : "activegrid.model.processmodel.CopyOperation",
- "ag:cssRule" : "activegrid.model.processmodel.CssRule",
- "ag:datasource" : "activegrid.data.dataservice.DataSource",
- "ag:debug" : "activegrid.model.processmodel.DebugOperation",
- "ag:deployment" : "activegrid.server.deployment.Deployment",
- "ag:glue" : "activegrid.model.processmodel.Glue",
- "ag:hr" : "activegrid.model.processmodel.HorizontalRow",
- "ag:image" : "activegrid.model.processmodel.Image",
- "ag:inputs" : "activegrid.model.processmodel.Inputs",
- "ag:label" : "activegrid.model.processmodel.Label",
- "ag:processmodel": "activegrid.model.processmodel.ProcessModel",
- "ag:processmodelref" : "activegrid.server.deployment.ProcessModelRef",
- "ag:query" : "activegrid.model.processmodel.Query",
- "ag:schemaOptions" : "activegrid.model.schema.SchemaOptions",
- "ag:schemaref" : "activegrid.server.deployment.SchemaRef",
- "ag:set" : "activegrid.model.processmodel.SetOperation",
- "ag:text" : "activegrid.model.processmodel.Text",
- "ag:title" : "activegrid.model.processmodel.Title",
- "ag:view" : "activegrid.model.processmodel.View",
- "bpws:case" : "activegrid.model.processmodel.BPELCase",
- "bpws:catch" : "activegrid.model.processmodel.BPELCatch",
- "bpws:faultHandlers" : "activegrid.model.processmodel.BPELFaultHandlers",
- "bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
- "bpws:onMessage" : "activegrid.model.processmodel.BPELOnMessage",
- "bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
- "bpws:pick" : "activegrid.model.processmodel.BPELPick",
- "bpws:process" : "activegrid.model.processmodel.BPELProcess",
- "bpws:receive" : "activegrid.model.processmodel.BPELReceive",
- "bpws:reply" : "activegrid.model.processmodel.BPELReply",
- "bpws:scope" : "activegrid.model.processmodel.BPELScope",
- "bpws:sequence" : "activegrid.model.processmodel.BPELSequence",
- "bpws:switch" : "activegrid.model.processmodel.BPELSwitch",
- "bpws:terminate" : "activegrid.model.processmodel.BPELTerminate",
- "bpws:variable" : "activegrid.model.processmodel.BPELVariable",
- "bpws:variables" : "activegrid.model.processmodel.BPELVariables",
- "bpws:while" : "activegrid.model.processmodel.BPELWhile",
- "wsdl:message" : "activegrid.model.processmodel.WSDLMessage",
- "wsdl:part" : "activegrid.model.processmodel.WSDLPart",
- "xforms:group" : "activegrid.model.processmodel.XFormsGroup",
- "xforms:input" : "activegrid.model.processmodel.XFormsInput",
- "xforms:label" : "activegrid.model.processmodel.XFormsLabel",
- "xforms:output" : "activegrid.model.processmodel.XFormsOutput",
- "xforms:secret" : "activegrid.model.processmodel.XFormsSecret",
- "xforms:submit" : "activegrid.model.processmodel.XFormsSubmit",
- "xs:all" : "activegrid.model.schema.XsdSequence",
- "xs:complexType" : "activegrid.model.schema.XsdComplexType",
- "xs:element" : "activegrid.model.schema.XsdElement",
- "xs:field" : "activegrid.model.schema.XsdKeyField",
- "xs:key" : "activegrid.model.schema.XsdKey",
- "xs:keyref" : "activegrid.model.schema.XsdKeyRef",
- "xs:schema" : "activegrid.model.schema.Schema",
- "xs:selector" : "activegrid.model.schema.XsdKeySelector",
- "xs:sequence" : "activegrid.model.schema.XsdSequence",
- "projectmodel" : "activegrid.tool.ProjectEditor.ProjectModel",
- }
-
-def defaultLoad(fileObject, knownTypes=None):
- xml = fileObject.read()
- loadedObject = defaultUnmarshal(xml, knownTypes=knownTypes)
- if hasattr(fileObject, 'name'):
- loadedObject.fileName = os.path.abspath(fileObject.name)
- loadedObject.initialize()
- return loadedObject
-
-def defaultUnmarshal(xml, knownTypes=None):
- if not knownTypes: knownTypes = AG_TYPE_MAPPING
- return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
-
-def defaultSave(fileObject, objectToSave, prettyPrint=True, knownTypes=None, withEncoding=1, encoding='utf-8'):
- xml = defaultMarshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
- fileObject.write(xml)
- fileObject.flush()
-
-def defaultMarshal(objectToSave, prettyPrint=True, knownTypes=None, withEncoding=1, encoding='utf-8'):
- if not knownTypes: knownTypes = AG_TYPE_MAPPING
- return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, withEncoding=withEncoding, encoding=encoding)
-
-def clone(objectToClone, knownTypes=None, encoding='utf-8'):
- if not knownTypes: knownTypes = AG_TYPE_MAPPING
- xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
- clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
- if hasattr(objectToClone, 'fileName'):
- clonedObject.fileName = objectToClone.fileName
- try:
- clonedObject.initialize()
- except AttributeError:
- pass
- return clonedObject
+from types import *
def classForName(className):
pathList = className.split('.')
code = code.__dict__[name]
return code
-def hasattrignorecase(object, name):
- namelow = name.lower()
- for attr in dir(object):
- if attr.lower() == namelow:
- return True
- for attr in dir(object):
- if attr.lower() == '_' + namelow:
- return True
- return False
-
-def setattrignorecase(object, name, value):
- namelow = name.lower()
- for attr in object.__dict__:
- if attr.lower() == namelow:
- object.__dict__[attr] = value
- return
- object.__dict__[name] = value
-
-def getattrignorecase(object, name):
- namelow = name.lower()
- for attr in object.__dict__:
- if attr.lower() == namelow:
- return object.__dict__[attr]
- return object.__dict__[name]
-
def hasPropertyValue(obj, attr):
hasProp = False
try:
return hasProp
def toDiffableString(value):
- s = repr(value)
+ s = str(value)
ds = ""
i = s.find(" at 0x")
start = 0
start = j
i = s.find(" at 0x", start)
return ds + s[start:]
-
+
+def toString(value, options=0):
+ if ((options & PRINT_OBJ_DIFFABLE) > 0):
+ return toDiffableString(value)
+ return value
+
+def toTypeString(obj):
+ if (isinstance(obj, BooleanType)):
+ return "bool"
+ elif (isinstance(obj, UnicodeType)):
+ return "unicode"
+ elif (isinstance(obj, basestring)):
+ return "string"
+ elif (isinstance(obj, IntType)):
+ return "int"
+ elif (isinstance(obj, FloatType)):
+ return "float"
+ elif (type(obj) == ListType):
+ return "list"
+ elif (isinstance(obj, DictType)):
+ return "dict"
+ elif (isinstance(obj, TupleType)):
+ return "tuple"
+ elif (isinstance(obj, InstanceType)):
+ return type(obj)
+ else:
+ return type(obj)
+
PRINT_OBJ_GETATTR = 1
PRINT_OBJ_HIDE_INTERNAL = 2
PRINT_OBJ_COMPACT = 4
PRINT_OBJ_NONONE = 8
+PRINT_OBJ_DIFFABLE = 16
PRINT_OBJ_INTERNAL = 512
def printObject(out, object, name="", indent=0, flags=0, exclude=None, maxIndent=30):
if ((maxIndent != None) and (indent > maxIndent)):
- print >> out, " "*indent, name, str(object)
+ print >> out, " "*indent, "%s: %s" % (name, toString(str(object), flags)),
+ if ((flags & PRINT_OBJ_INTERNAL) == 0):
+ print >> out
return True
finalNewLine = False
printed = True
+## if (exclude == None):
+## exclude = []
if ((flags & PRINT_OBJ_COMPACT) > 0):
if (exclude and object in exclude):
return
if ((flags & PRINT_OBJ_INTERNAL) == 0):
finalNewLine = True
flags |= PRINT_OBJ_INTERNAL
- if (object == None):
+ if (object is None):
if (flags & PRINT_OBJ_NONONE) == 0:
print >> out, " "*indent, name, " = None",
else:
finalNewLine = False
printed = False
elif (isinstance(object, (list, tuple))):
- if (exclude and object in exclude):
- print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (already printed)",
- elif (exclude and name in exclude):
- print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (excluded)",
+ if ((exclude != None) and object in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (already printed)",
+ elif ((exclude != None) and name in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
else:
- if (exclude != None): exclude.append(object)
- print >> out, " "*indent, name, " : ", type(object), " of length = %i" % len(object),
+ if ((exclude != None) and (len(object) > 0)): exclude.append(object)
+ print >> out, " "*indent, name, " : ", toTypeString(object), " of length = %d" % len(object),
for i, o in enumerate(object):
print >> out
- printObject(out, o, name="[%i]" % i, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
+ printObject(out, o, name="[%d]" % i, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent)
elif (isinstance(object, dict)):
- if (exclude and object in exclude):
- print >> out, " "*indent, name, " : ", type(object), " (already printed)",
+ if ((exclude != None) and object in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
else:
- if (exclude != None): exclude.append(object)
+ if ((exclude != None) and (len(object) > 0)): exclude.append(object)
if (len(name) > 0):
print >> out, " "*indent, name,
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
keys = object.keys()
keys.sort()
- for n in keys:
- if ((n != None) and (not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))):
- if printObject(out, object[n], name=n, indent=indent+2, flags=flags, exclude=exclude, maxIndent=maxIndent):
- if ((flags & PRINT_OBJ_COMPACT) == 0):
- print >> out
- else:
- print >> out, ",",
+ for key in keys:
+ if (key != None):
+ n = key
+ if (not (isinstance(n, basestring))):
+ n = str(n)
+ if ((not n.startswith("_") or ((flags & PRINT_OBJ_HIDE_INTERNAL) == 0))):
+ if printObject(out, object[key], name=n, indent=indent+2, flags=(flags | PRINT_OBJ_INTERNAL), exclude=exclude, maxIndent=maxIndent):
+ if ((flags & PRINT_OBJ_COMPACT) == 0):
+ print >> out
+ else:
+ print >> out, ",",
print >> out, " "*indent, "}",
elif (hasattr(object, "__dict__")):
- if (exclude and object in exclude):
- print >> out, " "*indent, name, " : ", type(object), " (already printed) = ", toDiffableString(object),
+ if ((exclude != None) and object in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed) = ", toDiffableString(object),
else:
if (exclude != None): exclude.append(object)
- if (name.startswith("_")):
- print >> out, " "*indent, name, " : ", type(object),
- elif (exclude and object.__dict__ in exclude):
- print >> out, " "*indent, name, " : ", type(object), " (already printed)",
+ if (name.startswith("_")): ## and ((flags & PRINT_OBJ_HIDE_INTERNAL) > 0)):
+ print >> out, " "*indent, name, " : ", toTypeString(object),
+ elif ((exclude != None) and object.__dict__ in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " (already printed)",
else:
- print >> out, " "*indent, name, " : ", type(object),
+ print >> out, " "*indent, name, " : ", toTypeString(object),
if ((flags & PRINT_OBJ_GETATTR) == 0):
if ((flags & PRINT_OBJ_COMPACT) == 0):
print >> out
elif (indent < 0):
print >> out, object,
elif isinstance(object, basestring):
- if (exclude and name in exclude):
- print >> out, " "*indent, name, " : ", type(object), " of length = ", len(object), " (excluded)",
+ if ((exclude != None) and name in exclude):
+ print >> out, " "*indent, name, " : ", toTypeString(object), " of length = ", len(object), " (excluded)",
elif (len(object) > 100):
- print >> out, " "*indent, name, ":", type(object), "[%i] = %s...%s" % (len(object), object[:50], object[-50:]),
+ print >> out, " "*indent, name, ":", toTypeString(object), "[%d] = %s...%s" % (len(object), object[:50], object[-50:]),
else:
- print >> out, " "*indent, name, ":", type(object), "=", str(object),
+ print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
+## elif (isinstance(object, float)):
+## val = str(object)
+## if (len(val) > 17):
+## val = val[:17]
+## print >> out, " "*indent, name, ":", type(object), "=", val,
else:
- print >> out, " "*indent, name, ":", type(object), "=", str(object),
+ print >> out, " "*indent, name, ":", toTypeString(object), "=", str(object),
if (finalNewLine):
print >> out
return printed
import __builtin__
import sys
from types import *
+import logging
import xml.sax
import xml.sax.handler
-from xml.sax import saxutils
-
-import objutils
+import xml.sax.saxutils as saxutils
+from activegrid.util.lang import *
+import activegrid.util.aglogging as aglogging
MODULE_PATH = "__main__"
-### ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
+## ToDO remove maxOccurs "unbounded" resolves to -1 hacks after bug 177 is fixed
"""
-
-More documentation later, but here are some special Python attributes
-that McLane recognizes:
+Special attributes that we recognize:
name: __xmlname__
type: string
name: __xmlattributes__
type: tuple or list
-description: the name(s) of the Python string attribute(s) to be
+description: the name(s) of the Lang string attribute(s) to be
marshalled as xml attributes instead of nested xml elements. currently
-these can only be strings since there's not a way to get the type
+these can only be strings since there"s not a way to get the type
information back when unmarshalling.
name: __xmlexclude__
type: tuple or list
-description: the name(s) of the python attribute(s) to skip when
+description: the name(s) of the lang attribute(s) to skip when
marshalling.
name: __xmlrename__
type: dict
-description: describes an alternate Python <-> XML name mapping.
+description: describes an alternate Lang <-> XML name mapping.
Normally the name mapping is the identity function. __xmlrename__
-overrides that. The keys are the Python names, the values are their
+overrides that. The keys are the Lang names, the values are their
associated XML names.
name: __xmlflattensequence__
type: dict, tuple, or list
-description: the name(s) of the Python sequence attribute(s) whose
+description: the name(s) of the Lang sequence attribute(s) whose
items are to be marshalled as a series of xml elements (with an
optional keyword argument that specifies the element name to use) as
opposed to containing them in a separate sequence element, e.g.:
myseq = (1, 2)
<!-- normal way of marshalling -->
<myseq>
- <item objtype='int'>1</item>
- <item objtype='int'>2</item>
+ <item objtype="int">1</item>
+ <item objtype="int">2</item>
</myseq>
-<!-- with __xmlflattensequence__ set to {'myseq': 'squish'} -->
-<squish objtype='int'>1</squish>
-<squish objtype='int'>2</squish>
+<!-- with __xmlflattensequence__ set to {"myseq": "squish"} -->
+<squish objtype="int">1</squish>
+<squish objtype="int">2</squish>
name: __xmlnamespaces__
type: dict
name: __xmlattrnamespaces__
type: dict
-description: a dict assigning the Python object's attributes to the namespaces
+description: a dict assigning the Lang object"s attributes to the namespaces
defined in __xmlnamespaces__. Each item in the dict should consist of a
prefix,attributeList combination where the key is the prefix and the value is
-a list of the Python attribute names. e.g.:
+a list of the Lang attribute names. e.g.:
__xmlattrnamespaces__ = { "ag":["firstName", "lastName", "addressLine1", "city"] }
"""
+global xmlMarshallerLogger
+xmlMarshallerLogger = logging.getLogger("activegrid.util.xmlmarshaller.marshal")
+xmlMarshallerLogger.setLevel(aglogging.LEVEL_WARN)
+# INFO : low-level info
+# DEBUG : debugging info
+
+global knownGlobalTypes
+
################################################################################
#
# module exceptions
return "%s is not supported for marshalling." % str(self.typename)
class XMLAttributeIsNotStringType(Error):
- """Exception raised when an object's attribute is specified to be
+ """Exception raised when an object"s attribute is specified to be
marshalled as an XML attribute of the enclosing object instead of
a nested element.
"""
self.typename = typename
def __str__(self):
return """%s was set to be marshalled as an XML attribute
- instead of a nested element, but the object's type is %s, not
+ instead of a nested element, but the object"s type is %s, not
string.""" % (self.attrname, self.typename)
+class MarshallerException(Exception):
+ pass
+
################################################################################
#
# constants and such
#
################################################################################
-XMLNS = 'xmlns'
-XMLNS_PREFIX = XMLNS + ':'
+XMLNS = "xmlns"
+XMLNS_PREFIX = XMLNS + ":"
XMLNS_PREFIX_LENGTH = len(XMLNS_PREFIX)
-BASETYPE_ELEMENT_NAME = 'item'
+BASETYPE_ELEMENT_NAME = "item"
+DICT_ITEM_NAME = "qqDictItem"
+DICT_ITEM_KEY_NAME = "key"
+DICT_ITEM_VALUE_NAME = "value"
-# This list doesn't seem to be used.
+# This list doesn"t seem to be used.
# Internal documentation or useless? You make the call!
-MEMBERS_TO_SKIP = ('__module__', '__doc__', '__xmlname__', '__xmlattributes__',
- '__xmlexclude__', '__xmlflattensequence__', '__xmlnamespaces__',
- '__xmldefaultnamespace__', '__xmlattrnamespaces__',
- '__xmlattrgroups__')
+##MEMBERS_TO_SKIP = ("__module__", "__doc__", "__xmlname__", "__xmlattributes__",
+## "__xmlexclude__", "__xmlflattensequence__", "__xmlnamespaces__",
+## "__xmldefaultnamespace__", "__xmlattrnamespaces__",
+## "__xmlattrgroups__")
################################################################################
#
#
################################################################################
+def setattrignorecase(object, name, value):
+ if (name not in object.__dict__):
+ namelow = name.lower()
+ for attr in object.__dict__:
+ if attr.lower() == namelow:
+ object.__dict__[attr] = value
+ return
+ object.__dict__[name] = value
+
+def getComplexType(obj):
+ if (hasattr(obj, "__xsdcomplextype__")):
+ return obj.__xsdcomplextype__
+ return None
+
def _objectfactory(objname, objargs=None, xsname=None):
- '''dynamically create an object based on the objname and return
- it. look it up in the BASETYPE_ELEMENT_MAP first.
- '''
- # split the objname into the typename and module path,
- # importing the module if need be.
+ "dynamically create an object based on the objname and return it."
+
if not isinstance(objargs, list):
objargs = [objargs]
-
- if (xsname):
- try:
- objname = knownGlobalTypes[xsname]
- except KeyError:
- pass
-
-## print "[objectfactory] creating an object of type %s and value %s, xsname=%s" % (objname, objargs, xsname)
- objtype = objname.split('.')[-1]
- pathlist = objname.split('.')
- modulename = '.'.join(pathlist[0:-1])
-## print "[objectfactory] object [%s] %s(%r)" % (objname, objtype, objargs)
- if objname == 'bool':
- return not objargs[0].lower() == 'false'
- elif objname == 'str': # don't strip strings - blanks are significant !!!
- if len(objargs) > 0:
- return saxutils.unescape(objargs[0]).encode()
- else:
- return ''
- elif objname == 'unicode': # don't strip strings - blanks are significant !!!
+## print "[objectfactory] xsname [%s]; objname [%s]" % (xsname, objname)
+
+ # (a) deal with tagName:knownTypes mappings
+ if (xsname != None):
+ objclass = knownGlobalTypes.get(xsname)
+ if (objclass != None):
+ if (objargs != None):
+ return objclass(*objargs)
+ else:
+ return objclass()
+
+ # (b) next with intrinisic types
+ if objname == "str" or objname == "unicode": # don"t strip: blanks are significant
if len(objargs) > 0:
return saxutils.unescape(objargs[0]).encode()
else:
- return ''
- elif objtype in ('float', 'int', 'str', 'long'):
- objargs = [x.strip() for x in objargs]
+ return ""
+ elif objname == "bool":
+ return not objargs[0].lower() == "false"
+ elif objname in ("float", "int", "long"):
+## objargs = [x.strip() for x in objargs]
+ return __builtin__.__dict__[objname](*objargs)
+ elif objname == "None":
+ return None
+
+ # (c) objtype=path...module.class
+ # split the objname into the typename and module path,
+ # importing the module if need be.
+## print "[objectfactory] creating an object of type %s and value %s, xsname=%s" % (objname, objargs, xsname)
+ objtype = objname.split(".")[-1]
+ pathlist = objname.split(".")
+ modulename = ".".join(pathlist[0:-1])
+## print "[objectfactory] object [%s] %s(%r)" % (objname, objtype, objargs)
try:
- if __builtin__.__dict__.has_key(objname):
- module = __builtin__
- elif knownGlobalModule:
- module = knownGlobalModule
- else:
- if modulename:
- module = __import__(modulename)
+ if modulename:
+ module = __import__(modulename)
for name in pathlist[1:-1]:
module = module.__dict__[name]
+ elif __builtin__.__dict__.has_key(objname):
+ module = __builtin__
+ else:
+ raise MarshallerException("Could not find class %s" % objname)
if objargs:
return module.__dict__[objtype](*objargs)
else:
- if objtype == 'None':
- return None
return module.__dict__[objtype]()
except KeyError:
- raise KeyError("Could not find class %s" % objname)
+ raise MarshallerException("Could not find class %s" % objname)
class Element:
+
def __init__(self, name, attrs=None):
self.name = name
self.attrs = attrs
- self.content = ''
+ self.content = ""
self.children = []
+
def getobjtype(self):
- if self.attrs.has_key('objtype'):
- return self.attrs.getValue('objtype')
- else:
- return 'str'
- def toString(self):
+ objtype = self.attrs.get("objtype")
+ if (objtype == None):
+ if (len(self.children) > 0):
+ objtype = "dict"
+ else:
+ objtype = "str"
+ return objtype
+
+ def __str__(self):
print " name = ", self.name, "; attrs = ", self.attrs, "number of children = ", len(self.children)
i = -1
for child in self.children:
self.elementstack = []
xml.sax.handler.ContentHandler.__init__(self)
- def toString(self):
+ def __str__(self):
print "-----XMLObjectFactory Dump-------------------------------"
if (self.rootelement == None):
print "rootelement is None"
for e in self.elementstack:
i = i + 1
print "elementstack[", i, "]: "
- e.toString()
+ str(e)
print "-----end XMLObjectFactory--------------------------------"
## ContentHandler methods
def startElement(self, name, attrs):
## print "startElement for name: ", name
- if name.find(':') > -1: # Strip namespace prefixes for now until actually looking them up in xsd
- name = name[name.index(':') + 1:]
+ if name.find(":") > -1: # Strip namespace prefixes for now until actually looking them up in xsd
+ name = name[name.find(":") + 1:]
## for attrname in attrs.getNames():
## print "%s: %s" % (attrname, attrs.getValue(attrname))
element = Element(name, attrs.copy())
## print self.elementstack
def characters(self, content):
-## print "got content: %s" % content
- if content:
+## print "got content: %s (%s)" % (content, type(content))
+ if (content != None):
self.elementstack[-1].content += content
def endElement(self, name):
-## print "[endElement] name of element we're at the end of: %s" % name
+## print "[endElement] name of element we"re at the end of: %s" % name
xsname = name
- if name.find(':') > -1: # Strip namespace prefixes for now until actually looking them up in xsd
- name = name[name.index(':') + 1:]
+ if name.find(":") > -1: # Strip namespace prefixes for now until actually looking them up in xsd
+ name = name[name.find(":") + 1:]
oldChildren = self.elementstack[-1].children
element = self.elementstack.pop()
if ((len(self.elementstack) > 1) and (self.elementstack[-1].getobjtype() == "None")):
## print "[endElement] %s: skipping a (objtype==None) end tag" % name
return
constructorarglist = []
- if element.content:
+ if (len(element.content) > 0):
strippedElementContent = element.content.strip()
- if strippedElementContent:
+ if (len(strippedElementContent) > 0):
constructorarglist.append(element.content)
## print "[endElement] calling objectfactory"
obj = _objectfactory(objtype, constructorarglist, xsname)
- complexType = None
- if hasattr(obj, '__xsdcomplextype__'):
- complexType = getattr(obj, '__xsdcomplextype__')
- if (hasattr(obj, '__xmlname__') and getattr(obj, '__xmlname__') == "sequence"):
-## print "[endElement] sequence found"
-## self.toString()
+ complexType = getComplexType(obj)
+ if (obj != None):
+ if (hasattr(obj, "__xmlname__") and getattr(obj, "__xmlname__") == "sequence"):
self.elementstack[-1].children = oldChildren
-## self.toString()
-## print "done moving sequence stuff; returning"
return
- if len(self.elementstack) > 0:
-## print "[endElement] appending child with name: ", name, "; objtype: ", objtype
- parentElement.children.append((name, obj))
-## print "parentElement now has ", len(parentElement.children), " children"
- else:
- self.rootelement = obj
- if element.attrs and not isinstance(obj, list):
+ if (len(element.attrs) > 0) and not isinstance(obj, list):
## print "[endElement] %s: element has attrs and the obj is not a list" % name
for attrname, attr in element.attrs.items():
if attrname == XMLNS or attrname.startswith(XMLNS_PREFIX):
ns = attrname[XMLNS_PREFIX_LENGTH:]
else:
ns = ""
- if not hasattr(obj, '__xmlnamespaces__'):
+ if not hasattr(obj, "__xmlnamespaces__"):
obj.__xmlnamespaces__ = {ns:attr}
elif ns not in obj.__xmlnamespaces__:
- if (hasattr(obj.__class__, '__xmlnamespaces__')
- and obj.__xmlnamespaces__ is obj.__class__.__xmlnamespaces__):
- obj.__xmlnamespaces__ = dict(obj.__xmlnamespaces__)
+ if (hasattr(obj.__class__, "__xmlnamespaces__")
+ and (obj.__xmlnamespaces__ is obj.__class__.__xmlnamespaces__)):
+ obj.__xmlnamespaces__ = dict(obj.__xmlnamespaces__)
obj.__xmlnamespaces__[ns] = attr
- elif not attrname == 'objtype':
- if attrname.find(':') > -1: # Strip namespace prefixes for now until actually looking them up in xsd
- attrname = attrname[attrname.index(':') + 1:]
- if complexType:
+ elif not attrname == "objtype":
+ if attrname.find(":") > -1: # Strip namespace prefixes for now until actually looking them up in xsd
+ attrname = attrname[attrname.find(":") + 1:]
+ if (complexType != None):
xsdElement = complexType.findElement(attrname)
- if xsdElement:
+ if (xsdElement != None):
type = xsdElement.type
- if type:
- type = xsdToPythonType(type)
+ if (type != None):
+ type = xsdToLangType(type)
### ToDO remove maxOccurs hack after bug 177 is fixed
if attrname == "maxOccurs" and attr == "unbounded":
attr = "-1"
attr = _objectfactory(type, attr)
- objutils.setattrignorecase(obj, _toAttrName(obj, attrname), attr)
+ try:
+ setattrignorecase(obj, _toAttrName(obj, attrname), attr)
+ except AttributeError:
+ raise MarshallerException("Error unmarshalling attribute \"%s\" of XML element \"%s\": object type not specified or known" % (attrname, name))
## obj.__dict__[_toAttrName(obj, attrname)] = attr
# stuff any child attributes meant to be in a sequence via the __xmlflattensequence__
flattenDict = {}
- if hasattr(obj, '__xmlflattensequence__'):
+ if hasattr(obj, "__xmlflattensequence__"):
+ flatten = obj.__xmlflattensequence__
## print "[endElement] %s: obj has __xmlflattensequence__" % name
- if (isinstance(obj.__xmlflattensequence__,dict)):
-## print "[endElement] dict with obj.__xmlflattensequence__.items: ", obj.__xmlflattensequence__.items()
- for sequencename, xmlnametuple in obj.__xmlflattensequence__.items():
- for xmlname in xmlnametuple:
-## print "[endElement]: adding flattenDict[%s] = %s" % (xmlname, sequencename)
- flattenDict[xmlname] = sequencename
- # handle __xmlflattensequence__ list/tuple (i.e. no element rename)
- elif (isinstance(obj.__xmlflattensequence__,list) or isinstance(obj.__xmlflattensequence__,tuple)):
- for sequencename in obj.__xmlflattensequence__:
- flattenDict[sequencename] = sequencename
+ if (isinstance(flatten, dict)):
+## print "[endElement] dict with flatten.items: ", flatten.items()
+ for sequencename, xmlnametuple in flatten.items():
+ if (xmlnametuple == None):
+ flattenDict[sequencename] = sequencename
+ elif (not isinstance(xmlnametuple, (tuple, list))):
+ flattenDict[str(xmlnametuple)] = sequencename
+ else:
+ for xmlname in xmlnametuple:
+ ## print "[endElement]: adding flattenDict[%s] = %s" % (xmlname, sequencename)
+ flattenDict[xmlname] = sequencename
else:
- raise "Invalid type for __xmlflattensequence___ : it must be a dict, list, or tuple"
+ raise "Invalid type for __xmlflattensequence___ : it must be a dict"
- # reattach an object's attributes to it
+ # reattach an object"s attributes to it
for childname, child in element.children:
## print "[endElement] childname is: ", childname, "; child is: ", child
- if flattenDict.has_key(childname):
+ if (childname in flattenDict):
sequencename = _toAttrName(obj, flattenDict[childname])
## print "[endElement] sequencename is: ", sequencename
- try:
+ if (not hasattr(obj, sequencename)):
## print "[endElement] obj.__dict__ is: ", obj.__dict__
- sequencevalue = obj.__dict__[sequencename]
- except (AttributeError, KeyError):
- sequencevalue = None
- if sequencevalue == None:
- sequencevalue = []
- obj.__dict__[sequencename] = sequencevalue
+ obj.__dict__[sequencename] = []
+ sequencevalue = getattr(obj, sequencename)
+ if (sequencevalue == None):
+ obj.__dict__[sequencename] = []
+ sequencevalue = getattr(obj, sequencename)
sequencevalue.append(child)
- elif isinstance(obj, list):
-## print "appended childname = ", childname
+ elif (objtype == "list"):
obj.append(child)
+ elif isinstance(obj, dict):
+ if (childname == DICT_ITEM_NAME):
+ obj[child[DICT_ITEM_KEY_NAME]] = child[DICT_ITEM_VALUE_NAME]
+ else:
+ obj[childname] = child
else:
## print "childname = %s, obj = %s, child = %s" % (childname, repr(obj), repr(child))
- objutils.setattrignorecase(obj, _toAttrName(obj, childname), child)
- obj.__dict__[_toAttrName(obj, childname)] = child
+ try:
+ setattrignorecase(obj, _toAttrName(obj, childname), child)
+ except AttributeError:
+ raise MarshallerException("Error unmarshalling child element \"%s\" of XML element \"%s\": object type not specified or known" % (childname, name))
+## obj.__dict__[_toAttrName(obj, childname)] = child
- if complexType:
+ if (complexType != None):
for element in complexType.elements:
if element.default:
elementName = _toAttrName(obj, element.name)
if ((elementName not in obj.__dict__) or (obj.__dict__[elementName] == None)):
- pythonType = xsdToPythonType(element.type)
- defaultValue = _objectfactory(pythonType, element.default)
+ langType = xsdToLangType(element.type)
+ defaultValue = _objectfactory(langType, element.default)
obj.__dict__[elementName] = defaultValue
+ ifDefPy()
+ if (isinstance(obj, list)):
+ if ((element.attrs.has_key("mutable")) and (element.attrs.getValue("mutable") == "false")):
+ obj = tuple(obj)
+ endIfDef()
+
+ if (len(self.elementstack) > 0):
+## print "[endElement] appending child with name: ", name, "; objtype: ", objtype
+ parentElement.children.append((name, obj))
+## print "parentElement now has ", len(parentElement.children), " children"
+ else:
+ self.rootelement = obj
+
def getRootObject(self):
return self.rootelement
## name = "_%s%s" % (obj.__class__.__name__, name)
return name
-__typeMappingXsdToPython = {
+__typeMappingXsdToLang = {
"string": "str",
"char": "str",
"varchar": "str",
- "date": "str", # ToDO Need to work out how to create python date types
+ "date": "str", # ToDO Need to work out how to create lang date types
"boolean": "bool",
"decimal": "float", # ToDO Does python have a better fixed point type?
"int": "int",
"double": "float",
}
-def xsdToPythonType(xsdType):
- try:
- return __typeMappingXsdToPython[xsdType]
- except KeyError:
+def xsdToLangType(xsdType):
+ langType = __typeMappingXsdToLang.get(xsdType)
+ if (langType == None):
raise Exception("Unknown xsd type %s" % xsdType)
+ return langType
-def _getXmlValue(pythonValue):
- if (isinstance(pythonValue, bool)):
- return str(pythonValue).lower()
- elif (isinstance(pythonValue, unicode)):
- return pythonValue.encode()
+def _getXmlValue(langValue):
+ if (isinstance(langValue, bool)):
+ return str(langValue).lower()
+ elif (isinstance(langValue, unicode)):
+ return langValue.encode()
else:
- return str(pythonValue)
+ return str(langValue)
-def unmarshal(xmlstr, knownTypes=None, knownModule=None):
- global knownGlobalTypes, knownGlobalModule
+def unmarshal(xmlstr, knownTypes=None):
+ global knownGlobalTypes
if (knownTypes == None):
knownGlobalTypes = {}
else:
knownGlobalTypes = knownTypes
- knownGlobalModule = knownModule
objectfactory = XMLObjectFactory()
xml.sax.parseString(xmlstr, objectfactory)
return objectfactory.getRootObject()
-def marshal(obj, elementName=None, prettyPrint=False, indent=0, knownTypes=None, withEncoding=True, encoding=None):
- xmlstr = ''.join(_marshal(obj, elementName, prettyPrint=prettyPrint, indent=indent, knownTypes=knownTypes))
- if withEncoding:
- if encoding is None:
- return '<?xml version="1.0" encoding="%s"?>\n%s' % (sys.getdefaultencoding(), xmlstr)
- else:
- return '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr.encode(encoding))
- else:
+def marshal(obj, elementName=None, prettyPrint=False, indent=0, knownTypes=None, encoding=-1):
+ xmlstr = "".join(_marshal(obj, elementName, prettyPrint=prettyPrint, indent=indent, knownTypes=knownTypes))
+ if (isinstance(encoding, basestring)):
+ return '<?xml version="1.0" encoding="%s"?>\n%s' % (encoding, xmlstr.encode(encoding))
+ elif (encoding == None):
return xmlstr
+ else:
+ return '<?xml version="1.0" encoding="%s"?>\n%s' % (sys.getdefaultencoding(), xmlstr)
-def _marshal(obj, elementName=None, nameSpacePrefix='', nameSpaces=None, prettyPrint=False, indent=0, knownTypes=None):
+def _marshal(obj, elementName=None, nameSpacePrefix="", nameSpaces=None, prettyPrint=False, indent=0, knownTypes=None):
+ xmlMarshallerLogger.debug("--> _marshal: elementName=%s, type=%s, obj=%s" % (elementName, type(obj), str(obj)))
+ xmlString = None
if prettyPrint or indent:
- prefix = ' '*indent
- newline = '\n'
+ prefix = " "*indent
+ newline = "\n"
increment = 4
else:
- prefix = ''
- newline = ''
+ prefix = ""
+ newline = ""
increment = 0
- ## Determine the XML element name. If it isn't specified in the
- ## parameter list, look for it in the __xmlname__ Python
+ ## Determine the XML element name. If it isn"t specified in the
+ ## parameter list, look for it in the __xmlname__ Lang
## attribute, else use the default generic BASETYPE_ELEMENT_NAME.
if not nameSpaces: nameSpaces = {} # Need to do this since if the {} is a default parameter it gets shared by all calls into the function
- nameSpaceAttrs = ''
+ nameSpaceAttrs = ""
if knownTypes == None:
knownTypes = {}
- if hasattr(obj, '__xmlnamespaces__'):
- for nameSpaceKey, nameSpaceUrl in getattr(obj, '__xmlnamespaces__').items():
- if nameSpaceUrl in nameSpaces:
+ if hasattr(obj, "__xmlnamespaces__"):
+ for nameSpaceKey, nameSpaceUrl in getattr(obj, "__xmlnamespaces__").items():
+ if nameSpaceUrl in asDict(nameSpaces):
nameSpaceKey = nameSpaces[nameSpaceUrl]
else:
-## # TODO: Wait to do this until there is shared state for use when going through the object graph
-## origNameSpaceKey = nameSpaceKey # Make sure there is no key collision, ie: same key referencing two different URL's
+## # TODO: Wait to do this until there is shared for use when going through the object graph
+## origNameSpaceKey = nameSpaceKey # Make sure there is no key collision, ie: same key referencing two different URL"s
## i = 1
## while nameSpaceKey in nameSpaces.values():
## nameSpaceKey = origNameSpaceKey + str(i)
## i += 1
nameSpaces[nameSpaceUrl] = nameSpaceKey
- if nameSpaceKey == '':
+ if nameSpaceKey == "":
nameSpaceAttrs += ' xmlns="%s" ' % (nameSpaceUrl)
else:
nameSpaceAttrs += ' xmlns:%s="%s" ' % (nameSpaceKey, nameSpaceUrl)
nameSpaceAttrs = nameSpaceAttrs.rstrip()
- if hasattr(obj, '__xmldefaultnamespace__'):
- nameSpacePrefix = getattr(obj, '__xmldefaultnamespace__') + ':'
+ if hasattr(obj, "__xmldefaultnamespace__"):
+ nameSpacePrefix = getattr(obj, "__xmldefaultnamespace__") + ":"
if not elementName:
- if hasattr(obj, '__xmlname__'):
+ if hasattr(obj, "__xmlname__"):
elementName = nameSpacePrefix + obj.__xmlname__
else:
elementName = nameSpacePrefix + BASETYPE_ELEMENT_NAME
else:
elementName = nameSpacePrefix + elementName
- if hasattr(obj, '__xmlsequencer__'):
+ if hasattr(obj, "__xmlsequencer__"):
elementAdd = obj.__xmlsequencer__
else:
elementAdd = None
members_to_skip = []
## Add more members_to_skip based on ones the user has selected
## via the __xmlexclude__ attribute.
- if hasattr(obj, '__xmlexclude__'):
+ if hasattr(obj, "__xmlexclude__"):
## print "marshal: found __xmlexclude__"
- members_to_skip += list(obj.__xmlexclude__)
+ members_to_skip.extend(obj.__xmlexclude__)
# Marshal the attributes that are selected to be XML attributes.
- objattrs = ''
- className = obj.__class__.__name__
+ objattrs = ""
+ className = ag_className(obj)
classNamePrefix = "_" + className
- if hasattr(obj, '__xmlattributes__'):
+ if hasattr(obj, "__xmlattributes__"):
## print "marshal: found __xmlattributes__"
xmlattributes = obj.__xmlattributes__
- members_to_skip += xmlattributes
+ members_to_skip.extend(xmlattributes)
for attr in xmlattributes:
internalAttrName = attr
+ ifDefPy()
if (attr.startswith("__") and not attr.endswith("__")):
internalAttrName = classNamePrefix + attr
+ endIfDef()
# Fail silently if a python attribute is specified to be
# an XML attribute but is missing.
## print "marshal: processing attribute ", internalAttrName
- try:
- value = obj.__dict__[internalAttrName]
- except KeyError:
- continue
-## # But, check and see if it is a property first:
-## if (objutils.hasPropertyValue(obj, attr)):
-## value = getattr(obj, attr)
-## else:
-## continue
+ attrs = obj.__dict__
+ value = attrs.get(internalAttrName)
xsdElement = None
- if hasattr(obj, '__xsdcomplextype__'):
+ complexType = getComplexType(obj)
+ if (complexType != None):
## print "marshal: found __xsdcomplextype__"
- complexType = getattr(obj, '__xsdcomplextype__')
xsdElement = complexType.findElement(attr)
- if xsdElement:
+ if (xsdElement != None):
default = xsdElement.default
- if default == value or default == _getXmlValue(value):
- continue
+ if (default != None):
+ if ((default == value) or (default == _getXmlValue(value))):
+ continue
+ else:
+ if (value == None):
+ continue
elif value == None:
continue
else:
value = "false"
- attrNameSpacePrefix = ''
- if hasattr(obj, '__xmlattrnamespaces__'):
+ attrNameSpacePrefix = ""
+ if hasattr(obj, "__xmlattrnamespaces__"):
## print "marshal: found __xmlattrnamespaces__"
- for nameSpaceKey, nameSpaceAttributes in getattr(obj, '__xmlattrnamespaces__').items():
- if nameSpaceKey == nameSpacePrefix[:-1]: # Don't need to specify attribute namespace if it is the same as it's element
+ for nameSpaceKey, nameSpaceAttributes in getattr(obj, "__xmlattrnamespaces__").iteritems():
+ if nameSpaceKey == nameSpacePrefix[:-1]: # Don't need to specify attribute namespace if it is the same as its element
continue
if attr in nameSpaceAttributes:
- attrNameSpacePrefix = nameSpaceKey + ':'
+ attrNameSpacePrefix = nameSpaceKey + ":"
break
-## if attr.startswith('_'):
+## if attr.startswith("_"):
## attr = attr[1:]
- if (hasattr(obj, "__xmlrename__") and attr in obj.__xmlrename__):
+ if (hasattr(obj, "__xmlrename__") and attr in asDict(obj.__xmlrename__)):
## print "marshal: found __xmlrename__ (and its attribute)"
attr = obj.__xmlrename__[attr]
- objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, value)
+ objattrs += ' %s%s="%s"' % (attrNameSpacePrefix, attr, str(value))
## print "marshal: new objattrs is: ", objattrs
- if isinstance(obj, NoneType):
- return ''
+ if (obj == None):
+ xmlString = [""]
elif isinstance(obj, bool):
- return ['%s<%s objtype="bool">%s</%s>%s' % (prefix, elementName, obj, elementName, newline)]
+ xmlString = ['%s<%s objtype="bool">%s</%s>%s' % (prefix, elementName, obj, elementName, newline)]
elif isinstance(obj, int):
- return ['''%s<%s objtype="int">%s</%s>%s''' % (prefix, elementName, str(obj), elementName, newline)]
+ xmlString = ['%s<%s objtype="int">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, long):
- return ['%s<%s objtype="long">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
+ xmlString = ['%s<%s objtype="long">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, float):
- return ['%s<%s objtype="float">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
+ xmlString = ['%s<%s objtype="float">%s</%s>%s' % (prefix, elementName, str(obj), elementName, newline)]
elif isinstance(obj, unicode): # have to check before basestring - unicode is instance of base string
- return ['''%s<%s>%s</%s>%s''' % (prefix, elementName, saxutils.escape(obj.encode()), elementName, newline)]
+ xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj.encode()), elementName, newline)]
elif isinstance(obj, basestring):
- return ['''%s<%s>%s</%s>%s''' % (prefix, elementName, saxutils.escape(obj), elementName, newline)]
+ xmlString = ['%s<%s>%s</%s>%s' % (prefix, elementName, saxutils.escape(obj), elementName, newline)]
elif isinstance(obj, list):
if len(obj) < 1:
- return ''
- xmlString = ['%s<%s objtype="list">%s' % (prefix, elementName, newline)]
- for item in obj:
- xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
- xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
- return xmlString
+ xmlString = ""
+ else:
+ xmlString = ['%s<%s objtype="list">%s' % (prefix, elementName, newline)]
+ for item in obj:
+ xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
+ xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
elif isinstance(obj, tuple):
if len(obj) < 1:
- return ''
- xmlString = ['%s<%s objtype="list" mutable="false">%s' % (prefix, elementName, newline)]
- for item in obj:
- xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
- xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
- return xmlString
+ xmlString = ""
+ else:
+ xmlString = ['%s<%s objtype="list" mutable="false">%s' % (prefix, elementName, newline)]
+ for item in obj:
+ xmlString.extend(_marshal(item, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
+ xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
elif isinstance(obj, dict):
xmlString = ['%s<%s objtype="dict">%s' % (prefix, elementName, newline)]
- subprefix = prefix + ' '*increment
+ subprefix = prefix + " "*increment
subindent = indent + 2*increment
for key, val in obj.iteritems():
- xmlString.append("%s<key>%s" % (subprefix, newline))
- xmlString.extend(_marshal(key, indent=subindent, knownTypes=knownTypes))
- xmlString.append("%s</key>%s%s<value>%s" % (subprefix, newline, subprefix, newline))
- xmlString.extend(_marshal(val, nameSpaces=nameSpaces, indent=subindent, knownTypes=knownTypes))
- xmlString.append("%s</value>%s" % (subprefix, newline))
- xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
- return xmlString
+## if (isinstance(key, basestring) and key is legal identifier):
+## xmlString.extend(_marshal(val, elementName=key, nameSpaces=nameSpaces, indent=subindent, knownTypes=knownTypes))
+## else:
+ xmlString.append("%s<%s>%s" % (subprefix, DICT_ITEM_NAME, newline))
+ xmlString.extend(_marshal(key, elementName=DICT_ITEM_KEY_NAME, indent=subindent, knownTypes=knownTypes))
+ xmlString.extend(_marshal(val, elementName=DICT_ITEM_VALUE_NAME, nameSpaces=nameSpaces, indent=subindent, knownTypes=knownTypes))
+ xmlString.append("%s</%s>%s" % (subprefix, DICT_ITEM_NAME, newline))
+ xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
else:
- moduleName = obj.__class__.__module__
- if (moduleName == "activegrid.model.schema"):
- xmlString = ['%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)]
+ # Only add the objtype if the element tag is unknown to us.
+ objname = knownTypes.get(elementName)
+ if (objname != None):
+ xmlString = ["%s<%s%s%s" % (prefix, elementName, nameSpaceAttrs, objattrs)]
else:
- # Only add the objtype if the element tag is unknown to us.
- try:
- objname = knownTypes[elementName]
- xmlString = ['%s<%s%s%s' % (prefix, elementName, nameSpaceAttrs, objattrs)]
- except KeyError:
- xmlString = ['%s<%s%s%s objtype="%s.%s"' % (prefix, elementName, nameSpaceAttrs, objattrs, moduleName, className)]
-## print "UnknownTypeException: Unknown type (%s.%s) passed to marshaller" % (moduleName, className)
- # get the member, value pairs for the object, filtering out the types we don't support
+ xmlString = ['%s<%s%s%s objtype="%s.%s"' % (prefix, elementName, nameSpaceAttrs, objattrs, obj.__class__.__module__, className)]
+ # get the member, value pairs for the object, filtering out the types we don"t support
if (elementAdd != None):
- prefix += increment*' '
+ prefix += increment*" "
indent += increment
xmlMemberString = []
- if hasattr(obj, '__xmlbody__'):
+ if hasattr(obj, "__xmlbody__"):
xmlbody = getattr(obj, obj.__xmlbody__)
if xmlbody != None:
xmlMemberString.append(xmlbody)
else:
- entryList = obj.__dict__.items()
-## # Add in properties
-## for key in obj.__class__.__dict__.iterkeys():
-## if (key not in members_to_skip and key not in obj.__dict__
-## and objutils.hasPropertyValue(obj, key)):
-## value = getattr(obj, key)
-## entryList.append((key, value))
- entryList.sort()
- if hasattr(obj, '__xmlattrgroups__'):
- attrGroups = obj.__xmlattrgroups__
- if (not isinstance(attrGroups,dict)):
+ if hasattr(obj, "__xmlattrgroups__"):
+ attrGroups = obj.__xmlattrgroups__.copy()
+ if (not isinstance(attrGroups, dict)):
raise "__xmlattrgroups__ is not a dict, but must be"
- for n in attrGroups:
- v = attrGroups[n]
- members_to_skip += v
+ for n in attrGroups.iterkeys():
+ members_to_skip.extend(attrGroups[n])
else:
attrGroups = {}
# add the list of all attributes to attrGroups
- eList = []
- for x, z in entryList:
- eList.append(x)
- attrGroups['__nogroup__'] = eList
+ eList = obj.__dict__.keys()
+ eList.sort()
+ attrGroups["__nogroup__"] = eList
- for eName in attrGroups:
- eList = attrGroups[eName]
- if (eName != '__nogroup__'):
- prefix += increment*' '
+ for eName, eList in attrGroups.iteritems():
+ if (eName != "__nogroup__"):
+ prefix += increment*" "
indent += increment
xmlMemberString.append('%s<%s objtype="None">%s' % (prefix, eName, newline))
for name in eList:
value = obj.__dict__[name]
-## print " ", name, " = ", value
-## # special name handling for private "__*" attributes:
-## # remove the _<class-name> added by Python
-## if name.startswith(classNamePrefix): name = name[len(classNamePrefix):]
- if eName == '__nogroup__' and name in members_to_skip: continue
- if name.startswith('__') and name.endswith('__'): continue
-## idx = name.find('__')
-## if idx > 0:
-## newName = name[idx+2:]
-## if newName:
-## name = newName
-## print "marshal: processing subElement ", name
+ if eName == "__nogroup__" and name in members_to_skip: continue
+ if name.startswith("__") and name.endswith("__"): continue
subElementNameSpacePrefix = nameSpacePrefix
- if hasattr(obj, '__xmlattrnamespaces__'):
- for nameSpaceKey, nameSpaceValues in getattr(obj, '__xmlattrnamespaces__').items():
+ if hasattr(obj, "__xmlattrnamespaces__"):
+ for nameSpaceKey, nameSpaceValues in getattr(obj, "__xmlattrnamespaces__").iteritems():
if name in nameSpaceValues:
- subElementNameSpacePrefix = nameSpaceKey + ':'
+ subElementNameSpacePrefix = nameSpaceKey + ":"
break
# handle sequences listed in __xmlflattensequence__
# specially: instead of listing the contained items inside
- # of a separate list, as god intended, list them inside
+ # of a separate list, as God intended, list them inside
# the object containing the sequence.
- if hasattr(obj, '__xmlflattensequence__') and name in obj.__xmlflattensequence__ and value:
- try:
- xmlnametuple = obj.__xmlflattensequence__[name]
- xmlname = None
- if len(xmlnametuple) == 1:
- xmlname = xmlnametuple[0]
- except:
- xmlname = name
-## xmlname = name.lower()
+ if (hasattr(obj, "__xmlflattensequence__") and (value != None) and (name in asDict(obj.__xmlflattensequence__))):
+ xmlnametuple = obj.__xmlflattensequence__[name]
+ if (xmlnametuple == None):
+ xmlnametuple = [name]
+ elif (not isinstance(xmlnametuple, (tuple,list))):
+ xmlnametuple = [str(xmlnametuple)]
+ xmlname = None
+ if (len(xmlnametuple) == 1):
+ xmlname = xmlnametuple[0]
+## ix = 0
for seqitem in value:
+## xmlname = xmlnametuple[ix]
+## ix += 1
+## if (ix >= len(xmlnametuple)):
+## ix = 0
xmlMemberString.extend(_marshal(seqitem, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
else:
- if (hasattr(obj, "__xmlrename__") and name in obj.__xmlrename__):
+ if (hasattr(obj, "__xmlrename__") and name in asDict(obj.__xmlrename__)):
xmlname = obj.__xmlrename__[name]
else:
xmlname = name
-## if (indent > 30):
-## print "getting pretty deep, xmlname = ", xmlname
xmlMemberString.extend(_marshal(value, xmlname, subElementNameSpacePrefix, nameSpaces=nameSpaces, indent=indent+increment, knownTypes=knownTypes))
- if (eName != '__nogroup__'):
-## print "marshal: Completing attrGroup ", eName
- xmlMemberString.append('%s</%s>%s' % (prefix, eName, newline))
+ if (eName != "__nogroup__"):
+ xmlMemberString.append("%s</%s>%s" % (prefix, eName, newline))
prefix = prefix[:-increment]
indent -= increment
# if we have nested elements, add them here, otherwise close the element tag immediately.
- xmlMemberString = filter(lambda x: len(x)>0, xmlMemberString)
+ newList = []
+ for s in xmlMemberString:
+ if (len(s) > 0): newList.append(s)
+ xmlMemberString = newList
if len(xmlMemberString) > 0:
- xmlString.append('>')
- if hasattr(obj, '__xmlbody__'):
+ xmlString.append(">")
+ if hasattr(obj, "__xmlbody__"):
xmlString.extend(xmlMemberString)
- xmlString.append('</%s>%s' % (elementName, newline))
+ xmlString.append("</%s>%s" % (elementName, newline))
else:
xmlString.append(newline)
if (elementAdd != None):
- xmlString.append('%s<%s>%s' % (prefix, elementAdd, newline))
+ xmlString.append("%s<%s>%s" % (prefix, elementAdd, newline))
xmlString.extend(xmlMemberString)
if (elementAdd != None):
- xmlString.append('%s</%s>%s' % (prefix, elementAdd, newline))
+ xmlString.append("%s</%s>%s" % (prefix, elementAdd, newline))
prefix = prefix[:-increment]
indent -= increment
- xmlString.append('%s</%s>%s' % (prefix, elementName, newline))
+ xmlString.append("%s</%s>%s" % (prefix, elementName, newline))
else:
- xmlString.append('/>%s' % newline)
- return xmlString
+ xmlString.append("/>%s" % newline)
+## return xmlString
+ xmlMarshallerLogger.debug("<-- _marshal: %s" % str(xmlString))
+ return xmlString
+
+# A simple test, to be executed when the xmlmarshaller is run standalone
+class MarshallerPerson:
+ __xmlname__ = "person"
+ __xmlexclude__ = ["fabulousness",]
+ __xmlattributes__ = ("nonSmoker",)
+ __xmlrename__ = {"_phoneNumber": "telephone"}
+ __xmlflattensequence__ = {"favoriteWords": ("vocabulary",)}
+ __xmlattrgroups__ = {"name": ["firstName", "lastName"], "address": ["addressLine1", "city", "state", "zip"]}
+
+ def setPerson(self):
+ self.firstName = "Albert"
+ self.lastName = "Camus"
+ self.addressLine1 = "23 Absurd St."
+ self.city = "Ennui"
+ self.state = "MO"
+ self.zip = "54321"
+ self._phoneNumber = "808-303-2323"
+ self.favoriteWords = ["angst", "ennui", "existence"]
+ self.phobias = ["war", "tuberculosis", "cars"]
+ self.weight = 150
+ self.fabulousness = "tres tres"
+ self.nonSmoker = False
+
+if isMain(__name__):
+ p1 = MarshallerPerson()
+ p1.setPerson()
+ xmlP1 = marshal(p1, prettyPrint=True, encoding="utf-8")
+ print "\n########################"
+ print "# testPerson test case #"
+ print "########################"
+ print xmlP1
+ p2 = unmarshal(xmlP1)
+ xmlP2 = marshal(p2, prettyPrint=True, encoding="utf-8")
+ if xmlP1 == xmlP2:
+ print "Success: repeated marshalling yields identical results"
+ else:
+ print "Failure: repeated marshalling yields different results"
+ print xmlP2
# License: wxWindows License
#----------------------------------------------------------------------------
import xml.sax
-import xml.sax.handler
-
+from activegrid.util.lang import *
class XMLPrettyPrinter(xml.sax.ContentHandler):
def __init__(self, indentationChar=' ', newlineChar='\n'):
## ContentHandler methods
def startElement(self, name, attrs):
- indentation = self.newlineChar + (self.indentationLevel * self.indentationChar)
+ indentation = self.newlineChar + (self.indentationChar * self.indentationLevel)
# build attribute string
attrstring = ''
for attr in attrs.getNames():
self.hitCharData = False
def characters(self, content):
+## print "--> characters(%s)" % content
self.xmlOutput += content
self.hitCharData = True
self.indentationLevel -= 1
indentation = ''
if not self.hitCharData:
-## indentation += self.newlineChar + (self.indentationLevel * self.indentationChar)
- indentation += self.indentationLevel * self.indentationChar
+ indentation += self.newlineChar + (self.indentationChar * self.indentationLevel)
+## indentation += self.indentationChar * self.indentationLevel
else:
self.hitCharData = False
- self.xmlOutput += '%s</%s>%s' % (indentation, self.elementStack.pop(), self.newlineChar)
+## self.xmlOutput += '%s</%s>%s' % (indentation, self.elementStack.pop(), self.newlineChar)
+ self.xmlOutput += '%s</%s>' % (indentation, self.elementStack.pop())
def getXMLString(self):
return self.xmlOutput[1:]
xml.sax.parseString(xmlstr, xpp)
return xpp.getXMLString()
-if __name__ == '__main__':
+if isMain(__name__):
simpleTestString = """<one>some text<two anattr="booga">two's data</two></one>"""
- print prettyprint(simpleTestString)
+ print xmlprettyprint(simpleTestString)
--- /dev/null
+#----------------------------------------------------------------------------
+# Name: xmlutils.py
+# Purpose: XML and Marshaller Utilities
+#
+# Author: Jeff Norton
+#
+# Created: 6/2/05
+# CVS-ID: $Id$
+# Copyright: (c) 2004-2005 ActiveGrid, Inc.
+# License: wxWindows License
+#----------------------------------------------------------------------------
+
+import os
+import activegrid.util.objutils as objutils
+import activegrid.util.xmlmarshaller as xmlmarshaller
+
+agKnownTypes = None
+
+def defaultLoad(fileObject, knownTypes=None):
+ xml = fileObject.read()
+ loadedObject = unmarshal(xml, knownTypes=knownTypes)
+ if hasattr(fileObject, 'name'):
+ loadedObject.fileName = os.path.abspath(fileObject.name)
+ loadedObject.initialize()
+ return loadedObject
+
+def unmarshal(xml, knownTypes=None):
+ if not knownTypes: knownTypes = getAgKnownTypes()
+ return xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
+
+def defaultSave(fileObject, objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
+ xml = marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
+ fileObject.write(xml)
+ fileObject.flush()
+
+def marshal(objectToSave, prettyPrint=True, knownTypes=None, encoding='utf-8'):
+ if not knownTypes: knownTypes = getAgKnownTypes()
+ return xmlmarshaller.marshal(objectToSave, prettyPrint=prettyPrint, knownTypes=knownTypes, encoding=encoding)
+
+def cloneObject(objectToClone, knownTypes=None, encoding='utf-8'):
+ if not knownTypes: knownTypes = getAgKnownTypes()
+ xml = xmlmarshaller.marshal(objectToClone, prettyPrint=True, knownTypes=knownTypes, encoding=encoding)
+ clonedObject = xmlmarshaller.unmarshal(xml, knownTypes=knownTypes)
+ if hasattr(objectToClone, 'fileName'):
+ clonedObject.fileName = objectToClone.fileName
+ try:
+ clonedObject.initialize()
+ except AttributeError:
+ pass
+ return clonedObject
+
+def getAgKnownTypes():
+ import activegrid.model.processmodel
+ import activegrid.model.schema
+ import activegrid.data.dataservice
+ import activegrid.server.deployment
+ global agKnownTypes
+ if agKnownTypes == None:
+ tmpAgKnownTypes = {}
+ AG_TYPE_MAPPING = {
+ "ag:append" : "activegrid.model.processmodel.AppendOperation",
+ "ag:body" : "activegrid.model.processmodel.Body",
+ "ag:cssRule" : "activegrid.model.processmodel.CssRule",
+ "ag:datasource" : "activegrid.data.dataservice.DataSource",
+ "ag:debug" : "activegrid.model.processmodel.DebugOperation",
+ "ag:deployment" : "activegrid.server.deployment.Deployment",
+ "ag:glue" : "activegrid.model.processmodel.Glue",
+ "ag:hr" : "activegrid.model.processmodel.HorizontalRow",
+ "ag:image" : "activegrid.model.processmodel.Image",
+ "ag:inputs" : "activegrid.model.processmodel.Inputs",
+ "ag:label" : "activegrid.model.processmodel.Label",
+ "ag:processmodel" : "activegrid.model.processmodel.ProcessModel",
+ "ag:processmodelref" : "activegrid.server.deployment.ProcessModelRef",
+ "ag:query" : "activegrid.model.processmodel.Query",
+ "ag:restParameter" : "activegrid.server.deployment.RestParameter",
+ "ag:restService" : "activegrid.server.deployment.RestService",
+ "ag:schemaOptions" : "activegrid.model.schema.SchemaOptions",
+ "ag:schemaref" : "activegrid.server.deployment.SchemaRef",
+ "ag:serviceref" : "activegrid.server.deployment.ServiceRef",
+ "ag:set" : "activegrid.model.processmodel.SetOperation",
+ "ag:text" : "activegrid.model.processmodel.Text",
+ "ag:title" : "activegrid.model.processmodel.Title",
+ "ag:view" : "activegrid.model.processmodel.View",
+ "bpws:case" : "activegrid.model.processmodel.BPELCase",
+ "bpws:catch" : "activegrid.model.processmodel.BPELCatch",
+ "bpws:faultHandlers" : "activegrid.model.processmodel.BPELFaultHandlers",
+ "bpws:invoke" : "activegrid.model.processmodel.BPELInvoke",
+ "bpws:onMessage" : "activegrid.model.processmodel.BPELOnMessage",
+ "bpws:otherwise" : "activegrid.model.processmodel.BPELOtherwise",
+ "bpws:pick" : "activegrid.model.processmodel.BPELPick",
+ "bpws:process" : "activegrid.model.processmodel.BPELProcess",
+ "bpws:receive" : "activegrid.model.processmodel.BPELReceive",
+ "bpws:reply" : "activegrid.model.processmodel.BPELReply",
+ "bpws:scope" : "activegrid.model.processmodel.BPELScope",
+ "bpws:sequence" : "activegrid.model.processmodel.BPELSequence",
+ "bpws:switch" : "activegrid.model.processmodel.BPELSwitch",
+ "bpws:terminate" : "activegrid.model.processmodel.BPELTerminate",
+ "bpws:variable" : "activegrid.model.processmodel.BPELVariable",
+ "bpws:variables" : "activegrid.model.processmodel.BPELVariables",
+ "bpws:while" : "activegrid.model.processmodel.BPELWhile",
+ "wsdl:message" : "activegrid.model.processmodel.WSDLMessage",
+ "wsdl:part" : "activegrid.model.processmodel.WSDLPart",
+ "xforms:group" : "activegrid.model.processmodel.XFormsGroup",
+ "xforms:input" : "activegrid.model.processmodel.XFormsInput",
+ "xforms:label" : "activegrid.model.processmodel.XFormsLabel",
+ "xforms:output" : "activegrid.model.processmodel.XFormsOutput",
+ "xforms:secret" : "activegrid.model.processmodel.XFormsSecret",
+ "xforms:submit" : "activegrid.model.processmodel.XFormsSubmit",
+ "xs:all" : "activegrid.model.schema.XsdSequence",
+ "xs:complexType" : "activegrid.model.schema.XsdComplexType",
+ "xs:element" : "activegrid.model.schema.XsdElement",
+ "xs:field" : "activegrid.model.schema.XsdKeyField",
+ "xs:key" : "activegrid.model.schema.XsdKey",
+ "xs:keyref" : "activegrid.model.schema.XsdKeyRef",
+ "xs:schema" : "activegrid.model.schema.Schema",
+ "xs:selector" : "activegrid.model.schema.XsdKeySelector",
+ "xs:sequence" : "activegrid.model.schema.XsdSequence",
+ }
+
+ for keyName, className in AG_TYPE_MAPPING.iteritems():
+ try:
+ tmpAgKnownTypes[keyName] = objutils.classForName(className)
+ except KeyError:
+ print "Error mapping knownType", className
+ pass
+ if len(tmpAgKnownTypes) > 0:
+ agKnownTypes = tmpAgKnownTypes
+ return agKnownTypes
if os.path.exists("tips.txt"):
wx.CallAfter(self.ShowTip, wx.GetApp().GetTopWindow(), wx.CreateFileTipProvider("tips.txt", 0))
+ wx.UpdateUIEvent.SetUpdateInterval(400) # Overhead of updating menus was too much. Change to update every 400 milliseconds.
+
# Tell the framework that everything is great
return True
import os
import os.path
+import shutil
import wx
import sys
_ = wx.GetTranslation
backupFilename = None
fileObject = None
+ copied = False
try:
# if current file exists, move it to a safe place temporarily
if os.path.exists(filename):
while os.path.exists(backupFilename):
i += 1
backupFilename = "%s.bak%s" % (filename, i)
- os.rename(filename, backupFilename)
+ shutil.copy(filename, backupFilename)
+ copied = True
fileObject = file(filename, 'w')
self.SaveObject(fileObject)
if fileObject:
fileObject.close() # file is still open, close it, need to do this before removal
- # save failed, restore old file
- if backupFilename:
- os.remove(filename)
- os.rename(backupFilename, filename)
- self.SetDocumentModificationDate()
+ # save failed, remove copied file
+ if backupFilename and copied:
+ os.remove(backupFilename)
wx.MessageBox("Could not save '%s'. %s" % (FileNameFromPath(filename), sys.exc_value),
msgTitle,
Returns True if the path's extension matches one of this template's
file filter extensions.
"""
-## print "*** path", path
-## if "*.*" in self.GetFileFilter():
-## return True
-##
ext = FindExtension(path)
if not ext: return False
return ext in self.GetFileFilter()
self._childView.Activate(False)
self._childView.Destroy()
self._childView = None
- if self._childDocument:
- self._childDocument.Destroy() # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
+ if self._childDocument: # This isn't in the wxWindows codebase but the document needs to be disposed of somehow
+ self._childDocument.DeleteContents()
+ if self._childDocument.GetDocumentManager():
+ self._childDocument.GetDocumentManager().RemoveDocument(self._childDocument)
self._childDocument = None
self.Destroy()
else:
def __init__(self):
"""Initializes the DocService."""
- wx.EvtHandler.__init__(self)
+ pass
def GetDocumentManager(self):
msgTitle = wx.GetApp().GetAppName()
if not msgTitle:
msgTitle = _("Document Options")
- wx.MessageBox("Document interface changes will not appear until the application is restarted.",
+ wx.MessageBox(_("Document interface changes will not appear until the application is restarted."),
msgTitle,
wx.OK | wx.ICON_INFORMATION,
self.GetParent())
if isinstance(document, ChildDocument) and document.GetParentDocument() == parentDocument:
if document.GetFirstView().GetFrame():
document.GetFirstView().GetFrame().SetFocus()
- if document.GetFirstView().OnClose(deleteWindow = False):
- if document.GetFirstView().GetFrame():
- document.GetFirstView().GetFrame().Close() # wxBug: Need to do this for some random reason
- else:
+ if not document.GetFirstView().OnClose():
return False
return True
"""
Initializes the AboutService.
"""
- DocService.__init__(self)
if aboutDialog:
self._dlg = aboutDialog
self._image = None
"""
Initializes the PropertyService.
"""
- DocService.__init__(self)
self._customEventHandlers = []
"""
Initializes the WindowMenu and its globals.
"""
- DocService.__init__(self)
self.ARRANGE_WINDOWS_ID = wx.NewId()
self.SELECT_WINDOW_1_ID = wx.NewId()
self.SELECT_WINDOW_2_ID = wx.NewId()