1 #---------------------------------------------------------------------------- 
   3 # Purpose:      Shared UI stuff 
   5 # Author:       Matt Fryer, Morgan Hua 
   9 # Copyright:    (c) 2005 ActiveGrid, Inc. 
  10 # License:      wxWindows License 
  11 #---------------------------------------------------------------------------- 
  18 import activegrid
.util
.sysutils 
as sysutils
 
  19 import activegrid
.util
.strutils 
as strutils
 
  20 import activegrid
.util
.appdirs 
as appdirs
 
  23 def CreateDirectoryControl( parent
, fileLabel
=_("File Name:"), dirLabel
=_("Directory"), fileExtension
="*", startingName
="", startingDirectory
=None, choiceDirs
=None, appDirDefaultStartDir
=False, returnAll
=False): 
  29         if appDirDefaultStartDir
: 
  30             appDirectory 
= wx
.ConfigBase_Get().Read(ProjectEditor
.PROJECT_DIRECTORY_KEY
, ProjectEditor
.NEW_PROJECT_DIRECTORY_DEFAULT
) 
  32             appDirectory 
= wx
.ConfigBase_Get().Read(ProjectEditor
.PROJECT_DIRECTORY_KEY
) 
  34             choiceDirs
.append(appDirectory
) 
  35             if appDirDefaultStartDir 
and not startingDirectory
: 
  36                 startingDirectory 
= appDirectory
 
  38         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
  40             curProjectDoc 
= projectService
.GetCurrentProject() 
  42                 homeDir 
= curProjectDoc
.GetAppDocMgr().homeDir
 
  43                 if homeDir 
and (homeDir 
not in choiceDirs
): 
  44                     choiceDirs
.append(homeDir
) 
  45                 if not startingDirectory
: 
  46                     startingDirectory 
= homeDir
 
  48             for projectDoc 
in projectService
.GetOpenProjects(): 
  49                 if projectDoc 
== curProjectDoc
: 
  51                 homeDir 
= projectDoc
.GetAppDocMgr().homeDir
 
  52                 if homeDir 
and (homeDir 
not in projectDirs
): 
  53                     projectDirs
.append(homeDir
) 
  54                 projectDirs
.sort(CaseInsensitiveCompare
) 
  55             for projectDir 
in projectDirs
: 
  56                 if projectDir 
not in choiceDirs
: 
  57                     choiceDirs
.append(projectDir
) 
  59         if startingDirectory 
and (startingDirectory 
not in choiceDirs
): 
  60             choiceDirs
.insert(0, startingDirectory
) 
  62         if os
.getcwd() not in choiceDirs
: 
  63             choiceDirs
.append(os
.getcwd())                 
  64         if appdirs
.documents_folder 
not in choiceDirs
: 
  65             choiceDirs
.append(appdirs
.documents_folder
)  
  67     if not startingDirectory
: 
  68         startingDirectory 
= os
.getcwd() 
  70     nameControl 
= wx
.TextCtrl(parent
, -1, startingName
, size
=(-1,-1)) 
  71     nameLabelText 
= wx
.StaticText(parent
, -1, fileLabel
) 
  72     dirLabelText 
= wx
.StaticText(parent
, -1, dirLabel
) 
  73     dirControl 
= wx
.ComboBox(parent
, -1, startingDirectory
, size
=(-1,-1), choices
=choiceDirs
) 
  74     dirControl
.SetToolTipString(startingDirectory
) 
  75     button 
= wx
.Button(parent
, -1, _("Browse...")) 
  76     allControls 
= [nameControl
, nameLabelText
, dirLabelText
, dirControl
, button
] 
  78     def OnFindDirClick(event
):  
  80         nameCtrlValue 
= nameControl
.GetValue() 
  82             root
, ext 
= os
.path
.splitext( nameCtrlValue 
) 
  83             if ext 
== '.' + fileExtension
: 
  86                 name 
