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.