📄 projecteditor.py
字号:
#----------------------------------------------------------------------------# Name: ProjectEditor.py# Purpose: IDE-style Project Editor for wx.lib.pydocview## Author: Morgan Hua, Peter Yared## Created: 8/15/03# CVS-ID: $Id: ProjectEditor.py,v 1.10 2006/10/03 21:31:28 RD Exp $# Copyright: (c) 2003-2006 ActiveGrid, Inc.# License: wxWindows License#----------------------------------------------------------------------------import wximport wx.lib.docviewimport wx.lib.pydocviewimport wx.lib.buttonsimport Serviceimport copyimport osimport os.pathimport setsimport sysimport timeimport typesimport activegrid.util.appdirs as appdirsimport activegrid.util.fileutils as fileutilsimport activegrid.util.aglogging as agloggingimport UICommonimport Wizardimport SVNServiceimport project as projectlibimport ExtensionServicefrom IDE import ACTIVEGRID_BASE_IDEif not ACTIVEGRID_BASE_IDE: import activegrid.server.deployment as deploymentlib import ProcessModelEditor import DataModelEditor import DeploymentGeneration import WsdlAgEditor import WsdlAgModel APP_LAST_LANGUAGE = "LastLanguage" import activegrid.model.basedocmgr as basedocmgr import activegrid.model.basemodel as basemodel import activegrid.model.projectmodel as projectmodel import PropertyService from activegrid.server.toolsupport import GetTemplate import activegrid.util.xmlutils as xmlutils import activegrid.util.sysutils as sysutils DataServiceExistenceException = DeploymentGeneration.DataServiceExistenceException import WebBrowserServicefrom SVNService import SVN_INSTALLED_ = wx.GetTranslationif wx.Platform == '__WXMSW__': _WINDOWS = Trueelse: _WINDOWS = False #----------------------------------------------------------------------------# Constants#----------------------------------------------------------------------------SPACE = 10HALF_SPACE = 5PROJECT_EXTENSION = ".agp"if not ACTIVEGRID_BASE_IDE: PRE_17_TMP_DPL_NAME = "RunTime_tmp" + deploymentlib.DEPLOYMENT_EXTENSION _17_TMP_DPL_NAME = ".tmp" + deploymentlib.DEPLOYMENT_EXTENSION# wxBug: the wxTextCtrl and wxChoice controls on Mac do not correctly size# themselves with sizers, so we need to add a right border to the sizer to# get the control to shrink itself to fit in the sizer.MAC_RIGHT_BORDER = 0if wx.Platform == "__WXMAC__": MAC_RIGHT_BORDER = 5PROJECT_KEY = "/AG_Projects"PROJECT_DIRECTORY_KEY = "NewProjectDirectory"NEW_PROJECT_DIRECTORY_DEFAULT = appdirs.getSystemDir()#----------------------------------------------------------------------------# Methods#----------------------------------------------------------------------------def AddProjectMapping(doc, projectDoc=None, hint=None): projectService = wx.GetApp().GetService(ProjectService) if projectService: if not projectDoc: if not hint: hint = doc.GetFilename() projectDocs = projectService.FindProjectByFile(hint) if projectDocs: projectDoc = projectDocs[0] projectService.AddProjectMapping(doc, projectDoc) if hasattr(doc, "GetModel"): projectService.AddProjectMapping(doc.GetModel(), projectDoc)def getProjectKeyName(projectName, mode=None): if mode: return "%s/%s/%s" % (PROJECT_KEY, projectName.replace(os.sep, '|'), mode) else: return "%s/%s" % (PROJECT_KEY, projectName.replace(os.sep, '|'))def GetDocCallback(filepath): """ Get the Document used by the IDE and the in-memory document model used by runtime engine """ docMgr = wx.GetApp().GetDocumentManager() try: doc = docMgr.CreateDocument(filepath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW) if doc: AddProjectMapping(doc) else: # already open for d in docMgr.GetDocuments(): if os.path.normcase(d.GetFilename()) == os.path.normcase(filepath): doc = d break except Exception,e: doc = None aglogging.reportException(e, stacktrace=True) if doc and doc.GetDocumentTemplate().GetDocumentType() == WsdlAgEditor.WsdlAgDocument: # get referenced wsdl doc instead if doc.GetModel().filePath: if os.path.isabs(doc.GetModel().filePath): # if absolute path, leave it alone filepath = doc.GetModel().filePath else: filepath = doc.GetAppDocMgr().fullPath(doc.GetModel().filePath) # check relative to project homeDir if not os.path.isfile(filepath): filepath = os.path.normpath(os.path.join(os.path.dirname(doc.GetFilename()), doc.GetModel().filePath)) # check relative to wsdlag file if not os.path.isfile(filepath): filename = os.sep + os.path.basename(doc.GetModel().filePath) # check to see if in project file filePaths = findDocumentMgr(doc).filePaths for fp in filePaths: if fp.endswith(filename): filepath = fp break try: doc = docMgr.CreateDocument(filepath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW) except Exception,e: doc = None aglogging.reportException(e, stacktrace=True) if doc: AddProjectMapping(doc) else: # already open for d in docMgr.GetDocuments(): if os.path.normcase(d.GetFilename()) == os.path.normcase(filepath): doc = d break else: doc = None if doc: docModel = doc.GetModel() else: docModel = None return doc, docModeldef findDocumentMgr(root): projectService = wx.GetApp().GetService(ProjectService) if projectService: projectDoc = projectService.FindProjectFromMapping(root) if projectDoc: return projectDoc.GetModel() projectDoc = projectService.GetCurrentProject() if not projectDoc: return None if isinstance(root, wx.lib.docview.Document): filepath = root.GetFilename() elif hasattr(root, "fileName") and root.fileName: filepath = root.fileName else: filepath = None if filepath: if projectDoc.IsFileInProject(filepath): return projectDoc.GetModel() projects = [] openDocs = wx.GetApp().GetDocumentManager().GetDocuments() for openDoc in openDocs: if openDoc == projectDoc: continue if(isinstance(openDoc, ProjectDocument)): if openDoc.IsFileInProject(filepath): projects.append(openDoc) if projects: if len(projects) == 1: return projects[0].GetModel() else: choices = [os.path.basename(project.GetFilename()) for project in projects] dlg = wx.SingleChoiceDialog(wx.GetApp().GetTopWindow(), _("'%s' found in more than one project.\nWhich project should be used for this operation?") % os.path.basename(filepath), _("Select Project"), choices, wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER|wx.OK|wx.CENTRE) dlg.CenterOnParent() projectDoc = None if dlg.ShowModal() == wx.ID_OK: i = dlg.GetSelection() projectDoc = projects[i] dlg.Destroy() return projectDoc.GetModel() return projectDoc.GetModel() return None if not ACTIVEGRID_BASE_IDE: basemodel.findGlobalDocumentMgr = findDocumentMgr#----------------------------------------------------------------------------# Classes#----------------------------------------------------------------------------if not ACTIVEGRID_BASE_IDE: class IDEResourceFactory(DeploymentGeneration.DeploymentResourceFactory): def __init__(self, openDocs, dataSourceService, projectDir, preview=False, deployFilepath=None): self.openDocs = openDocs self.dataSourceService = dataSourceService self.projectDir = projectDir self.preview = preview self.deployFilepath = deployFilepath self.defaultFlagsNoView = ( wx.GetApp().GetDocumentManager().GetFlags()| wx.lib.docview.DOC_SILENT| wx.lib.docview.DOC_OPEN_ONCE| wx.lib.docview.DOC_NO_VIEW) def getModel(self, projectFile): doc = wx.GetApp().GetDocumentManager().CreateDocument( projectFile.filePath, flags=self.defaultFlagsNoView) if (doc == None): # already open doc = self._findOpenDoc(projectFile.filePath) else: AddProjectMapping(doc) if (doc != None): return doc.GetModel() def getDataSource(self, dataSourceName): # in preview mode, runtime needs the generated Deployment # to contain the requried data source. But runtime doesn't # actually need to communicate to db. So here is the logic to # make preview works if the required data soruce has not # yet been defined. dataSource = self.dataSourceService.getDataSource(dataSourceName) if (dataSource != None): return dataSource elif not self.preview: raise DataServiceExistenceException(dataSourceName) else: # first to see if an existing dpl file is there, if so, # use the data source in dpl file if (self.deployFilepath != None): tempDply = None try: tempDply = xmlutils.load(deployFilepath) except: pass if (tempDply != None): for tempDataSource in tempDply.dataSources: if (tempDataSource.name == dataSourceName): return tempDataSource # if unable to use dpl file, then create a dummy data source import activegrid.data.dataservice as dataservice return dataservice.DataSource( name=dataSourceName, dbtype=dataservice.DB_TYPE_SQLITE) def initDocumentRef(self, projectFile, documentRef, dpl): doc = self._findOpenDoc(projectFile.filePath) if (doc and hasattr(doc, 'GetModel')): documentRef.document = doc.GetModel() if isinstance(documentRef, deploymentlib.XFormRef): doc.GetModel().linkDeployment(dpl, dpl.loader) def _findOpenDoc(self, filePath): for openDoc in self.openDocs: if openDoc.GetFilename() == filePath: return openDoc return None def getProjectDir(self): return self.projectDirclass ProjectDocument(wx.lib.docview.Document): def __init__(self, model=None): wx.lib.docview.Document.__init__(self) if model: self.SetModel(model) else: self.SetModel(projectlib.Project()) # initial model used by "File | New... | Project" self.GetModel().SetDocCallback(GetDocCallback) self._stageProjectFile = False def __copy__(self): model = copy.copy(self.GetModel()) clone = ProjectDocument(model) clone.SetFilename(self.GetFilename()) return clone def GetFirstView(self): """ Bug: workaround. If user tries to open an already open project with main menu "File | Open...", docview.DocManager.OnFileOpen() silently returns None if project is already open. And to the user, it appears as if nothing has happened. The user expects to see the open project. This forces the project view to show the correct project. """ view = wx.lib.docview.Document.GetFirstView(self) view.SetProject(self.GetFilename()) # ensure project is displayed in view return view def GetModel(self): return self._projectModel
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -