]> git.saurik.com Git - wxWidgets.git/blob - wxPython/samples/ide/activegrid/tool/project.py
Merged modifications from the 2.6 branch
[wxWidgets.git] / wxPython / samples / ide / activegrid / tool / project.py
1 #----------------------------------------------------------------------------
2 # Name: project.py
3 # Purpose: project model for wx.lib.pydocview
4 #
5 # Author: Morgan Hua
6 #
7 # Created: 8/25/05
8 # CVS-ID: $Id$
9 # Copyright: (c) 2005 ActiveGrid, Inc.
10 # License: wxWindows License
11 #----------------------------------------------------------------------------
12
13 import copy
14 import os
15 import os.path
16 import activegrid.util.xmlutils as xmlutils
17 from IDE import ACTIVEGRID_BASE_IDE
18 if not ACTIVEGRID_BASE_IDE:
19 import activegrid.model.basedocmgr as basedocmgr
20 import AppInfo
21
22 #----------------------------------------------------------------------------
23 # Constants
24 #----------------------------------------------------------------------------
25 # Always add new versions, never edit the version number
26 # This allows you to upgrade the file by checking the version number
27 PROJECT_VERSION_050730 = '10'
28 PROJECT_VERSION_050826 = '11'
29
30
31 #----------------------------------------------------------------------------
32 # XML Marshalling Methods
33 #----------------------------------------------------------------------------
34
35 def load(fileObject):
36 version = xmlutils.getAgVersion(fileObject.name)
37 # most current versions on top
38 if version == PROJECT_VERSION_050826:
39 fileObject.seek(0)
40 if ACTIVEGRID_BASE_IDE:
41 KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
42 else:
43 KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
44 project = xmlutils.load(fileObject.name, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
45 elif version == PROJECT_VERSION_050730:
46 fileObject.seek(0)
47 project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
48 project = project.upgradeVersion()
49 else:
50 # assume it is old version without version number
51 fileObject.seek(0)
52 project = xmlutils.load(fileObject.name, knownTypes={"project" : Project_10})
53 if project:
54 project = project.upgradeVersion()
55 else:
56 print "Project, unknown version:", version
57 return None
58
59 if project:
60 project._projectDir = os.path.dirname(fileObject.name)
61 project.RelativeToAbsPath()
62
63 return project
64
65
66 def save(fileObject, project, productionDeployment=False):
67 if not project._projectDir:
68 project._projectDir = os.path.dirname(fileObject.name)
69 project.AbsToRelativePath() # temporarily change it to relative paths for saving
70 if ACTIVEGRID_BASE_IDE:
71 KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile}
72 else:
73 KNOWNTYPES = {"ag:project" : Project, "ag:file" : ProjectFile, "ag:appInfo" : AppInfo.AppInfo}
74
75 savedHomeDir = project.homeDir
76 if productionDeployment:
77 # for deployments, we don't want an abs path in homeDir since that
78 # would tie the app to the current filesystem. So unset it.
79 project.homeDir = None
80
81 xmlutils.save(fileObject.name, project, prettyPrint=True, knownTypes=KNOWNTYPES, knownNamespaces=xmlutils.KNOWN_NAMESPACES)
82
83 if productionDeployment:
84 project.homeDir = savedHomeDir
85
86 project.RelativeToAbsPath() # swap it back to absolute path
87
88
89 #----------------------------------------------------------------------------
90 # Classes
91 #----------------------------------------------------------------------------
92
93 class BaseProject(object):
94
95 __xmlname__ = "project"
96 __xmlexclude__ = ('fileName', '_projectDir', '_getDocCallback')
97 __xmlattributes__ = ("_homeDir", "version")
98 __xmlrename__ = { "_homeDir":"homeDir", "_appInfo":"appInfo" }
99 __xmlflattensequence__ = { "_files":("file",) }
100 __xmldefaultnamespace__ = xmlutils.AG_NS_URL
101 __xmlattrnamespaces__ = { "ag": ["version", "_homeDir"] }
102
103
104 def __init__(self):
105 self.__xmlnamespaces__ = { "ag" : xmlutils.AG_NS_URL }
106 self.version = PROJECT_VERSION_050826
107 self._files = []
108 self._projectDir = None # default for homeDir, set on load
109 self._homeDir = None # user set homeDir for use in calculating relative path
110 if not ACTIVEGRID_BASE_IDE:
111 self._appInfo = AppInfo.AppInfo()
112
113
114 def __copy__(self):
115 clone = Project()
116 clone._files = [copy.copy(file) for file in self._files]
117 clone._projectDir = self._projectDir
118 clone._homeDir = self._homeDir
119 if not ACTIVEGRID_BASE_IDE:
120 clone._appInfo = self._appInfo
121 return clone
122
123
124 def initialize(self):
125 """ Required method for xmlmarshaller """
126 pass
127
128
129 def GetAppInfo(self):
130 return self._appInfo
131
132
133 def AddFile(self, filePath=None, logicalFolder=None, type=None, name=None, file=None):
134 """ Usage: self.AddFile(filePath, logicalFolder, type, name) # used for initial generation of object
135 self.AddFile(file=xyzFile) # normally used for redo/undo
136 Add newly created file object using filePath and logicalFolder or given file object
137 """
138 if file:
139 self._files.append(file)
140 else:
141 self._files.append(ProjectFile(filePath, logicalFolder, type, name, getDocCallback=self._getDocCallback))
142
143
144 def RemoveFile(self, file):
145 self._files.remove(file)
146
147
148 def FindFile(self, filePath):
149 if filePath:
150 for file in self._files:
151 if file.filePath == filePath:
152 return file
153
154 return None
155
156
157 def _GetFilePaths(self):
158 return [file.filePath for file in self._files]
159
160
161 filePaths = property(_GetFilePaths)
162
163
164 def _GetLogicalFolders(self):
165 folders = []
166 for file in self._files:
167 if file.logicalFolder and file.logicalFolder not in folders:
168 folders.append(file.logicalFolder)
169 return folders
170
171
172 logicalFolders = property(_GetLogicalFolders)
173
174
175 def _GetPhysicalFolders(self):
176 physicalFolders = []
177 for file in self._files:
178 physicalFolder = file.physicalFolder
179 if physicalFolder and physicalFolder not in physicalFolders:
180 physicalFolders.append(physicalFolder)
181 return physicalFolders
182
183
184 physicalFolders = property(_GetPhysicalFolders)
185
186
187 def _GetHomeDir(self):
188 if self._homeDir:
189 return self._homeDir
190 else:
191 return self._projectDir
192
193
194 def _SetHomeDir(self, parentPath):
195 self._homeDir = parentPath
196
197
198 def _IsDefaultHomeDir(self):
199 return (self._homeDir == None)
200
201
202 isDefaultHomeDir = property(_IsDefaultHomeDir)
203
204
205 homeDir = property(_GetHomeDir, _SetHomeDir)
206
207
208 def GetRelativeFolders(self):
209 relativeFolders = []
210 for file in self._files:
211 relFolder = file.GetRelativeFolder(self.homeDir)
212 if relFolder and relFolder not in relativeFolders:
213 relativeFolders.append(relFolder)
214 return relativeFolders
215
216
217 def AbsToRelativePath(self):
218 for file in self._files:
219 file.AbsToRelativePath(self.homeDir)
220
221
222 def RelativeToAbsPath(self):
223 for file in self._files:
224 file.RelativeToAbsPath(self.homeDir)
225
226
227 #----------------------------------------------------------------------------
228 # BaseDocumentMgr methods
229 #----------------------------------------------------------------------------
230
231
232 def fullPath(self, fileName):
233 fileName = super(BaseProject, self).fullPath(fileName)
234
235 if os.path.isabs(fileName):
236 absPath = fileName
237 elif self.homeDir:
238 absPath = os.path.join(self.homeDir, fileName)
239 else:
240 absPath = os.path.abspath(fileName)
241 return os.path.normpath(absPath)
242
243
244 def documentRefFactory(self, name, fileType, filePath):
245 return ProjectFile(filePath=self.fullPath(filePath), type=fileType, name=name, getDocCallback=self._getDocCallback)
246
247
248 def findAllRefs(self):
249 return self._files
250
251
252 def GetXFormsDirectory(self):
253 forms = self.findRefsByFileType(basedocmgr.FILE_TYPE_XFORM)
254 filePaths = map(lambda form: form.filePath, forms)
255 xformdir = os.path.commonprefix(filePaths)
256 if not xformdir:
257 xformdir = self.homeDir
258 return xformdir
259
260
261 def setRefs(self, files):
262 self._files = files
263
264
265 def findRefsByFileType(self, fileType):
266 fileList = []
267 for file in self._files:
268 if fileType == file.type:
269 fileList.append(file)
270 return fileList
271
272
273 def GenerateServiceRefPath(self, wsdlFilePath):
274 # HACK: temporary solution to getting wsdlag path from wsdl path.
275 import wx
276 from WsdlAgEditor import WsdlAgDocument
277 ext = WsdlAgDocument.WSDL_AG_EXT
278 for template in wx.GetApp().GetDocumentManager().GetTemplates():
279 if template.GetDocumentType() == WsdlAgDocument:
280 ext = template.GetDefaultExtension()
281 break;
282 wsdlAgFilePath = os.path.splitext(wsdlFilePath)[0] + ext
283 return wsdlAgFilePath
284
285
286 def SetDocCallback(self, getDocCallback):
287 self._getDocCallback = getDocCallback
288 for file in self._files:
289 file._getDocCallback = getDocCallback
290
291
292 if ACTIVEGRID_BASE_IDE:
293 class Project(BaseProject):
294 pass
295 else:
296 class Project(BaseProject, basedocmgr.BaseDocumentMgr):
297 pass
298
299
300 class ProjectFile(object):
301 __xmlname__ = "file"
302 __xmlexclude__ = ('_getDocCallback', '_docCallbackCacheReturnValue', '_docModelCallbackCacheReturnValue', '_doc',)
303 __xmlattributes__ = ["filePath", "logicalFolder", "type", "name"]
304 __xmldefaultnamespace__ = xmlutils.AG_NS_URL
305
306
307 def __init__(self, filePath=None, logicalFolder=None, type=None, name=None, getDocCallback=None):
308 self.filePath = filePath
309 self.logicalFolder = logicalFolder
310 self.type = type
311 self.name = name
312 self._getDocCallback = getDocCallback
313 self._docCallbackCacheReturnValue = None
314 self._docModelCallbackCacheReturnValue = None
315 self._doc = None
316
317
318 def _GetDocumentModel(self):
319 # possible bug is if document gets replaced outside of IDE, where we'll return previous doc.
320 # originally added a timestamp check but that increased the time again to 4x
321 if self._docModelCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
322 return self._docModelCallbackCacheReturnValue
323
324 if self._getDocCallback:
325 self._docCallbackCacheReturnValue, self._docModelCallbackCacheReturnValue = self._getDocCallback(self.filePath)
326 return self._docModelCallbackCacheReturnValue
327
328 return None
329
330
331 document = property(_GetDocumentModel)
332
333
334 def _GetDocument(self):
335 # Hack, just return the IDE document wrapper that corresponds to the runtime document model
336 # callers should have called ".document" before calling ".ideDocument"
337 if self._docCallbackCacheReturnValue: # accelerator for caching document, got 4x speed up.
338 return self._docCallbackCacheReturnValue
339 return None
340
341
342 ideDocument = property(_GetDocument)
343
344
345 def _typeEnumeration(self):
346 return basedocmgr.FILE_TYPE_LIST
347
348
349 def _GetPhysicalFolder(self):
350 dir = None
351 if self.filePath:
352 dir = os.path.dirname(self.filePath)
353 if os.sep != '/':
354 dir = dir.replace(os.sep, '/') # require '/' as delimiter
355 return dir
356
357
358 physicalFolder = property(_GetPhysicalFolder)
359
360
361 def GetRelativeFolder(self, parentPath):
362 parentPathLen = len(parentPath)
363
364 dir = None
365 if self.filePath:
366 dir = os.path.dirname(self.filePath)
367 if dir.startswith(parentPath):
368 dir = "." + dir[parentPathLen:] # convert to relative path
369 if os.sep != '/':
370 dir = dir.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
371 return dir
372
373
374 def AbsToRelativePath(self, parentPath):
375 """ Used to convert path to relative path for saving (disk format) """
376 parentPathLen = len(parentPath)
377
378 if self.filePath.startswith(parentPath):
379 self.filePath = "." + self.filePath[parentPathLen:] # convert to relative path
380 if os.sep != '/':
381 self.filePath = self.filePath.replace(os.sep, '/') # always save out with '/' as path separator for cross-platform compatibility.
382 else:
383 pass # not a decendant of project, use absolute path
384
385
386 def RelativeToAbsPath(self, parentPath):
387 """ Used to convert path to absolute path (for any necessary disk access) """
388 if self.filePath.startswith("."): # relative to project file
389 self.filePath = os.path.normpath(os.path.join(parentPath, self.filePath))
390
391
392 #----------------------------------------------------------------------------
393 # BaseDocumentMgr methods
394 #----------------------------------------------------------------------------
395
396 def _GetDoc(self):
397 # HACK: temporary solution.
398 import wx
399 import wx.lib.docview
400 if not self._doc:
401 docMgr = wx.GetApp().GetDocumentManager()
402
403 doc = docMgr.CreateDocument(self.filePath, docMgr.GetFlags()|wx.lib.docview.DOC_SILENT|wx.lib.docview.DOC_OPEN_ONCE|wx.lib.docview.DOC_NO_VIEW)
404 if (doc == None): # already open
405 docs = docMgr.GetDocuments()
406 for d in docs:
407 if d.GetFilename() == self.filePath:
408 doc = d
409 break
410 self._doc = doc
411 return self._doc
412
413
414 def _GetLocalServiceProcessName(self):
415 # HACK: temporary solution to getting process name from wsdlag file.
416 return self._GetDoc().GetModel().processName
417
418
419 processName = property(_GetLocalServiceProcessName)
420
421
422 def _GetStateful(self):
423 # HACK: temporary solution to getting stateful from wsdlag file.
424 return self._GetDoc().GetModel().stateful
425
426
427 def _SetStateful(self, stateful):
428 # HACK: temporary solution to setting stateful from wsdlag file.
429 self._GetDoc().GetModel().stateful = stateful
430
431
432 stateful = property(_GetStateful, _SetStateful)
433
434
435 def _GetLocalServiceCodeFile(self):
436 # HACK: temporary solution to getting class name from wsdlag file.
437 return self._GetDoc().GetModel().localServiceCodeFile
438
439
440 def _SetLocalServiceCodeFile(self, codefile):
441 # HACK: temporary solution to setting class name from wsdlag file.
442 self._GetDoc().GetModel().localServiceCodeFile = codefile
443
444
445 localServiceCodeFile = property(_GetLocalServiceCodeFile, _SetLocalServiceCodeFile)
446
447
448 def _GetLocalServiceClassName(self):
449 # HACK: temporary solution to getting class name from wsdlag file.
450 return self._GetDoc().GetModel().localServiceClassName
451
452
453 def _SetLocalServiceClassName(self, className):
454 # HACK: temporary solution to setting class name from wsdlag file.
455 self._GetDoc().GetModel().localServiceClassName = className
456
457
458 localServiceClassName = property(_GetLocalServiceClassName, _SetLocalServiceClassName)
459
460
461
462 # only activate this code if we programatically need to access these values
463 ## def _GetRssServiceBaseURL(self):
464 ## return self._GetDoc().GetModel().rssServiceBaseURL
465 ##
466 ##
467 ## def _SetRssServiceBaseURL(self, baseURL):
468 ## self._GetDoc().GetModel().rssServiceBaseURL = baseURL
469 ##
470 ##
471 ## rssServiceBaseURL = property(_GetRssServiceBaseURL, _SetRssServiceBaseURL)
472 ##
473 ##
474 ## def _GetRssServiceRssVersion(self):
475 ## return self._GetDoc().GetModel().rssServiceRssVersion
476 ##
477 ##
478 ## def _SetRssServiceRssVersion(self, rssVersion):
479 ## self._GetDoc().GetModel().rssServiceRssVersion = rssVersion
480 ##
481 ##
482 ## rssServiceRssVersion = property(_GetRssServiceRssVersion, _SetRssServiceRssVersion)
483
484
485 def _GetServiceRefServiceType(self):
486 # HACK: temporary solution to getting service type from wsdlag file.
487 model = self._GetDoc().GetModel()
488 if hasattr(model, 'serviceType'):
489 return model.serviceType
490 else:
491 return None
492
493
494 def _SetServiceRefServiceType(self, serviceType):
495 # HACK: temporary solution to getting service type from wsdlag file.
496 self._GetDoc().GetModel().serviceType = serviceType
497
498
499 serviceType = property(_GetServiceRefServiceType, _SetServiceRefServiceType)
500
501
502 def getExternalPackage(self):
503 # HACK: temporary solution to getting custom code filename from wsdlag file.
504 import activegrid.server.deployment as deploymentlib
505
506 appInfo = self._GetDoc().GetAppInfo()
507
508 if appInfo.language == None:
509 language = deploymentlib.LANGUAGE_DEFAULT
510 else:
511 language = appInfo.language
512
513 if language == deploymentlib.LANGUAGE_PYTHON:
514 suffix = ".py"
515 elif language == deploymentlib.LANGUAGE_PHP:
516 suffix = ".php"
517 pyFilename = self.name + suffix
518 return self._GetDoc().GetAppDocMgr().fullPath(pyFilename)
519
520
521 #----------------------------------------------------------------------------
522 # Old Classes
523 #----------------------------------------------------------------------------
524
525 class Project_10:
526 """ Version 1.0, kept for upgrading to latest version. Over time, this should be deprecated. """
527 __xmlname__ = "project"
528 __xmlrename__ = { "_files":"files"}
529 __xmlexclude__ = ('fileName',)
530 __xmlattributes__ = ["version"]
531
532
533 def __init__(self):
534 self.version = PROJECT_VERSION_050730
535 self._files = []
536
537
538 def initialize(self):
539 """ Required method for xmlmarshaller """
540 pass
541
542
543 def upgradeVersion(self):
544 currModel = Project()
545 for file in self._files:
546 currModel._files.append(ProjectFile(file))
547 return currModel
548
549