X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/a780a8dc191711b8290733ca0817e28eef6e7beb..02b800ce7c2bb1c1f08075f22be2e7412124b47f:/wxPython/samples/ide/activegrid/tool/project.py diff --git a/wxPython/samples/ide/activegrid/tool/project.py b/wxPython/samples/ide/activegrid/tool/project.py new file mode 100644 index 0000000000..babdadea42 --- /dev/null +++ b/wxPython/samples/ide/activegrid/tool/project.py @@ -0,0 +1,549 @@ +#---------------------------------------------------------------------------- +# Name: project.py +# Purpose: project model for wx.lib.pydocview +# +# Author: Morgan Hua +# +# Created: 8/25/05 +# CVS-ID: $Id$ +# Copyright: (c) 2005 ActiveGrid, Inc. +# License: wxWindows License +#---------------------------------------------------------------------------- + +import copy +import os +import os.path +import activegrid.util.xmlutils as xmlutils +from IDE import ACTIVEGRID_BASE_IDE +if not ACTIVEGRID_BASE_IDE: + import activegrid.model.basedocmgr as basedocmgr + import AppInfo + +#---------------------------------------------------------------------------- +# Constants +#---------------------------------------------------------------------------- +# Always add new versions, never edit the version number +# This allows you to upgrade the file by checking the version number +PROJECT_VERSION_050730 = '10' +PROJECT_VERSION_050826 = '11' + + +#---------------------------------------------------------------------------- +# XML Marshalling Methods +#---------------------------------------------------------------------------- + +def load(fileObject): + version = xmlutils.getAgVersion(fileObject.name) + # most current versions on top + if version == PROJECT_VERSION_050826: + fileObject.seek(0) + if ACTIVEGRID_BASE_IDE: + KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile} + else: + KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo} + project = xmlutils.load(fileObject.name, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES) + elif version == PROJECT_VERSION_050730: + fileObject.seek(0) + project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10}) + project = project.upgradeVersion() + else: + # assume it is old version without version number + fileObject.seek(0) + project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10}) + if project: + project = project.upgradeVersion() + else: + print "Project, unknown version:", version + return None + + if project: + project._projectDir = os.path.dirname(fileObject.name) + project.RelativeToAbsPath() + + return project + + +def save(fileObject, project, productionDeployment=False): + if not project._projectDir: + project._projectDir = os.path.dirname(fileObject.name) + project.AbsToRelativePath() # temporarily change it to relative paths for saving + if ACTIVEGRID_BASE_IDE: + KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile} + else: + KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo} + + savedHomeDir = project.homeDir + if productionDeployment: + # for deployments, we don't want an abs path in homeDir since that + # would tie the app to the current filesystem. So unset it. + project.homeDir = None + + xmlutils.save(fileObject.name, project, prettyPrint=True, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES) + + if productionDeployment: + project.homeDir = savedHomeDir + + project.RelativeToAbsPath() # swap it back to absolute path + + +#---------------------------------------------------------------------------- +# Classes +#---------------------------------------------------------------------------- + +class BaseProject(object): + + __xmlname__ = "project" + __xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback') + __xmlattributes__ = ("_homeDir", "version") + __xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" } + __xmlflattensequence__ = { "_files":("file",) } + __xmldefaultnamespace__ = xmlutils.AG_NS_URL + __xmlattrnamespaces__ = { "ag": ["version", "_homeDir"] } + + + def __init__(self): + self.__xmlnamespaces__ = { "ag" : xmlutils.AG_NS_URL } + self.version = PROJECT_VERSION_050826 + self._files = [] + self._projectDir = None # default for homeDir, set on load + self._homeDir = None # user set homeDir for use in calculating relative path + if not ACTIVEGRID_BASE_IDE: + self._appInfo = AppInfo.AppInfo() + + + def __copy__(self): + clone = Project() + clone._files = [copy.copy(file) for file in self._files] + clone._projectDir = self._projectDir + clone._homeDir = self._homeDir + if not ACTIVEGRID_BASE_IDE: + clone._appInfo = self._appInfo + return clone + + + def initialize(self): + """ Required method for xmlmarshaller """ + pass + + + def GetAppInfo(self): + return self._appInfo + + + def AddFile(self, filePath=None, logicalFolder=None, type=None, name=None, file=None): + """ Usage: self.AddFile(filePath, logicalFolder, type, name) # used for initial generation of object + self.AddFile(file=xyzFile) # normally used for redo/undo + Add newly created file object using filePath and logicalFolder or given file object + """ + if file: + self._files.append(file) + else: + self._files.append(ProjectFile(filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback)) + + + def RemoveFile(self, file): + self._files.remove(file) + + + def FindFile(self, filePath): + if filePath: + for file in self._files: + if file.filePath == filePath: + return file + + return None + + + def _GetFilePaths(self): + return [file.filePath for file in self._files] + + + filePaths = property(_GetFilePaths) + + + def _GetLogicalFolders(self): + folders = [] + for file in self._files: + if file.logicalFolder and file.logicalFolder not in folders: + folders.append(file.logicalFolder) + return folders + + + logicalFolders = property(_GetLogicalFolders) + + + def _GetPhysicalFolders(self): + physicalFolders = [] + for file in self._files: + physicalFolder = file.physicalFolder + if physicalFolder and physicalFolder not in physicalFolders: + physicalFolders.append(physicalFolder) + return physicalFolders + + + physicalFolders = property(_GetPhysicalFolders) + + + def _GetHomeDir(self): + if self._homeDir: + return self._homeDir + else: + return self._projectDir + + + def _SetHomeDir(self, parentPath): + self._homeDir = parentPath + + + def _IsDefaultHomeDir(self): + return (self._homeDir == None) + + + isDefaultHomeDir = property(_IsDefaultHomeDir) + + + homeDir = property(_GetHomeDir, _SetHomeDir) + + + def GetRelativeFolders(self): + relativeFolders = [] + for file in self._files: + relFolder = file.GetRelativeFolder(self.homeDir) + if relFolder and relFolder not in relativeFolders: + relativeFolders.append(relFolder) + return relativeFolders + + + def AbsToRelativePath(self): + for file in self._files: + file.AbsToRelativePath(self.homeDir) + + + def RelativeToAbsPath(self): + for file in self._files: + file.RelativeToAbsPath(self.homeDir) + + + #---------------------------------------------------------------------------- + # BaseDocumentMgr methods + #---------------------------------------------------------------------------- + + + def fullPath(self, fileName): + fileName = super(BaseProject, self).fullPath(fileName) + + if os.path.isabs(fileName): + absPath = fileName + elif self.homeDir: + absPath = os.path.join(self.homeDir, fileName) + else: + absPath = os.path.abspath(fileName) + return os.path.normpath(absPath) + + + def documentRefFactory(self, name, fileType, filePath): + return ProjectFile(filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback) + + + def findAllRefs(self): + return self._files + + + def GetXFormsDirectory(self): + forms = self.findRefsByFileType(basedocmgr.FILE_TYPE_XFORM) + filePaths = map(lambda form: form.filePath, forms) + xformdir = os.path.commonprefix(filePaths) + if not xformdir: + xformdir = self.homeDir + return xformdir + + + def setRefs(self, files): + self._files = files + + + def findRefsByFileType(self, fileType): + fileList = [] + for file in self._files: + if fileType == file.type: + fileList.append(file) + return fileList + + + def GenerateServiceRefPath(self, wsdlFilePath): + # HACK: temporary solution to getting wsdlag path from wsdl path. + import wx + from WsdlAgEditor import WsdlAgDocument + ext = WsdlAgDocument.WSDL_AG_EXT + for template in wx.GetApp().GetDocumentManager().GetTemplates(): + if template.GetDocumentType() == WsdlAgDocument: + ext = template.GetDefaultExtension() + break; + wsdlAgFilePath = os.path.splitext(wsdlFilePath)[0] + ext + return wsdlAgFilePath + + + def SetDocCallback(self, getDocCallback): + self._getDocCallback = getDocCallback + for file in self._files: + file._getDocCallback = getDocCallback + + +if ACTIVEGRID_BASE_IDE: + class Project(BaseProject): + pass +else: + class Project(BaseProject, basedocmgr.BaseDocumentMgr): + pass + + +class ProjectFile(object): + __xmlname__ = "file" + __xmlexclude__ = ('_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',) + __xmlattributes__ = ["filePath", "logicalFolder", "type", "name"] + __xmldefaultnamespace__ = xmlutils.AG_NS_URL + + + def __init__(self, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None): + self.filePath = filePath + self.logicalFolder = logicalFolder + self.type = type + self.name = name + self._getDocCallback = getDocCallback + self._docCallbackCacheReturnValue = None + self._docModelCallbackCacheReturnValue = None + self._doc = None + + + def _GetDocumentModel(self): + # possible bug is if document gets replaced outside of IDE, where we'll return previous doc. + # originally added a timestamp check but that increased the time again to 4x + if self._docModelCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up. + return self._docModelCallbackCacheReturnValue + + if self._getDocCallback: + self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath) + return self._docModelCallbackCacheReturnValue + + return None + + + document = property(_GetDocumentModel) + + + def _GetDocument(self): + # Hack, just return the IDE document wrapper that corresponds to the runtime document model + # callers should have called ".document" before calling ".ideDocument" + if self._docCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up. + return self._docCallbackCacheReturnValue + return None + + + ideDocument = property(_GetDocument) + + + def _typeEnumeration(self): + return basedocmgr.FILE_TYPE_LIST + + + def _GetPhysicalFolder(self): + dir = None + if self.filePath: + dir = os.path.dirname(self.filePath) + if os.sep != '/': + dir = dir.replace(os.sep, '/') # require '/' as delimiter + return dir + + + physicalFolder = property(_GetPhysicalFolder) + + + def GetRelativeFolder(self, parentPath): + parentPathLen = len(parentPath) + + dir = None + if self.filePath: + dir = os.path.dirname(self.filePath) + if dir.startswith(parentPath): + dir = "." + dir[parentPathLen:] # convert to relative path + if os.sep != '/': + dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility. + return dir + + + def AbsToRelativePath(self, parentPath): + """ Used to convert path to relative path for saving (disk format) """ + parentPathLen = len(parentPath) + + if self.filePath.startswith(parentPath): + self.filePath = "." + self.filePath[parentPathLen:] # convert to relative path + if os.sep != '/': + self.filePath = self.filePath.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility. + else: + pass # not a decendant of project, use absolute path + + + def RelativeToAbsPath(self, parentPath): + """ Used to convert path to absolute path (for any necessary disk access) """ + if self.filePath.startswith("."): # relative to project file + self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath)) + + + #---------------------------------------------------------------------------- + # BaseDocumentMgr methods + #---------------------------------------------------------------------------- + + def _GetDoc(self): + # HACK: temporary solution. + import wx + import wx.lib.docview + if not self._doc: + docMgr = wx.GetApp().GetDocumentManager() + + doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW) + if (doc == None): # already open + docs = docMgr.GetDocuments() + for d in docs: + if d.GetFilename() == self.filePath: + doc = d + break + self._doc = doc + return self._doc + + + def _GetLocalServiceProcessName(self): + # HACK: temporary solution to getting process name from wsdlag file. + return self._GetDoc().GetModel().processName + + + processName = property(_GetLocalServiceProcessName) + + + def _GetStateful(self): + # HACK: temporary solution to getting stateful from wsdlag file. + return self._GetDoc().GetModel().stateful + + + def _SetStateful(self, stateful): + # HACK: temporary solution to setting stateful from wsdlag file. + self._GetDoc().GetModel().stateful = stateful + + + stateful = property(_GetStateful, _SetStateful) + + + def _GetLocalServiceCodeFile(self): + # HACK: temporary solution to getting class name from wsdlag file. + return self._GetDoc().GetModel().localServiceCodeFile + + + def _SetLocalServiceCodeFile(self, codefile): + # HACK: temporary solution to setting class name from wsdlag file. + self._GetDoc().GetModel().localServiceCodeFile = codefile + + + localServiceCodeFile = property(_GetLocalServiceCodeFile, _SetLocalServiceCodeFile) + + + def _GetLocalServiceClassName(self): + # HACK: temporary solution to getting class name from wsdlag file. + return self._GetDoc().GetModel().localServiceClassName + + + def _SetLocalServiceClassName(self, className): + # HACK: temporary solution to setting class name from wsdlag file. + self._GetDoc().GetModel().localServiceClassName = className + + + localServiceClassName = property(_GetLocalServiceClassName, _SetLocalServiceClassName) + + + +# only activate this code if we programatically need to access these values +## def _GetRssServiceBaseURL(self): +## return self._GetDoc().GetModel().rssServiceBaseURL +## +## +## def _SetRssServiceBaseURL(self, baseURL): +## self._GetDoc().GetModel().rssServiceBaseURL = baseURL +## +## +## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL) +## +## +## def _GetRssServiceRssVersion(self): +## return self._GetDoc().GetModel().rssServiceRssVersion +## +## +## def _SetRssServiceRssVersion(self, rssVersion): +## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion +## +## +## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion) + + + def _GetServiceRefServiceType(self): + # HACK: temporary solution to getting service type from wsdlag file. + model = self._GetDoc().GetModel() + if hasattr(model, 'serviceType'): + return model.serviceType + else: + return None + + + def _SetServiceRefServiceType(self, serviceType): + # HACK: temporary solution to getting service type from wsdlag file. + self._GetDoc().GetModel().serviceType = serviceType + + + serviceType = property(_GetServiceRefServiceType, _SetServiceRefServiceType) + + + def getExternalPackage(self): + # HACK: temporary solution to getting custom code filename from wsdlag file. + import activegrid.server.deployment as deploymentlib + + appInfo = self._GetDoc().GetAppInfo() + + if appInfo.language == None: + language = deploymentlib.LANGUAGE_DEFAULT + else: + language = appInfo.language + + if language == deploymentlib.LANGUAGE_PYTHON: + suffix = ".py" + elif language == deploymentlib.LANGUAGE_PHP: + suffix = ".php" + pyFilename = self.name + suffix + return self._GetDoc().GetAppDocMgr().fullPath(pyFilename) + + +#---------------------------------------------------------------------------- +# Old Classes +#---------------------------------------------------------------------------- + +class Project_10: + """ Version 1.0, kept for upgrading to latest version. Over time, this should be deprecated. """ + __xmlname__ = "project" + __xmlrename__ = { "_files":"files"} + __xmlexclude__ = ('fileName',) + __xmlattributes__ = ["version"] + + + def __init__(self): + self.version = PROJECT_VERSION_050730 + self._files = [] + + + def initialize(self): + """ Required method for xmlmarshaller """ + pass + + + def upgradeVersion(self): + currModel = Project() + for file in self._files: + currModel._files.append(ProjectFile(file)) + return currModel + +