= _("%s.%s") % (nameCtrlValue
, fileExtension
) 
  88         dlg 
= wx
.FileDialog(parent
, _("Choose a filename and directory"), 
  89                        defaultDir 
= dirControl
.GetValue().strip(), 
  91                        wildcard
= "*.%s" % fileExtension
, 
  92                        style
=wx
.SAVE|wx
.CHANGE_DIR
) 
  94         if dlg
.ShowModal() != wx
.ID_OK
: 
 101             dir, filename 
= os
.path
.split(path
) 
 102             if dirControl
.FindString(dir) == wx
.NOT_FOUND
: 
 103                 dirControl
.Insert(dir, 0) 
 104             dirControl
.SetValue(dir) 
 105             dirControl
.SetToolTipString(dir) 
 106             nameControl
.SetValue(filename
) 
 108     parent
.Bind(wx
.EVT_BUTTON
, OnFindDirClick
, button
) 
 110     def Validate(allowOverwriteOnPrompt
=False, infoString
='', noFirstCharDigit
=False): 
 111         projName 
= nameControl
.GetValue().strip() 
 113             wx
.MessageBox(_("Please provide a %sfile name.") % infoString
, _("Provide a File Name"))             
 115         if noFirstCharDigit 
and projName
[0].isdigit(): 
 116             wx
.MessageBox(_("File name cannot start with a number.  Please enter a different name."), _("Invalid File Name"))             
 118         if projName
.find(' ') != -1: 
 119             wx
.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString
, _("Spaces in File Name"))             
 121         if not os
.path
.exists(dirControl
.GetValue()): 
 122             wx
.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString
, _("Provide a Valid Directory"))             
 125         filePath 
= os
.path
.join(dirControl
.GetValue(), MakeNameEndInExtension(projName
, "." + fileExtension
)) 
 126         if os
.path
.exists(filePath
): 
 127             if allowOverwriteOnPrompt
: 
 128                 res 
= wx
.MessageBox(_("That %sfile already exists. Would you like to overwrite it.") % infoString
, "File Exists", style
=wx
.YES_NO|wx
.NO_DEFAULT
) 
 129                 return (res 
== wx
.YES
)   
 131                 wx
.MessageBox(_("That %sfile already exists. Please choose a different name.") % infoString
, "File Exists") 
 135     flexGridSizer 
= wx
.FlexGridSizer(cols 
= 3, vgap 
= HALF_SPACE
, hgap 
= HALF_SPACE
) 
 136     flexGridSizer
.AddGrowableCol(1,1) 
 137     flexGridSizer
