]>
Commit | Line | Data |
---|---|---|
1f780e48 RD |
1 | #---------------------------------------------------------------------------- |
2 | # Name: UICommon.py | |
3 | # Purpose: Shared UI stuff | |
4 | # | |
02b800ce | 5 | # Author: Matt Fryer, Morgan Hua |
1f780e48 RD |
6 | # |
7 | # Created: 3/10/05 | |
8 | # CVS-ID: $Id$ | |
aca310e5 | 9 | # Copyright: (c) 2005-2006 ActiveGrid, Inc. |
1f780e48 RD |
10 | # License: wxWindows License |
11 | #---------------------------------------------------------------------------- | |
12 | ||
13 | import os | |
14 | import os.path | |
15 | import wx | |
02b800ce | 16 | import string |
1f780e48 | 17 | import ProjectEditor |
02b800ce | 18 | import activegrid.util.appdirs as appdirs |
aca310e5 RD |
19 | import activegrid.util.fileutils as fileutils |
20 | import activegrid.util.strutils as strutils | |
21 | import activegrid.util.sysutils as sysutils | |
22 | import activegrid.util.xmlutils as xmlutils | |
1f780e48 RD |
23 | _ = wx.GetTranslation |
24 | ||
aca310e5 | 25 | def CreateDirectoryControl( parent, fileLabel=_("File Name:"), dirLabel=_("Directory:"), fileExtension="*", startingName="", startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False, returnAll=False, useDirDialog=False): |
1f780e48 | 26 | |
02b800ce RD |
27 | if not choiceDirs: |
28 | choiceDirs = [] | |
29 | projectDirs = [] | |
30 | ||
31 | if appDirDefaultStartDir: | |
32 | appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT) | |
33 | else: | |
34 | appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY) | |
35 | if appDirectory: | |
36 | choiceDirs.append(appDirectory) | |
37 | if appDirDefaultStartDir and not startingDirectory: | |
38 | startingDirectory = appDirectory | |
39 | ||
40 | projectService = wx.GetApp().GetService(ProjectEditor.ProjectService) | |
41 | if projectService: | |
42 | curProjectDoc = projectService.GetCurrentProject() | |
43 | if curProjectDoc: | |
44 | homeDir = curProjectDoc.GetAppDocMgr().homeDir | |
45 | if homeDir and (homeDir not in choiceDirs): | |
46 | choiceDirs.append(homeDir) | |
47 | if not startingDirectory: | |
48 | startingDirectory = homeDir | |
49 | ||
50 | for projectDoc in projectService.GetOpenProjects(): | |
51 | if projectDoc == curProjectDoc: | |
52 | continue | |
53 | homeDir = projectDoc.GetAppDocMgr().homeDir | |
54 | if homeDir and (homeDir not in projectDirs): | |
55 | projectDirs.append(homeDir) | |
56 | projectDirs.sort(CaseInsensitiveCompare) | |
57 | for projectDir in projectDirs: | |
58 | if projectDir not in choiceDirs: | |
59 | choiceDirs.append(projectDir) | |
60 | ||
61 | if startingDirectory and (startingDirectory not in choiceDirs): | |
62 | choiceDirs.insert(0, startingDirectory) | |
63 | ||
64 | if os.getcwd() not in choiceDirs: | |
65 | choiceDirs.append(os.getcwd()) | |
aca310e5 RD |
66 | if appdirs.getSystemDir() not in choiceDirs: |
67 | choiceDirs.append(appdirs.getSystemDir()) | |
02b800ce RD |
68 | |
69 | if not startingDirectory: | |
70 | startingDirectory = os.getcwd() | |
71 | ||
1f780e48 RD |
72 | nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1)) |
73 | nameLabelText = wx.StaticText(parent, -1, fileLabel) | |
74 | dirLabelText = wx.StaticText(parent, -1, dirLabel) | |
02b800ce | 75 | dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs) |
1f780e48 | 76 | dirControl.SetToolTipString(startingDirectory) |
02b800ce RD |
77 | button = wx.Button(parent, -1, _("Browse...")) |
78 | allControls = [nameControl, nameLabelText, dirLabelText, dirControl, button] | |
1f780e48 RD |
79 | |
80 | def OnFindDirClick(event): | |
81 | name = "" | |
82 | nameCtrlValue = nameControl.GetValue() | |
83 | if nameCtrlValue: | |
84 | root, ext = os.path.splitext( nameCtrlValue ) | |
85 | if ext == '.' + fileExtension: | |
86 | name = nameCtrlValue | |
87 | else: | |
88 | name = _("%s.%s") % (nameCtrlValue, fileExtension) | |
02b800ce | 89 | |
aca310e5 RD |
90 | if not useDirDialog: |
91 | dlg = wx.FileDialog(parent, _("Choose a filename and directory"), | |
02b800ce RD |
92 | defaultDir = dirControl.GetValue().strip(), |
93 | defaultFile = name, | |
94 | wildcard= "*.%s" % fileExtension, | |
95 | style=wx.SAVE|wx.CHANGE_DIR) | |
aca310e5 RD |
96 | else: |
97 | dlg = wx.DirDialog(wx.GetApp().GetTopWindow(), | |
98 | _("Choose a directory:"), | |
99 | defaultPath=dirControl.GetValue().strip(), | |
100 | style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON) | |
101 | ||
02b800ce RD |
102 | if dlg.ShowModal() != wx.ID_OK: |
103 | dlg.Destroy() | |
104 | return | |
105 | path = dlg.GetPath() | |
106 | dlg.Destroy() | |
107 | ||
1f780e48 | 108 | if path: |
aca310e5 RD |
109 | if not useDirDialog: |
110 | dir, filename = os.path.split(path) | |
111 | if dirControl.FindString(dir) == wx.NOT_FOUND: | |
112 | dirControl.Insert(dir, 0) | |
113 | dirControl.SetValue(dir) | |
114 | dirControl.SetToolTipString(dir) | |
115 | nameControl.SetValue(filename) | |
116 | else: | |
117 | dirControl.SetValue(path) | |
118 | dirControl.SetToolTipString(path) | |
1f780e48 RD |
119 | |
120 | parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button) | |
121 | ||
aca310e5 | 122 | def Validate(allowOverwriteOnPrompt=False, infoString='', validClassName=False, ignoreFileConflicts=False): |
02b800ce RD |
123 | projName = nameControl.GetValue().strip() |
124 | if projName == "": | |
125 | wx.MessageBox(_("Please provide a %sfile name.") % infoString, _("Provide a File Name")) | |
126 | return False | |
02b800ce RD |
127 | if projName.find(' ') != -1: |
128 | wx.MessageBox(_("Please provide a %sfile name that does not contains spaces.") % infoString, _("Spaces in File Name")) | |
1f780e48 | 129 | return False |
aca310e5 RD |
130 | if validClassName: |
131 | if projName[0].isdigit(): | |
132 | wx.MessageBox(_("File name cannot start with a number. Please enter a different name."), _("Invalid File Name")) | |
133 | return False | |
134 | if projName.endswith(".agp"): | |
135 | projName2 = projName[:-4] | |
136 | else: | |
137 | projName2 = projName | |
138 | if not projName2.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ending '.agp'. | |
139 | wx.MessageBox(_("Name must be alphanumeric ('_' allowed). Please enter a valid name."), _("Project Name")) | |
140 | return False | |
141 | ||
142 | dirName = dirControl.GetValue().strip() | |
143 | if dirName == "": | |
144 | wx.MessageBox(_("No directory. Please provide a directory."), _("Provide a Directory")) | |
26ee3a06 | 145 | return False |
aca310e5 RD |
146 | if os.sep == "\\" and dirName.find("/") != -1: |
147 | wx.MessageBox(_("Wrong delimiter '/' found in directory path. Use '%s' as delimiter.") % os.sep, _("Provide a Valid Directory")) | |
148 | return False | |
149 | if not os.path.exists(dirName): | |
150 | wx.MessageBox(_("That %sdirectory does not exist. Please choose an existing directory.") % infoString, _("Provide a Valid Directory")) | |
151 | return False | |
152 | if not ignoreFileConflicts: | |
153 | filePath = os.path.join(dirName, MakeNameEndInExtension(projName, "." + fileExtension)) | |
154 | if os.path.exists(filePath): | |
155 | if allowOverwriteOnPrompt: | |
156 | res = wx.MessageBox(_("That %sfile already exists. Would you like to overwrite it.") % infoString, "File Exists", style=wx.YES_NO|wx.NO_DEFAULT) | |
157 | return (res == wx.YES) | |
158 | else: | |
159 | wx.MessageBox(_("That %sfile already exists. Please choose a different name.") % infoString, "File Exists") | |
160 | return False | |
161 | ||
1f780e48 RD |
162 | return True |
163 | HALF_SPACE = 5 | |
164 | flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE) | |
165 | flexGridSizer.AddGrowableCol(1,1) | |
aca310e5 RD |
166 | if not useDirDialog: |
167 | flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) | |
168 | flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND) | |
169 | flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE) | |
170 | flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) | |
171 | flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND) | |
172 | flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0) | |
173 | else: | |
174 | flexGridSizer.Add(nameLabelText, 0, wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) | |
175 | flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND) | |
176 | flexGridSizer.Add(wx.StaticText(parent, -1, ""), 0) | |
177 | flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT) | |
178 | flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND) | |
179 | flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE) | |
1f780e48 | 180 | |
02b800ce RD |
181 | if returnAll: |
182 | return nameControl, dirControl, flexGridSizer, Validate, allControls | |
183 | else: | |
184 | return nameControl, dirControl, flexGridSizer, Validate | |
185 | ||
186 | ||
187 | def CreateDirectoryOnlyControl( parent, dirLabel=_("Location:"), startingDirectory=None, choiceDirs=None, appDirDefaultStartDir=False): | |
188 | ||
189 | if not choiceDirs: | |
190 | choiceDirs = [] | |
191 | projectDirs = [] | |
192 | ||
193 | if appDirDefaultStartDir: | |
194 | appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY, ProjectEditor.NEW_PROJECT_DIRECTORY_DEFAULT) | |
195 | else: | |
196 | appDirectory = wx.ConfigBase_Get().Read(ProjectEditor.PROJECT_DIRECTORY_KEY) | |
197 | if appDirectory: | |
198 | choiceDirs.append(appDirectory) | |
199 | if appDirDefaultStartDir and not startingDirectory: | |
200 | startingDirectory = appDirectory | |
201 | ||
202 | projectService = wx.GetApp().GetService(ProjectEditor.ProjectService) | |
203 | if projectService: | |
204 | curProjectDoc = projectService.GetCurrentProject() | |
205 | if curProjectDoc: | |
206 | homeDir = curProjectDoc.GetAppDocMgr().homeDir | |
207 | if homeDir and (homeDir not in choiceDirs): | |
208 | choiceDirs.append(homeDir) | |
209 | if not startingDirectory: | |
210 | startingDirectory = homeDir | |
211 | ||
212 | for projectDoc in projectService.GetOpenProjects(): | |
213 | if projectDoc == curProjectDoc: | |
214 | continue | |
215 | homeDir = projectDoc.GetAppDocMgr().homeDir | |
216 | if homeDir and (homeDir not in projectDirs): | |
217 | projectDirs.append(homeDir) | |
218 | projectDirs.sort(CaseInsensitiveCompare) | |
219 | for projectDir in projectDirs: | |
220 | if projectDir not in choiceDirs: | |
221 | choiceDirs.append(projectDir) | |
222 | ||
223 | if startingDirectory and (startingDirectory not in choiceDirs): | |
224 | choiceDirs.insert(0, startingDirectory) | |
225 | ||
226 | if os.getcwd() not in choiceDirs: | |
227 | choiceDirs.append(os.getcwd()) | |
aca310e5 RD |
228 | if appdirs.getSystemDir() not in choiceDirs: |
229 | choiceDirs.append(appdirs.getSystemDir()) | |
02b800ce RD |
230 | |
231 | ||
232 | if not startingDirectory: | |
233 | startingDirectory = os.getcwd() | |
234 | ||
235 | dirLabelText = wx.StaticText(parent, -1, dirLabel) | |
236 | dirControl = wx.ComboBox(parent, -1, startingDirectory, size=(-1,-1), choices=choiceDirs) | |
237 | dirControl.SetToolTipString(startingDirectory) | |
238 | button = wx.Button(parent, -1, _("Browse...")) | |
239 | ||
240 | def OnFindDirClick(event): | |
241 | dlg = wx.DirDialog(wx.GetApp().GetTopWindow(), | |
242 | _("Choose a directory:"), | |
243 | defaultPath=dirControl.GetValue().strip(), | |
244 | style=wx.DD_DEFAULT_STYLE|wx.DD_NEW_DIR_BUTTON) | |
245 | dlg.CenterOnParent() | |
246 | if dlg.ShowModal() == wx.ID_OK: | |
247 | dir = dlg.GetPath() | |
248 | if dirControl.FindString(dir) == wx.NOT_FOUND: | |
249 | dirControl.Insert(dir, 0) | |
250 | dirControl.SetValue(dir) | |
251 | dirControl.SetToolTipString(dir) | |
252 | dlg.Destroy() | |
253 | ||
254 | parent.Bind(wx.EVT_BUTTON, OnFindDirClick, button) | |
255 | ||
256 | def Validate(allowOverwriteOnPrompt=False): | |
257 | dirName = dirControl.GetValue().strip() | |
258 | if dirName == "": | |
259 | wx.MessageBox(_("Please provide a directory."), _("Provide a Directory")) | |
260 | return False | |
aca310e5 RD |
261 | if os.sep == "\\" and dirName.find("/") != -1: |
262 | wx.MessageBox(_("Wrong delimiter '/' found in directory path. Use '%s' as delimiter.") % os.sep, _("Provide a Valid Directory")) | |
263 | return False | |
02b800ce RD |
264 | if not os.path.exists(dirName): |
265 | wx.MessageBox(_("That directory does not exist. Please choose an existing directory."), _("Provide a Valid Directory")) | |
266 | return False | |
267 | return True | |
268 | ||
269 | HALF_SPACE = 5 | |
270 | flexGridSizer = wx.FlexGridSizer(cols = 3, vgap = HALF_SPACE, hgap = HALF_SPACE) | |
271 | flexGridSizer.AddGrowableCol(1,1) | |
272 | flexGridSizer.Add(dirLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.RIGHT, border=HALF_SPACE) | |
273 | flexGridSizer.Add(dirControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE) | |
274 | flexGridSizer.Add(button, flag=wx.ALIGN_RIGHT|wx.LEFT, border=HALF_SPACE) | |
275 | ||
276 | return dirControl, flexGridSizer, Validate | |
277 | ||
278 | ||
279 | def CreateNameOnlyControl( parent, fileLabel, startingName="", startingDirectoryControl=None): | |
280 | ||
281 | fileLabelText = wx.StaticText(parent, -1, fileLabel) | |
282 | nameControl = wx.TextCtrl(parent, -1, startingName, size=(-1,-1)) | |
283 | ||
aca310e5 | 284 | def Validate(allowOverwriteOnPrompt=False, validClassName=False): |
02b800ce RD |
285 | projName = nameControl.GetValue().strip() |
286 | if projName == "": | |
287 | wx.MessageBox(_("Blank name. Please enter a valid name."), _("Project Name")) | |
288 | return False | |
02b800ce | 289 | if projName.find(' ') != -1: |
aca310e5 | 290 | wx.MessageBox(_("Spaces in name. Name cannot have spaces."), _("Project Name")) |
02b800ce | 291 | return False |
aca310e5 RD |
292 | if validClassName: |
293 | if projName[0].isdigit(): | |
294 | wx.MessageBox(_("Name cannot start with a number. Please enter a valid name."), _("Project Name")) | |
295 | return False | |
296 | if projName.endswith(".agp"): | |
297 | projName2 = projName[:-4] | |
298 | else: | |
299 | projName2 = projName | |
300 | if not projName2.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ending '.agp'. | |
301 | wx.MessageBox(_("Name must be alphanumeric ('_' allowed). Please enter a valid name."), _("Project Name")) | |
302 | return False | |
02b800ce RD |
303 | path = os.path.join(startingDirectoryControl.GetValue().strip(), projName) |
304 | if os.path.exists(path): | |
305 | if os.path.isdir(path): | |
306 | message = _("Project '%s' already exists. Would you like to overwrite the contents of the project?") % projName | |
307 | else: # os.path.isfile(path): | |
308 | message = _("'%s' already exists as a file. Would you like to replace it with the project?") % nameControl.GetValue().strip() | |
309 | ||
310 | yesNoMsg = wx.MessageDialog(wx.GetApp().GetTopWindow(), | |
311 | message, | |
312 | _("Project Directory Exists"), | |
313 | wx.YES_NO|wx.ICON_QUESTION | |
314 | ) | |
315 | yesNoMsg.CenterOnParent() | |
316 | status = yesNoMsg.ShowModal() | |
317 | yesNoMsg.Destroy() | |
318 | if status == wx.ID_NO: | |
319 | return False | |
320 | return True | |
321 | ||
322 | HALF_SPACE = 5 | |
323 | flexGridSizer = wx.FlexGridSizer(cols = 2, vgap = HALF_SPACE, hgap = HALF_SPACE) | |
324 | flexGridSizer.AddGrowableCol(1,1) | |
325 | flexGridSizer.Add(fileLabelText, flag=wx.ALIGN_CENTER_VERTICAL|wx.ALIGN_LEFT|wx.TOP|wx.RIGHT, border=HALF_SPACE) | |
326 | flexGridSizer.Add(nameControl, 2, flag=wx.ALIGN_CENTER_VERTICAL|wx.EXPAND, border=HALF_SPACE) | |
327 | ||
328 | return nameControl, flexGridSizer, Validate | |
329 | ||
1f780e48 | 330 | |
aca310e5 RD |
331 | def ValidateName(name, ext=None, hint="name"): |
332 | """ Returns an error string if there is something wrong with the name. | |
333 | Otherwise it returns None | |
334 | """ | |
335 | if name == "": | |
336 | return _("Blank %s. Please enter a valid %s.") % (hint, hint) | |
337 | ||
338 | if name.find(' ') != -1: | |
339 | return _("Spaces in %s. %s cannot have spaces.") % (hint, hint.title()) | |
340 | ||
341 | if name[0].isdigit(): | |
342 | return _("%s cannot start with a number. Please enter a valid %s.") % (hint.title(), hint) | |
343 | ||
344 | if ext and name.endswith(ext): # strip extension if provided | |
345 | lenExt = len(ext) | |
346 | name = name[:-lenExt] | |
347 | ||
348 | if not name.replace("_", "a").isalnum(): # [a-zA-Z0-9_] note '_' is allowed and ext ending. | |
349 | return _("%s must be alphanumeric ('_' allowed). Please enter a valid %s.") % (hint.title(), hint) | |
350 | ||
351 | return None | |
352 | ||
353 | ||
02b800ce RD |
354 | def GetCurrentProject(): |
355 | projectDocument = None | |
356 | projectService = wx.GetApp().GetService(ProjectEditor.ProjectService) | |
357 | if projectService: | |
358 | projectDocument = projectService.GetCurrentProject() | |
359 | return projectDocument | |
360 | ||
361 | def AddFilesToCurrentProject(paths, folderPath=None, types=None, names=None, save=False): | |
1f780e48 RD |
362 | projectService = wx.GetApp().GetService(ProjectEditor.ProjectService) |
363 | if projectService: | |
364 | projectDocument = projectService.GetCurrentProject() | |
365 | if projectDocument: | |
366 | files = projectDocument.GetFiles() | |
367 | for path in paths: | |
368 | if path in files: | |
369 | paths.remove(path) | |
370 | if paths: | |
02b800ce | 371 | projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, folderPath=folderPath, types=types, names=names)) |
1f780e48 RD |
372 | if save: |
373 | projectDocument.OnSaveDocument(projectDocument.GetFilename()) | |
374 | ||
02b800ce RD |
375 | def AddFilesToProject(projectDocument, paths, types=None, names=None, save=False): |
376 | if projectDocument: | |
377 | files = projectDocument.GetFiles() | |
378 | for path in paths: | |
379 | if path in files: | |
380 | paths.remove(path) | |
381 | if paths: | |
382 | projectDocument.GetCommandProcessor().Submit(ProjectEditor.ProjectAddFilesCommand(projectDocument, paths, types=types, names=names)) | |
383 | if save: | |
384 | projectDocument.OnSaveDocument(projectDocument.GetFilename()) | |
385 | ||
386 | ||
1f780e48 RD |
387 | def MakeNameEndInExtension(name, extension): |
388 | if not name: | |
389 | return name | |
390 | root, ext = os.path.splitext(name) | |
391 | if ext == extension: | |
392 | return name | |
393 | else: | |
394 | return name + extension | |
395 | ||
02b800ce | 396 | |
2eeaec19 RD |
397 | def GetPythonExecPath(): |
398 | pythonExecPath = wx.ConfigBase_Get().Read("ActiveGridPythonLocation") | |
399 | if not pythonExecPath: | |
02b800ce | 400 | pythonExecPath = sysutils.pythonExecPath |
2eeaec19 RD |
401 | return pythonExecPath |
402 | ||
403 | ||
aca310e5 RD |
404 | def GetPHPExecPath(): |
405 | PHPExecPath = wx.ConfigBase_Get().Read("ActiveGridPHPLocation") | |
406 | return PHPExecPath | |
407 | ||
408 | ||
409 | def GetPHPINIPath(): | |
410 | PHPINIPath = wx.ConfigBase_Get().Read("ActiveGridPHPINILocation") | |
411 | return PHPINIPath | |
412 | ||
413 | ||
02b800ce RD |
414 | def _DoRemoveRecursive(path, skipFile=None, skipped=False): |
415 | if path == skipFile: | |
416 | skipped = True | |
417 | elif os.path.isdir(path): | |
418 | for file in os.listdir(path): | |
419 | file_or_dir = os.path.join(path,file) | |
420 | if skipFile == file_or_dir: | |
421 | skipped = True | |
422 | elif os.path.isdir(file_or_dir) and not os.path.islink(file_or_dir): | |
423 | if _DoRemoveRecursive(file_or_dir, skipFile): # it's a directory recursive call to function again | |
424 | skipped = True | |
425 | else: | |
426 | os.remove(file_or_dir) # it's a file, delete it | |
427 | if not skipped: | |
428 | os.rmdir(path) # delete the directory here | |
429 | else: | |
430 | os.remove(path) | |
431 | ||
432 | return skipped | |
433 | ||
434 | ||
435 | def RemoveRecursive(path, skipFile=None): | |
436 | _DoRemoveRecursive(path, skipFile) | |
437 | ||
438 | ||
439 | def CaseInsensitiveCompare(s1, s2): | |
440 | """ Method used by sort() to sort values in case insensitive order """ | |
441 | return strutils.caseInsensitiveCompare(s1, s2) | |
442 | ||
443 | ||
444 | def GetAnnotation(model, elementName): | |
445 | """ Get an object's annotation used for tooltips """ | |
aca310e5 RD |
446 | if hasattr(model, "_complexType"): |
447 | ct = model._complexType | |
448 | elif hasattr(model, "__xsdcomplextype__"): | |
02b800ce | 449 | ct = model.__xsdcomplextype__ |
aca310e5 RD |
450 | else: |
451 | ct = None | |
452 | ||
453 | if ct: | |
454 | el = ct.findElement(elementName) | |
455 | if el and el.annotation: | |
456 | return el.annotation | |
02b800ce RD |
457 | |
458 | return "" | |
459 | ||
460 | ||
aca310e5 RD |
461 | def GetDisplayName(doc, name): |
462 | if name: | |
463 | appDocMgr = doc.GetAppDocMgr() | |
464 | if appDocMgr: | |
465 | name = appDocMgr.toDisplayTypeName(name) | |
466 | else: | |
467 | namespace, name = xmlutils.splitType(name) | |
468 | if namespace and hasattr(doc.GetModel(), "getXmlNamespaces"): | |
469 | for xmlkey, xmlval in doc.GetModel().getXmlNamespaces().iteritems(): | |
470 | if xmlval == namespace: | |
471 | name = "%s:%s" % (xmlkey, name) | |
472 | break | |
473 | ||
474 | if name: | |
475 | import activegrid.model.schema as schemalib | |
476 | baseTypeName = schemalib.mapXsdType(name) | |
477 | if baseTypeName: | |
478 | name = baseTypeName | |
479 | ||
480 | return name | |
481 | ||
482 | ||
483 | def GetInternalName(doc, name): | |
484 | if name: | |
485 | appDocMgr = doc.GetAppDocMgr() | |
486 | if appDocMgr: | |
487 | name = appDocMgr.toInternalTypeName(name) | |
488 | else: | |
489 | namespace, name = xmlutils.splitType(name) | |
490 | if namespace and hasattr(doc.GetModel(), "getXmlNamespaces"): | |
491 | for xmlkey, xmlval in doc.GetModel().getXmlNamespaces().iteritems(): | |
492 | if xmlkey == namespace: | |
493 | name = "%s:%s" % (xmlval, name) | |
494 | break | |
495 | ||
496 | import activegrid.model.schema as schemalib | |
497 | name = schemalib.mapAGType(name) | |
498 | ||
499 | return name | |
500 | ||
501 | ||
02b800ce RD |
502 | #---------------------------------------------------------------------------- |
503 | # Methods for finding application level info | |
504 | #---------------------------------------------------------------------------- | |
505 | ||
506 | def GetProjectForDoc(doc): | |
507 | """ Given a document find which project it belongs to. | |
508 | Tries to intelligently resolve conflicts if it is in more than one open project. | |
509 | """ | |
510 | projectService = wx.GetApp().GetService(ProjectEditor.ProjectService) | |
511 | ||
512 | projectDoc = projectService.FindProjectFromMapping(doc) | |
513 | if projectDoc: | |
514 | return projectDoc | |
515 | ||
516 | projectDoc = projectService.GetCurrentProject() | |
517 | if not projectDoc: | |
518 | return None | |
519 | if projectDoc.IsFileInProject(doc.GetFilename()): | |
520 | return projectDoc | |
521 | ||
522 | projects = [] | |
523 | openDocs = wx.GetApp().GetDocumentManager().GetDocuments() | |
524 | for openDoc in openDocs: | |
525 | if openDoc == projectDoc: | |
526 | continue | |
527 | if(isinstance(openDoc, ProjectEditor.ProjectDocument)): | |
528 | if openDoc.IsFileInProject(doc.GetFilename()): | |
529 | projects.append(openDoc) | |
530 | ||
531 | if projects: | |
532 | if len(projects) == 1: | |
533 | return projects[0] | |
534 | else: | |
535 | choices = [os.path.basename(project.GetFilename()) for project in projects] | |
536 | 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) | |
537 | dlg.CenterOnParent() | |
538 | projectDoc = None | |
539 | if dlg.ShowModal() == wx.ID_OK: | |
540 | i = dlg.GetSelection() | |
541 | projectDoc = projects[i] | |
542 | dlg.Destroy() | |
543 | return projectDoc | |
544 | ||
545 | return None | |
546 | ||
547 | ||
548 | def GetAppInfoForDoc(doc): | |
549 | """ Get the AppInfo for a given document """ | |
550 | projectDoc = GetProjectForDoc(doc) | |
551 | if projectDoc: | |
552 | return projectDoc.GetAppInfo() | |
553 | return None | |
554 | ||
555 | ||
556 | def GetAppDocMgrForDoc(doc): | |
557 | """ Get the AppDocMgr for a given document """ | |
558 | projectDoc = GetProjectForDoc(doc) | |
559 | if projectDoc: | |
560 | return projectDoc.GetModel() | |
561 | return None | |
562 | ||
563 | ||
564 | def GetAppInfoLanguage(doc=None): | |
aca310e5 RD |
565 | from activegrid.server.projectmodel import LANGUAGE_DEFAULT |
566 | ||
02b800ce RD |
567 | if doc: |
568 | language = doc.GetAppInfo().language | |
569 | else: | |
570 | language = None | |
571 | ||
572 | if not language: | |
573 | config = wx.ConfigBase_Get() | |
574 | language = config.Read(ProjectEditor.APP_LAST_LANGUAGE, LANGUAGE_DEFAULT) | |
575 | ||
576 | if doc: | |
577 | doc.GetAppInfo().language = language # once it is selected, it must be set. | |
578 | ||
579 | return language | |
aca310e5 RD |
580 | |
581 | def AddWsdlAgToProjectFromWsdlRegistration(wsdlRegistration): | |
582 | """Add wsdl ag for registry entry.""" | |
583 | ||
584 | wsdlPath = wsdlRegistration.path | |
585 | rootPath = None | |
586 | serviceRefName = wsdlRegistration.name | |
587 | ||
588 | agwsDoc = _InitWsdlAg(wsdlPath, rootPath, serviceRefName) | |
589 | ||
590 | if (agwsDoc == None): | |
591 | return | |
592 | ||
593 | serviceRef = agwsDoc.GetModel() | |
594 | ||
595 | serviceRef.serviceType = wsdlRegistration.type | |
596 | ||
597 | import activegrid.server.deployment as deployment | |
598 | ||
599 | if (serviceRef.serviceType == deployment.SERVICE_LOCAL): | |
600 | serviceRef.localService = deployment.LocalService( | |
601 | wsdlRegistration.codeFile) | |
602 | ||
603 | elif (serviceRef.serviceType == deployment.SERVICE_DATABASE): | |
604 | serviceRef.databaseService = deployment.DatabaseService( | |
605 | wsdlRegistration.datasourceName) | |
606 | ||
607 | elif (serviceRef.serviceType == deployment.SERVICE_SOAP): | |
608 | pass | |
609 | ||
610 | elif (serviceRef.serviceType == deployment.SERVICE_RSS): | |
611 | serviceRef.rssService = deployment.RssService(wsdlRegistration.feedUrl) | |
612 | ||
613 | elif (serviceRef.serviceType == deployment.SERVICE_REST): | |
614 | serviceRef.restService = deployment.RestService( | |
615 | wsdlRegistration.baseUrl) | |
616 | else: | |
617 | raise AssertionError("Unknown service type") | |
618 | ||
619 | _AddToProject(agwsDoc, addWsdl=True) | |
620 | ||
621 | ||
622 | def AddWsdlAgToProject(wsdlPath, rootPath=fileutils.AG_SYSTEM_STATIC_VAR_REF, | |
623 | serviceRefName=None, className=None, serviceType=None, | |
624 | dataSourceName=None): | |
625 | """ | |
626 | wsdlPath: path to wsdl from rootPath. If wsdlPath is absolute, rootPath | |
627 | is ignored. rootPath is also ignored when rootPath is set to None. | |
628 | rootPath: defaults to ${AG_SYSTEM_STATIC}. | |
629 | serviceRefName: If None, it will be set to the wsdl file name without | |
630 | the .wsdl file extension. | |
631 | className: if not None, will be used for the the wsdlag's ClassName. | |
632 | serviceType: defaults to local. | |
633 | dataSourceName: if serviceType is deployment.DATABASE, the ds must be | |
634 | provided. | |
635 | """ | |
636 | import WsdlAgEditor | |
637 | import XFormWizard | |
638 | import activegrid.model.basedocmgr as basedocmgr | |
639 | import activegrid.server.deployment as deployment | |
640 | ||
641 | if (serviceType == None): | |
642 | serviceType = deployment.SERVICE_LOCAL | |
643 | ||
644 | ||
645 | agwsDoc = _InitWsdlAg(wsdlPath, rootPath, serviceRefName) | |
646 | ||
647 | if (agwsDoc == None): | |
648 | return | |
649 | ||
650 | serviceRef = agwsDoc.GetModel() | |
651 | ||
652 | serviceRef.serviceType = serviceType | |
653 | ||
654 | if (serviceType == deployment.SERVICE_DATABASE and dataSourceName != None): | |
655 | serviceRef.databaseService = deployment.DatabaseService(dataSourceName) | |
656 | else: | |
657 | serviceRef.localService = deployment.LocalService(className=className) | |
658 | ||
659 | _AddToProject(agwsDoc) | |
660 | ||
661 | ||
662 | def _AddToProject(agwsDoc, addWsdl=False): | |
663 | import activegrid.model.basedocmgr as basedocmgr | |
664 | projectDoc = GetCurrentProject() | |
665 | agwsDoc.OnSaveDocument(agwsDoc.GetFilename()) | |
666 | ||
667 | files = [agwsDoc.fileName] | |
668 | types = [basedocmgr.FILE_TYPE_SERVICE] | |
669 | names = [agwsDoc.GetModel().name] | |
670 | if (addWsdl): | |
671 | m = agwsDoc.GetModel() | |
672 | wsdlName = os.path.splitext(os.path.basename(m.filePath))[0] | |
673 | appDocMgr = projectDoc.GetAppDocMgr() | |
674 | if (appDocMgr.findService(wsdlName) == None): | |
675 | m = agwsDoc.GetModel() | |
676 | files.append(m.filePath) | |
677 | types.append(None) | |
678 | names.append(wsdlName) | |
679 | ||
680 | ProjectEditor.ProjectAddFilesCommand(projectDoc, files, types=types, | |
681 | names=names).Do() | |
682 | ||
683 | ||
684 | def _InitWsdlAg(wsdlPath, rootPath=fileutils.AG_SYSTEM_STATIC_VAR_REF, | |
685 | serviceRefName=None): | |
686 | ||
687 | projectDoc = GetCurrentProject() | |
688 | appDocMgr = projectDoc.GetAppDocMgr() | |
689 | ||
690 | if (serviceRefName == None): | |
691 | serviceRefName = os.path.splitext(os.path.basename(wsdlPath))[0] | |
692 | ||
693 | if (appDocMgr.findServiceRef(serviceRefName) != None): | |
694 | return None | |
695 | ||
696 | import WsdlAgEditor | |
697 | import XFormWizard | |
698 | import activegrid.server.deployment as deployment | |
699 | ||
700 | template = XFormWizard.GetTemplate(WsdlAgEditor.WsdlAgDocument) | |
701 | ext = template.GetDefaultExtension() | |
702 | fullPath = os.path.join(appDocMgr.homeDir, serviceRefName + ext) | |
703 | ||
704 | agwsDoc = template.CreateDocument( | |
705 | fullPath, flags=(wx.lib.docview.DOC_NO_VIEW|wx.lib.docview.DOC_NEW| | |
706 | wx.lib.docview.DOC_OPEN_ONCE)) | |
707 | ||
708 | serviceRef = agwsDoc.GetModel() | |
709 | serviceRef.name = serviceRefName | |
710 | ||
711 | if (rootPath == None or os.path.isabs(wsdlPath)): | |
712 | serviceRef.filePath = wsdlPath | |
713 | else: | |
714 | # make sure to use forward slashes for the path to the .wsdl | |
715 | wsdlPath = wsdlPath.replace("\\", "/") | |
716 | ||
717 | if not wsdlPath.startswith("/"): | |
718 | wsdlPath = "/%s" % wsdlPath | |
719 | serviceRef.filePath = "%s%s" % (rootPath, wsdlPath) | |
720 | ||
721 | agwsDoc.fileName = fullPath | |
722 | ||
723 | return agwsDoc | |
724 | ||
725 | ||
726 | def GetSchemaName(schema): | |
727 | return os.path.basename(schema.fileName) | |
728 | ||
729 | ||
730 | class AGChoice(wx.Choice): | |
731 | """Extension to wx.Choice that fixes linux bug where first item of choices | |
732 | passed into ctor would be visible, but not selected.""" | |
733 | def __init__(self, parent, id, choices=[]): | |
734 | super(AGChoice, self).__init__(parent=parent, id=id) | |
735 | self.AppendItems(choices) |