📄 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.9 2006/04/20 06:25:58 RD Exp $
# Copyright: (c) 2003-2006 ActiveGrid, Inc.
# License: wxWindows License
#----------------------------------------------------------------------------
import wx
import wx.lib.docview
import wx.lib.pydocview
import wx.lib.buttons
from wxPython.lib.rcsizer import RowColSizer
import Service
import copy
import os
import os.path
import sets
import sys
import time
import types
import activegrid.util.appdirs as appdirs
import activegrid.util.fileutils as fileutils
import activegrid.util.aglogging as aglogging
import UICommon
import Wizard
import SVNService
import project as projectlib
import ExtensionService
from IDE import ACTIVEGRID_BASE_IDE
if 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 WebBrowserService
from SVNService import SVN_INSTALLED
_ = wx.GetTranslation
if wx.Platform == '__WXMSW__':
_WINDOWS = True
else:
_WINDOWS = False
#----------------------------------------------------------------------------
# Constants
#----------------------------------------------------------------------------
SPACE = 10
HALF_SPACE = 5
PROJECT_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 = 0
if wx.Platform == "__WXMAC__":
MAC_RIGHT_BORDER = 5
PROJECT_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, docModel
def 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.projectDir
class 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.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -