# Name: UICommon.py
# Purpose: Shared UI stuff
#
-# Author: Matt Fryer
+# Author: Matt Fryer, Morgan Hua
#
# Created: 3/10/05
# CVS-ID: $Id$
import os
import os.path
import wx
+import string
import ProjectEditor
-import activegrid.util as utillib
+import activegrid.util.sysutils as sysutils
+import activegrid.util.strutils as strutils
+import activegrid.util.appdirs as appdirs
_ = wx.GetTranslation
-def CreateDirectoryControl( parent, fileLabel, dirLabel, fileExtension, startingName="", startingDirectory=""):
+def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False):
+ if not choiceDirs:
+ choiceDirs = []
+ projectDirs = []
+
+ if appDirDefaultStartDir:
+ appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT)
+ else:
+ appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY)
+ if appDirectory:
+ choiceDirs.append(appDirectory)
+ if appDirDefaultStartDir and not startingDirectory:
+ startingDirectory = appDirectory
+
+ projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
+ if projectService:
+ curProjectDoc = projectService.GetCurrentProject()
+ if curProjectDoc:
+ homeDir = curProjectDoc.GetAppDocMgr().homeDir
+ if homeDir and (homeDir not in choiceDirs):
+ choiceDirs.append(homeDir)
+ if not startingDirectory:
+ startingDirectory = homeDir
+
+ for projectDoc in projectService.GetOpenProjects():
+ if projectDoc == curProjectDoc:
+ continue
+ homeDir = projectDoc.GetAppDocMgr().homeDir
+ if homeDir and (homeDir not in projectDirs):
+ projectDirs.append(homeDir)
+ projectDirs.sort(CaseInsensitiveCompare)
+ for projectDir in projectDirs:
+ if projectDir not in choiceDirs:
+ choiceDirs.append(projectDir)
+
+ if startingDirectory and (startingDirectory not in choiceDirs):
+ choiceDirs.insert(0, startingDirectory)
+
+ if os.getcwd() not in choiceDirs:
+ choiceDirs.append(os.getcwd())
+ if appdirs.documents_folder not in choiceDirs:
+ choiceDirs.append(appdirs.documents_folder)
+
+ if not startingDirectory:
+ startingDirectory = os.getcwd()
+
nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
nameLabelText = wx.StaticText(parent, -1, fileLabel)
dirLabelText = wx.StaticText(parent, -1, dirLabel)
- dirControl = wx.TextCtrl(parent, -1, startingDirectory, size=(-1,-1))
+ dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs)
dirControl.SetToolTipString(startingDirectory)
- button = wx.Button(parent, -1, _("Browse..."), size=(60,-1))
+ button = wx.Button(parent, -1, _("Browse..."))
+ allControls = [nameControl, nameLabelText, dirLabelText, dirControl, button]
def OnFindDirClick(event):
name = ""
name = nameCtrlValue
else:
name = _("%s.%s") % (nameCtrlValue, fileExtension)
- path = wx.FileSelector(_("Choose a filename and directory"),
- "",
- "%s" % name,
- wildcard=_("*.%s") % fileExtension ,
- flags=wx.SAVE,
- parent=parent)
+
+ dlg = wx.FileDialog(parent, _("Choose a filename and directory"),
+ defaultDir = dirControl.GetValue().strip(),
+ defaultFile = name,
+ wildcard= "*.%s" % fileExtension,
+ style=wx.SAVE|wx.CHANGE_DIR)
+ if dlg.ShowModal() != wx.ID_OK:
+ dlg.Destroy()
+ return
+ path = dlg.GetPath()
+ dlg.Destroy()
+
if path:
dir, filename = os.path.split(path)
+ if dirControl.FindString(dir) == wx.NOT_FOUND:
+ dirControl.Insert(dir, 0)
dirControl.SetValue(dir)
dirControl.SetToolTipString(dir)
nameControl.SetValue(filename)
parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
- def Validate(allowOverwriteOnPrompt=False):
- if nameControl.GetValue() == "":
- wx.MessageBox(_("Please provide a filename."), _("Provide a Filename"))
+ def Validate(allowOverwriteOnPrompt=False, infoString='', noFirstCharDigit=False):
+ projName = nameControl.GetValue().strip()
+ if projName == "":
+ wx.MessageBox(_("Please provide a %sfile name.") % infoString, _("Provide a File Name"))
+ return False
+ if noFirstCharDigit and projName[0].isdigit():
+ wx.MessageBox(_("File name cannot start with a number. Please enter a different name."), _("Invalid File Name"))
return False
- if nameControl.GetValue().find(' ') != -1:
- wx.MessageBox(_("Please provide a filename that does not contains spaces."), _("Spaces in Filename"))
+ if projName.find(' ') != -1:
+ wx.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString, _("Spaces in File Name"))
return False
if not os.path.exists(dirControl.GetValue()):
- wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
+ wx.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString, _("Provide a Valid Directory"))
return False
- filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(nameControl.GetValue(), "." + fileExtension))
+ filePath = os.path.join(dirControl.GetValue(), MakeNameEndInExtension(projName, "." + fileExtension))
if os.path.exists(filePath):
if allowOverwriteOnPrompt:
- res = wx.MessageBox(_("That file already exists. Would you like to overwrite it."), "File Exists", style=wx.YES_NO|wx.NO_DEFAULT)
+ res = wx.MessageBox(_("That %sfile already exists. Would you like to overwrite it.") % infoString, "File Exists", style=wx.YES_NO|wx.NO_DEFAULT)
return (res == wx.YES)
else:
- wx.MessageBox(_("That file already exists. Please choose a different name."), "File Exists")
+ wx.MessageBox(_("That %sfile already exists. Please choose a different name.") % infoString, "File Exists")
return False
return True
HALF_SPACE = 5
flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
flexGridSizer.AddGrowableCol(1,1)
- flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, HALF_SPACE)
+ flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
- flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, border=HALF_SPACE)
- flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
+ flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT)
+ flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND)
flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0)
- return nameControl, dirControl, flexGridSizer, Validate
+ if returnAll:
+ return nameControl, dirControl, flexGridSizer, Validate, allControls
+ else:
+ return nameControl, dirControl, flexGridSizer, Validate
+
+
+def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False):
+
+ if not choiceDirs:
+ choiceDirs = []
+ projectDirs = []
+
+ if appDirDefaultStartDir:
+ appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT)
+ else:
+ appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY)
+ if appDirectory:
+ choiceDirs.append(appDirectory)
+ if appDirDefaultStartDir and not startingDirectory:
+ startingDirectory = appDirectory
+
+ projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
+ if projectService:
+ curProjectDoc = projectService.GetCurrentProject()
+ if curProjectDoc:
+ homeDir = curProjectDoc.GetAppDocMgr().homeDir
+ if homeDir and (homeDir not in choiceDirs):
+ choiceDirs.append(homeDir)
+ if not startingDirectory:
+ startingDirectory = homeDir
+
+ for projectDoc in projectService.GetOpenProjects():
+ if projectDoc == curProjectDoc:
+ continue
+ homeDir = projectDoc.GetAppDocMgr().homeDir
+ if homeDir and (homeDir not in projectDirs):
+ projectDirs.append(homeDir)
+ projectDirs.sort(CaseInsensitiveCompare)
+ for projectDir in projectDirs:
+ if projectDir not in choiceDirs:
+ choiceDirs.append(projectDir)
+
+ if startingDirectory and (startingDirectory not in choiceDirs):
+ choiceDirs.insert(0, startingDirectory)
+
+ if os.getcwd() not in choiceDirs:
+ choiceDirs.append(os.getcwd())
+ if appdirs.documents_folder not in choiceDirs:
+ choiceDirs.append(appdirs.documents_folder)
+
+
+ if not startingDirectory:
+ startingDirectory = os.getcwd()
+
+ dirLabelText = wx.StaticText(parent, -1, dirLabel)
+ dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs)
+ dirControl.SetToolTipString(startingDirectory)
+ button = wx.Button(parent, -1, _("Browse..."))
+
+ def OnFindDirClick(event):
+ dlg = wx.DirDialog(wx.GetApp().GetTopWindow(),
+ _("Choose a directory:"),
+ defaultPath=dirControl.GetValue().strip(),
+ style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON)
+ dlg.CenterOnParent()
+ if dlg.ShowModal() == wx.ID_OK:
+ dir = dlg.GetPath()
+ if dirControl.FindString(dir) == wx.NOT_FOUND:
+ dirControl.Insert(dir, 0)
+ dirControl.SetValue(dir)
+ dirControl.SetToolTipString(dir)
+ dlg.Destroy()
+
+ parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button)
+
+ def Validate(allowOverwriteOnPrompt=False):
+ dirName = dirControl.GetValue().strip()
+ if dirName == "":
+ wx.MessageBox(_("Please provide a directory."), _("Provide a Directory"))
+ return False
+ if not os.path.exists(dirName):
+ wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))
+ return False
+ return True
+
+ HALF_SPACE = 5
+ flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE)
+ flexGridSizer.AddGrowableCol(1,1)
+ flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.RIGHT, border=HALF_SPACE)
+ flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
+ flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE)
+
+ return dirControl, flexGridSizer, Validate
+
+
+def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectoryControl=None):
+
+ fileLabelText = wx.StaticText(parent, -1, fileLabel)
+ nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1))
+
+ def Validate(allowOverwriteOnPrompt=False, noFirstCharDigit=False):
+ projName = nameControl.GetValue().strip()
+ if projName == "":
+ wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name"))
+ return False
+ if noFirstCharDigit and projName[0].isdigit():
+ wx.MessageBox(_("Name cannot start with a number. Please enter a valid name."), _("Project Name"))
+ return False
+ if projName.find(' ') != -1:
+ wx.MessageBox(_("Spaces in name. Name cannot have spaces.") % infoString, _("Project Name"))
+ return False
+ path = os.path.join(startingDirectoryControl.GetValue().strip(), projName)
+ if os.path.exists(path):
+ if os.path.isdir(path):
+ message = _("Project '%s' already exists. Would you like to overwrite the contents of the project?") % projName
+ else: # os.path.isfile(path):
+ message = _("'%s' already exists as a file. Would you like to replace it with the project?") % nameControl.GetValue().strip()
+
+ yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(),
+ message,
+ _("Project Directory Exists"),
+ wx.YES_NO|wx.ICON_QUESTION
+ )
+ yesNoMsg.CenterOnParent()
+ status = yesNoMsg.ShowModal()
+ yesNoMsg.Destroy()
+ if status == wx.ID_NO:
+ return False
+ return True
+
+ HALF_SPACE = 5
+ flexGridSizer = wx.FlexGridSizer(cols = 2, vgap = HALF_SPACE, hgap = HALF_SPACE)
+ flexGridSizer.AddGrowableCol(1,1)
+ flexGridSizer.Add(fileLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, border=HALF_SPACE)
+ flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE)
+
+ return nameControl, flexGridSizer, Validate
+
-def AddFilesToCurrentProject(paths, save=False):
+def GetCurrentProject():
+ projectDocument = None
+ projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
+ if projectService:
+ projectDocument = projectService.GetCurrentProject()
+ return projectDocument
+
+def AddFilesToCurrentProject(paths, folderPath=None, types=None, names=None, save=False):
projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
if projectService:
projectDocument = projectService.GetCurrentProject()
if path in files:
paths.remove(path)
if paths:
- projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths))
- projectDocument.GetFirstView().DoSelectFiles([paths[0]])
+ projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, folderPath=folderPath, types=types, names=names))
if save:
projectDocument.OnSaveDocument(projectDocument.GetFilename())
+def AddFilesToProject(projectDocument, paths, types=None, names=None, save=False):
+ if projectDocument:
+ files = projectDocument.GetFiles()
+ for path in paths:
+ if path in files:
+ paths.remove(path)
+ if paths:
+ projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, types=types, names=names))
+ if save:
+ projectDocument.OnSaveDocument(projectDocument.GetFilename())
+
+
def MakeNameEndInExtension(name, extension):
if not name:
return name
else:
return name + extension
-# Lame
-def PluralName(name):
- if not name:
- return name
- if name.endswith('us'):
- return name[0:-2] + 'ii'
- elif name.endswith('s'):
- return name
- elif name.endswith('y'):
- return name[0:-1] + 'ies'
- else:
- return name + 's'
-
+
def GetPythonExecPath():
pythonExecPath = wx.ConfigBase_Get().Read("ActiveGridPythonLocation")
if not pythonExecPath:
- pythonExecPath = utillib.pythonExecPath
+ pythonExecPath = sysutils.pythonExecPath
return pythonExecPath
+def _DoRemoveRecursive(path, skipFile=None, skipped=False):
+ if path == skipFile:
+ skipped = True
+ elif os.path.isdir(path):
+ for file in os.listdir(path):
+ file_or_dir = os.path.join(path,file)
+ if skipFile == file_or_dir:
+ skipped = True
+ elif os.path.isdir(file_or_dir) and not os.path.islink(file_or_dir):
+ if _DoRemoveRecursive(file_or_dir, skipFile): # it's a directory recursive call to function again
+ skipped = True
+ else:
+ os.remove(file_or_dir) # it's a file, delete it
+ if not skipped:
+ os.rmdir(path) # delete the directory here
+ else:
+ os.remove(path)
+
+ return skipped
+
+
+def RemoveRecursive(path, skipFile=None):
+ _DoRemoveRecursive(path, skipFile)
+
+
+def CaseInsensitiveCompare(s1, s2):
+ """ Method used by sort() to sort values in case insensitive order """
+ return strutils.caseInsensitiveCompare(s1, s2)
+
+
+def GetAnnotation(model, elementName):
+ """ Get an object's annotation used for tooltips """
+ if hasattr(model, "__xsdcomplextype__"):
+ ct = model.__xsdcomplextype__
+ if ct:
+ el = ct.findElement(elementName)
+ if el and el.annotation:
+ return el.annotation
+
+ return ""
+
+
+#----------------------------------------------------------------------------
+# Methods for finding application level info
+#----------------------------------------------------------------------------
+
+def GetProjectForDoc(doc):
+ """ Given a document find which project it belongs to.
+ Tries to intelligently resolve conflicts if it is in more than one open project.
+ """
+ projectService = wx.GetApp().GetService(ProjectEditor.ProjectService)
+
+ projectDoc = projectService.FindProjectFromMapping(doc)
+ if projectDoc:
+ return projectDoc
+
+ projectDoc = projectService.GetCurrentProject()
+ if not projectDoc:
+ return None
+ if projectDoc.IsFileInProject(doc.GetFilename()):
+ return projectDoc
+
+ projects = []
+ openDocs = wx.GetApp().GetDocumentManager().GetDocuments()
+ for openDoc in openDocs:
+ if openDoc == projectDoc:
+ continue
+ if(isinstance(openDoc, ProjectEditor.ProjectDocument)):
+ if openDoc.IsFileInProject(doc.GetFilename()):
+ projects.append(openDoc)
+
+ if projects:
+ if len(projects) == 1:
+ return projects[0]
+ 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(doc.GetFilename()), _("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
+
+ return None
+
+
+def GetAppInfoForDoc(doc):
+ """ Get the AppInfo for a given document """
+ projectDoc = GetProjectForDoc(doc)
+ if projectDoc:
+ return projectDoc.GetAppInfo()
+ return None
+
+
+def GetAppDocMgrForDoc(doc):
+ """ Get the AppDocMgr for a given document """
+ projectDoc = GetProjectForDoc(doc)
+ if projectDoc:
+ return projectDoc.GetModel()
+ return None
+
+
+def GetAppInfoLanguage(doc=None):
+ from activegrid.server.deployment import LANGUAGE_DEFAULT
+ if doc:
+ language = doc.GetAppInfo().language
+ else:
+ language = None
+
+ if not language:
+ config = wx.ConfigBase_Get()
+ language = config.Read(ProjectEditor.APP_LAST_LANGUAGE, LANGUAGE_DEFAULT)
+
+ if doc:
+ doc.GetAppInfo().language = language # once it is selected, it must be set.
+
+ return language