Salome HOME
Merge branch 'V7_dev'
[modules/kernel.git] / src / KERNEL_PY / salome_study.py
1 #  -*- coding: iso-8859-1 -*-
2 # Copyright (C) 2007-2016  CEA/DEN, EDF R&D, OPEN CASCADE
3 #
4 # Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
5 # CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 #
7 # This library is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU Lesser General Public
9 # License as published by the Free Software Foundation; either
10 # version 2.1 of the License, or (at your option) any later version.
11 #
12 # This library is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 # Lesser General Public License for more details.
16 #
17 # You should have received a copy of the GNU Lesser General Public
18 # License along with this library; if not, write to the Free Software
19 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
20 #
21 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #
23
24 #  File   : salome_study.py
25 #  Author : Paul RASCLE, EDF
26 #  Module : SALOME
27 #  $Header$
28 #
29 import salome_kernel
30 import SALOMEDS
31 import salome_iapp
32 from launchConfigureParser import verbose
33
34 myStudyManager = None
35 myStudyId = None
36 myStudy = None
37 myStudyName = None
38
39 #--------------------------------------------------------------------------
40
41 def DumpComponent(Study, SO, Builder,offset):
42   it = Study.NewChildIterator(SO)
43   while it.More():
44     CSO = it.Value()
45     a=offset*"--" + ">" + CSO.GetID()
46     find,AtName = Builder.FindAttribute(CSO, "AttributeName")
47     if find:
48       a=a+":"+AtName.Value()
49     find,AtIOR = Builder.FindAttribute(CSO, "AttributeIOR")
50     if find:
51       a=a+":"+AtIOR.Value()
52     find,RefSO = CSO.ReferencedObject()
53     if find:
54       a=a+":"+RefSO.GetID()
55     print a
56     DumpComponent(Study, CSO, Builder,offset+2)
57     it.Next()
58
59 #--------------------------------------------------------------------------
60
61 def DumpStudy(Study):
62     """
63     Dump a study, given the ior
64     """
65     itcomp = Study.NewComponentIterator()
66     Builder = Study.NewBuilder()
67     while itcomp.More():
68       SC = itcomp.Value()
69       name = SC.ComponentDataType()
70       print "-> ComponentDataType is " + name
71       DumpComponent(Study, SC,Builder, 1)
72       itcomp.Next()
73
74 def DumpStudies():
75   """
76     Dump all studies in a StudyManager
77   """
78   global myStudyManager
79   for name in myStudyManager.GetOpenStudies():
80     s = myStudyManager.GetStudyByName(name)
81     print "study:",name, s._get_StudyId()
82     DumpStudy(s)
83
84
85 #--------------------------------------------------------------------------
86
87 def IDToObject(id):
88     global myStudy
89     myObj = None
90     mySO = myStudy.FindObjectID(id);
91     if mySO is not None:
92         ok, anAttr = mySO.FindAttribute("AttributeIOR")
93         if ok:
94             AtIOR = anAttr._narrow(SALOMEDS.AttributeIOR)
95             if AtIOR.Value() != "":
96                 myObj = orb.string_to_object(AtIOR.Value())
97     return myObj
98
99 def ObjectToSObject(obj):
100     mySO = None
101     if obj is not None:
102         ior =  orb.object_to_string(obj)
103         if ior != "":
104             mySO = myStudy.FindObjectIOR(ior)
105     return mySO
106
107 def ObjectToID(obj):
108     mySO = ObjectToSObject(obj)
109     if mySO:
110         return mySO.GetID()
111     return ""
112
113 def IDToSObject(id):
114     global myStudy
115     mySO = myStudy.FindObjectID(id);
116     return mySO
117
118     #--------------------------------------------------------------------------
119
120 def generateName(prefix = None):
121     import random;
122     int = random.randint(1,1000);
123     if prefix is None:
124         return "Study" + str(int)
125     else :
126         return prefix + str(int)
127
128     #--------------------------------------------------------------------------
129
130 def PersistentPresentation(theStudy, theSO, theWithID):
131     # put the sobject's content (with subchildren) to the string
132     aResult = ""
133     attrs = theSO.GetAllAttributes()
134     aLen = len(attrs)
135     anUncopied = 0
136     for a in range(0,aLen):
137         attr = attrs[a]
138         if isinstance(attr,SALOMEDS._objref_AttributeTreeNode):
139             anUncopied += 1
140         elif isinstance(attr,SALOMEDS._objref_AttributeTarget):
141             anUncopied += 1
142         elif isinstance(attr,SALOMEDS._objref_AttributeReal) or \
143              isinstance(attr,SALOMEDS._objref_AttributeInteger) or \
144              isinstance(attr,SALOMEDS._objref_AttributeName) or \
145              isinstance(attr,SALOMEDS._objref_AttributeComment) or \
146              isinstance(attr,SALOMEDS._objref_AttributePersistentRef) or \
147              isinstance(attr,SALOMEDS._objref_AttributeLocalID) or \
148              isinstance(attr,SALOMEDS._objref_AttributeUserID):
149             aResult += " attribute value: " + str(attr.Value())
150         elif isinstance(attr,SALOMEDS._objref_AttributeIOR):
151             aResult += " attribute: IOR"
152         elif isinstance(attr,SALOMEDS._objref_AttributeSequenceOfReal) or \
153              isinstance(attr,SALOMEDS._objref_AttributeSequenceOfInteger):
154             aResult += " Sequence: " + str(attr.CorbaSequence())
155         elif isinstance(attr,SALOMEDS._objref_AttributeDrawable):
156             aResult += " Drawable: " + str(attr.IsDrawable())
157         elif isinstance(attr,SALOMEDS._objref_AttributeSelectable):
158             aResult += " Selectable: " + str(attr.IsSelectable())
159         elif isinstance(attr,SALOMEDS._objref_AttributeExpandable):
160             aResult += " Expandable: " + str(attr.IsExpandable())
161         elif isinstance(attr,SALOMEDS._objref_AttributeOpened):
162             aResult += " Opened: " + str(attr.IsOpened())
163         elif isinstance(attr,SALOMEDS._objref_AttributeTextColor):
164             aResult += " TextColor: " + str(attr.TextColor())
165         elif isinstance(attr,SALOMEDS._objref_AttributeTextHighlightColor):
166             aResult += " TextHighlightColor: " + str(attr.TextHighlightColor())
167         elif isinstance(attr,SALOMEDS._objref_AttributePixMap):
168             aResult += " PixMap: " + str(attr.GetPixMap())
169         elif isinstance(attr,SALOMEDS._objref_AttributeTableOfInteger) or \
170              isinstance(attr,SALOMEDS._objref_AttributeTableOfReal):
171             aResult += " Table with title: " + attr.GetTitle()
172         elif isinstance(attr,SALOMEDS._objref_AttributePythonObject):
173             aResult += " PythonObject: " + attr.GetObject()
174
175     if theWithID:
176         aResult = "sobject: " + theSO.GetID() + " nbattrs: " + str(aLen - anUncopied) + aResult + '\n'
177     else:
178         aResult = " nbattrs: " + str(aLen - anUncopied) + aResult + '\n'
179     anIter = theStudy.NewChildIterator(theSO)
180     while anIter.More():
181         aResult += PersistentPresentation(theStudy, anIter.Value(), theWithID)
182         anIter.Next()
183     return aResult
184
185     #--------------------------------------------------------------------------
186
187 def GetTree(theSO):
188     # returns the document list tree (as list)
189     global myStudy
190     aResult = [theSO.GetID()]
191     anIter = myStudy.NewChildIterator(theSO)
192     while anIter.More():
193         aResult += GetTree(anIter.Value())
194         anIter.Next()
195     return aResult
196
197     #--------------------------------------------------------------------------
198
199 def CheckCopyPaste(theSO, theInfo ,theComponentPaste):
200     global myStudyManager, myStudy
201
202     aRoot = theSO
203     while aRoot.GetID() != "0:":
204         aRoot = aRoot.GetFather()
205     aTree = GetTree(aRoot)
206     aStudyPersist = PersistentPresentation(myStudy, aRoot, 1)
207
208     if not myStudyManager.CanCopy(theSO):
209         raise RuntimeError, "<CanCopy> for "+theInfo+" returns false"
210     
211     if not myStudyManager.Copy(theSO):
212         raise RuntimeError, "<Copy> for "+theInfo+" returns false"
213
214     
215     if not myStudyManager.CanPaste(theSO):
216         raise RuntimeError, "<CanPaste> for "+theInfo+" returns false"
217
218     # check: before paste study is not changed check
219     if aStudyPersist != PersistentPresentation(myStudy, aRoot, 1):
220         raise RuntimeError, "Study is changed before Paste calling for "+theInfo
221     
222     aSObj = theSO
223     if theComponentPaste:
224         aSObj = theSO.GetFatherComponent()
225         theInfo = theInfo + "(paste for component)"
226     if myStudyManager.Paste(aSObj) == None:
227         raise RuntimeError, "<Paste> for "+theInfo+" returns None object"
228     aNewTree = GetTree(aRoot)
229     aLen = len(aTree)
230     for a in range(0,aLen):
231         if aTree[a] != aNewTree[a]:
232             return myStudy.FindObjectID(aNewTree[a])
233         
234     if aLen < len(aNewTree):
235         return myStudy.FindObjectID(aNewTree[aLen])
236     
237     raise RuntimeError, "After Copy calling the tree is not changed"
238     
239     #--------------------------------------------------------------------------
240
241 def GetComponentVersion(theComponent, all_versions = False):
242     # returns the document list tree (as list)
243     global myStudy
244     props = myStudy.GetProperties()
245     stored_components = props.GetStoredComponents()
246     version = "no component data" # vsr: better raise an exception in this case?
247     if theComponent in stored_components:
248       if all_versions:
249         version = props.GetComponentVersions(theComponent)
250         for i in range(len(version)):
251           if not version[i]: version[i] = "unknown"
252           pass
253         pass
254       else:
255         version = props.GetComponentVersion(theComponent)
256         if not version: version = "unknown"
257         pass
258       pass
259     return version
260     
261     #--------------------------------------------------------------------------
262
263 def FindFileInDataDir(filename):
264     import os
265     datadir = os.getenv("DATA_DIR")
266     if datadir is not None:
267         import string
268         dirs = string.split(datadir, ":")
269         for dir in dirs:
270             file = dir + "/" + filename
271             if os.path.exists(file):
272                 return file;
273     datadir = os.getenv("KERNEL_ROOT_DIR") + "/examples/"
274     file = datadir + filename
275     if os.path.exists(file):
276         return file;
277
278     return None
279
280     #--------------------------------------------------------------------------
281
282 salome_study_ID = -1
283
284 # *args are used here to support backward compatibility
285 # previously it was possible to pass theStudyId parameter to this function
286 # which is no more supported.
287 def getActiveStudy(*args):
288     global myStudyManager
289     global salome_study_ID
290
291     if not myStudyManager:
292         print "No active study"
293         return None
294         pass
295
296     if verbose(): print "getActiveStudy"
297     if salome_study_ID == -1:
298         listOpenStudies = myStudyManager.GetOpenStudies()
299         if len(listOpenStudies) == 0:
300             return None
301         else:
302             s = myStudyManager.GetStudyByName(listOpenStudies[0])
303             salome_study_ID = s._get_StudyId()
304     if verbose(): print"--- Study Id ", salome_study_ID
305     return salome_study_ID
306
307     #--------------------------------------------------------------------------
308
309 def setCurrentStudy(theStudy):
310     """
311     Change current study : an existing one given by a study object.
312
313     :param theStudy: the study CORBA object to set as current study
314
315     Obsolete: only one study can be opened at the moment.
316     This function works properly if specified theStudy parameter
317     corresponds to the currently opened study.
318     Kept for backward compatibility only.
319     """
320     global myStudyId, myStudy, myStudyName
321     global salome_study_ID
322     myStudy = theStudy
323     myStudyId = theStudy._get_StudyId()
324     myStudyName = theStudy._get_Name()
325     return myStudyId, myStudy, myStudyName
326
327     #--------------------------------------------------------------------------
328
329 # *args are used here to support backward compatibility
330 # previously it was possible to pass theStudyId parameter to this function
331 # which is no more supported.
332 def setCurrentStudyId(*args):
333     """
334     Change current study : an existing or new one.
335
336     This function connects to the single opened study if there is any; otherwise
337     new empty study is created.
338
339     Obsolete: only one study can be opened at the moment.
340     Kept for backward compatibility only.
341     """
342     global myStudyManager, myStudyId, myStudy, myStudyName
343     global salome_study_ID
344     salome_study_ID = -1
345     myStudyId = getActiveStudy()
346     if not myStudyId:
347       myStudyId = createNewStudy()
348     if verbose(): print "myStudyId",myStudyId
349     myStudy = myStudyManager.GetStudyByID(myStudyId)
350     myStudyName = myStudy._get_Name()
351     return myStudyId, myStudy, myStudyName
352
353     #--------------------------------------------------------------------------
354
355 def createNewStudy():
356     global myStudyManager
357     print "createNewStudy"
358     aStudyName = "extStudy"
359     theStudy = myStudyManager.NewStudy(aStudyName)
360     theStudyId = theStudy._get_StudyId()
361     print aStudyName, theStudyId
362     return theStudyId
363
364     #--------------------------------------------------------------------------
365
366 def openStudy(theStudyPath):
367     global myStudyManager
368     print "openStudy"
369     theStudy = myStudyManager.Open(theStudyPath)
370     theStudyId = theStudy._get_StudyId()
371     print theStudyPath, theStudyId
372     return theStudyId
373
374     #--------------------------------------------------------------------------
375
376 def salome_study_init(theStudyPath=None):
377     """
378     Performs only once study creation or connection.
379     optional argument : theStudyPath
380         None        : attach to the currently active single study;
381                       create new empty study if there is active study
382         <URL> (str) : open study with the given file name
383     """
384     global myStudyManager, myStudyId, myStudy, myStudyName
385     global orb, lcc, naming_service, cm
386
387     if verbose(): print "theStudyPath:", theStudyPath
388     if not myStudyManager:
389         orb, lcc, naming_service, cm = salome_kernel.salome_kernel_init()
390
391         # get Study Manager reference
392         if verbose(): print "looking for studyManager ..."
393         obj = naming_service.Resolve('myStudyManager')
394         myStudyManager = obj._narrow(SALOMEDS.StudyManager)
395         if verbose(): print "studyManager found"
396         pass
397
398     # get active study Id, ref and name
399     myStudy = None
400     myStudyId = getActiveStudy()
401     if myStudyId == None :
402         import types
403         if theStudyPath and type(theStudyPath) == types.StringType:
404             myStudyId = openStudy(theStudyPath)
405         else:
406             myStudyId = createNewStudy()
407     if verbose(): print "myStudyId", myStudyId
408
409     if myStudy == None:
410         myStudy = myStudyManager.GetStudyByID(myStudyId)
411     myStudyName = myStudy._get_Name()
412
413     return myStudyManager, myStudyId, myStudy, myStudyName
414
415 def salome_study_close():
416     global salome_study_ID
417     global myStudyId, myStudy, myStudyName
418     salome_study_ID = -1
419     myStudyId, myStudy, myStudyName = None, None, None
420     pass