.Add(nameLabelText
, 0, wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
 138     flexGridSizer
.Add(nameControl
, 2, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.EXPAND
) 
 139     flexGridSizer
.Add(button
, flag
=wx
.ALIGN_RIGHT|wx
.LEFT
, border
=HALF_SPACE
) 
 141     flexGridSizer
.Add(dirLabelText
, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT
) 
 142     flexGridSizer
.Add(dirControl
, 2, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.EXPAND
) 
 143     flexGridSizer
.Add(wx
.StaticText(parent
, -1, ""), 0) 
 145         return nameControl
, dirControl
, flexGridSizer
, Validate
, allControls
 
 147         return nameControl
, dirControl
, flexGridSizer
, Validate
 
 150 def CreateDirectoryOnlyControl( parent
, dirLabel
=_("Location:"), startingDirectory
=None, choiceDirs
=None, appDirDefaultStartDir
=False): 
 156         if appDirDefaultStartDir
: 
 157             appDirectory 
= wx
.ConfigBase_Get().Read(ProjectEditor
.PROJECT_DIRECTORY_KEY
, ProjectEditor
.NEW_PROJECT_DIRECTORY_DEFAULT
) 
 159             appDirectory 
= wx
.ConfigBase_Get().Read(ProjectEditor
.PROJECT_DIRECTORY_KEY
) 
 161             choiceDirs
.append(appDirectory
) 
 162             if appDirDefaultStartDir 
and not startingDirectory
: 
 163                 startingDirectory 
= appDirectory
 
 165         projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 167             curProjectDoc 
= projectService
.GetCurrentProject() 
 169                 homeDir 
= curProjectDoc
.GetAppDocMgr().homeDir
 
 170                 if homeDir 
and (homeDir 
not in choiceDirs
): 
 171                     choiceDirs
.append(homeDir
) 
 172                 if not startingDirectory
: 
 173                     startingDirectory 
= homeDir
 
 175             for projectDoc 
in projectService
.GetOpenProjects(): 
 176                 if projectDoc 
== curProjectDoc
: 
 178                 homeDir 
= projectDoc
.GetAppDocMgr().homeDir
 
 179                 if homeDir 
and (homeDir 
not in projectDirs
): 
 180                     projectDirs
.append(homeDir
) 
 181                 projectDirs
.sort(CaseInsensitiveCompare
) 
 182             for projectDir 
in projectDirs
: 
 183                 if projectDir 
not in choiceDirs
: 
 184                     choiceDirs
.append(projectDir
) 
 186         if startingDirectory 
and (startingDirectory 
not in choiceDirs
): 
 187             choiceDirs
.insert(0, startingDirectory
) 
 189         if os
.getcwd() not in choiceDirs
: 
 190             choiceDirs
.append(os
.getcwd())                 
 191         if appdirs
.documents_folder 
not in choiceDirs
: 
 192             choiceDirs
.append(appdirs
.documents_folder
)                 
 195     if not startingDirectory
: 
 196         startingDirectory 
= os
.getcwd() 
 198     dirLabelText 
= wx
.StaticText(parent
, -1, dirLabel
) 
 199     dirControl 
= wx
.ComboBox(parent
, -1, startingDirectory
, size
=(-1,-1), choices
=choiceDirs
) 
 200     dirControl
.SetToolTipString(startingDirectory
) 
 201     button 
= wx
.Button(parent
, -1, _("Browse...")) 
 203     def OnFindDirClick(event
):  
 204             dlg 
= wx
.DirDialog(wx
.GetApp().GetTopWindow(), 
 205                                 _("Choose a directory:"), 
 206                                 defaultPath
=dirControl
.GetValue().strip(), 
 207                                 style
=wx
.DD_DEFAULT_STYLE|wx
.DD_NEW_DIR_BUTTON
) 
 209             if dlg
.ShowModal() == wx
.ID_OK
: 
 211                 if dirControl
.FindString(dir) == wx
.NOT_FOUND
: 
 212                     dirControl
.Insert(dir, 0) 
 213                 dirControl
.SetValue(dir) 
 214                 dirControl
.SetToolTipString(dir) 
 217     parent
.Bind(wx
.EVT_BUTTON
, OnFindDirClick
, button
) 
 219     def Validate(allowOverwriteOnPrompt
=False): 
 220         dirName 
= dirControl
.GetValue().strip() 
 222             wx
.MessageBox(_("Please provide a directory."), _("Provide a Directory"))             
 224         if not os
.path
.exists(dirName
): 
 225             wx
.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory"))             
 230     flexGridSizer 
= wx
.FlexGridSizer(cols 
= 3, vgap 
= HALF_SPACE
, hgap 
= HALF_SPACE
) 
 231     flexGridSizer
.AddGrowableCol(1,1) 
 232     flexGridSizer
.Add(dirLabelText
, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.RIGHT
, border
=HALF_SPACE
) 
 233     flexGridSizer
.Add(dirControl
, 2, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.EXPAND
, border
=HALF_SPACE
) 
 234     flexGridSizer
.Add(button
, flag
=wx
.ALIGN_RIGHT|wx
.LEFT
, border
=HALF_SPACE
) 
 236     return dirControl
, flexGridSizer
, Validate
 
 239 def CreateNameOnlyControl( parent
, fileLabel
, startingName
="", startingDirectoryControl
=None): 
 241     fileLabelText 
= wx
.StaticText(parent
, -1, fileLabel
) 
 242     nameControl 
= wx
.TextCtrl(parent
, -1, startingName
, size
=(-1,-1)) 
 244     def Validate(allowOverwriteOnPrompt
=False, noFirstCharDigit
=False): 
 245         projName 
= nameControl
.GetValue().strip() 
 247             wx
.MessageBox(_("Blank name.  Please enter a valid name."), _("Project Name"))             
 249         if noFirstCharDigit 
and projName
[0].isdigit(): 
 250             wx
.MessageBox(_("Name cannot start with a number.  Please enter a valid name."), _("Project Name"))             
 252         if projName
.find(' ') != -1: 
 253             wx
.MessageBox(_("Spaces in name.  Name cannot have spaces.") % infoString
, _("Project Name"))             
 255         path 
= os
.path
.join(startingDirectoryControl
.GetValue().strip(), projName
) 
 256         if os
.path
.exists(path
): 
 257             if os
.path
.isdir(path
): 
 258                 message 
= _("Project '%s' already exists.  Would you like to overwrite the contents of the project?") % projName
 
 259             else: # os.path.isfile(path): 
 260                 message 
= _("'%s' already exists as a file.  Would you like to replace it with the project?") % nameControl
.GetValue().strip() 
 262             yesNoMsg 
= wx
.MessageDialog(wx
.GetApp().GetTopWindow(), 
 264                           _("Project Directory Exists"), 
 265                           wx
.YES_NO|wx
.ICON_QUESTION
 
 267             yesNoMsg
.CenterOnParent() 
 268             status 
= yesNoMsg
.ShowModal() 
 270             if status 
== wx
.ID_NO
: 
 275     flexGridSizer 
= wx
.FlexGridSizer(cols 
= 2, vgap 
= HALF_SPACE
, hgap 
= HALF_SPACE
) 
 276     flexGridSizer
.AddGrowableCol(1,1) 
 277     flexGridSizer
.Add(fileLabelText
, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.ALIGN_LEFT|wx
.TOP|wx
.RIGHT
, border
=HALF_SPACE
) 
 278     flexGridSizer
.Add(nameControl
, 2, flag
=wx
.ALIGN_CENTER_VERTICAL|wx
.EXPAND
, border
=HALF_SPACE
) 
 280     return nameControl
, flexGridSizer
, Validate
 
 283 def GetCurrentProject(): 
 284     projectDocument 
= None 
 285     projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 287         projectDocument 
= projectService
.GetCurrentProject() 
 288     return projectDocument
 
 290 def AddFilesToCurrentProject(paths
, folderPath
=None, types
=None, names
=None, save
=False): 
 291     projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 293         projectDocument 
= projectService
.GetCurrentProject() 
 295             files 
= projectDocument
.GetFiles() 
 300                 projectDocument
.GetCommandProcessor().Submit(ProjectEditor
.ProjectAddFilesCommand(projectDocument
, paths
, folderPath
=folderPath
, types
=types
, names
=names
)) 
 302                     projectDocument
.OnSaveDocument(projectDocument
.GetFilename()) 
 304 def AddFilesToProject(projectDocument
, paths
, types
=None, names
=None, save
=False): 
 306         files 
= projectDocument
.GetFiles() 
 311             projectDocument
.GetCommandProcessor().Submit(ProjectEditor
.ProjectAddFilesCommand(projectDocument
, paths
, types
=types
, names
=names
)) 
 313                 projectDocument
.OnSaveDocument(projectDocument
.GetFilename()) 
 316 def MakeNameEndInExtension(name
, extension
): 
 319     root
, ext 
= os
.path
.splitext(name
) 
 323         return name 
+ extension
 
 326 def GetPythonExecPath(): 
 327     pythonExecPath 
= wx
.ConfigBase_Get().Read("ActiveGridPythonLocation") 
 328     if not pythonExecPath
: 
 329         pythonExecPath 
= sysutils
.pythonExecPath
 
 330     return pythonExecPath
 
 333 def _DoRemoveRecursive(path
, skipFile
=None, skipped
=False): 
 336     elif os
.path
.isdir(path
): 
 337         for file in os
.listdir(path
): 
 338             file_or_dir 
= os
.path
.join(path
,file) 
 339             if skipFile 
== file_or_dir
: 
 341             elif os
.path
.isdir(file_or_dir
) and not os
.path
.islink(file_or_dir
): 
 342                 if _DoRemoveRecursive(file_or_dir
, skipFile
): # it's a directory recursive call to function again 
 345                 os
.remove(file_or_dir
) # it's a file, delete it 
 347             os
.rmdir(path
) # delete the directory here 
 354 def RemoveRecursive(path
, skipFile
=None): 
 355     _DoRemoveRecursive(path
, skipFile
)     
 358 def CaseInsensitiveCompare(s1
, s2
): 
 359     """ Method used by sort() to sort values in case insensitive order """ 
 360     return strutils
.caseInsensitiveCompare(s1
, s2
) 
 363 def GetAnnotation(model
, elementName
): 
 364     """ Get an object's annotation used for tooltips """ 
 365     if hasattr(model
, "__xsdcomplextype__"): 
 366         ct 
= model
.__xsdcomplextype
__ 
 368             el 
= ct
.findElement(elementName
) 
 369             if el 
and el
.annotation
: 
 375 #---------------------------------------------------------------------------- 
 376 # Methods for finding application level info 
 377 #---------------------------------------------------------------------------- 
 379 def GetProjectForDoc(doc
): 
 380     """ Given a document find which project it belongs to. 
 381         Tries to intelligently resolve conflicts if it is in more than one open project. 
 383     projectService 
= wx
.GetApp().GetService(ProjectEditor
.ProjectService
) 
 385     projectDoc 
= projectService
.FindProjectFromMapping(doc
) 
 389     projectDoc 
= projectService
.GetCurrentProject() 
 392     if projectDoc
.IsFileInProject(doc
.GetFilename()): 
 396     openDocs 
= wx
.GetApp().GetDocumentManager().GetDocuments() 
 397     for openDoc 
in openDocs
: 
 398         if openDoc 
== projectDoc
: 
 400         if(isinstance(openDoc
, ProjectEditor
.ProjectDocument
)): 
 401             if openDoc
.IsFileInProject(doc
.GetFilename()): 
 402                 projects
.append(openDoc
) 
 405         if len(projects
) == 1: 
 408             choices 
= [os
.path
.basename(project
.GetFilename()) for project 
in projects
] 
 409             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
) 
 412             if dlg
.ShowModal() == wx
.ID_OK
: 
 413                 i 
= dlg
.GetSelection() 
 414                 projectDoc 
= projects
[i
] 
 421 def GetAppInfoForDoc(doc
): 
 422     """ Get the AppInfo for a given document """ 
 423     projectDoc 
= GetProjectForDoc(doc
) 
 425         return projectDoc
.GetAppInfo() 
 429 def GetAppDocMgrForDoc(doc
): 
 430     """ Get the AppDocMgr for a given document """ 
 431     projectDoc 
= GetProjectForDoc(doc
) 
 433         return projectDoc
.GetModel() 
 437 def GetAppInfoLanguage(doc
=None): 
 438     from activegrid
.server
.deployment 
import LANGUAGE_DEFAULT
 
 440         language 
= doc
.GetAppInfo().language
 
 445         config 
= wx
.ConfigBase_Get() 
 446         language 
= config
.Read(ProjectEditor
.APP_LAST_LANGUAGE
, LANGUAGE_DEFAULT
) 
 449             doc
.GetAppInfo().language 
= language  
# once it is selected, it must be set.