1 # -*- coding: utf-8 -*-
3 # Copyright (C) 2007-2009 EDF R&D
5 # This file is part of PAL_SRC.
7 # PAL_SRC is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 2 of the License, or
10 # (at your option) any later version.
12 # PAL_SRC 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
15 # GNU General Public License for more details.
17 # You should have received a copy of the GNU General Public License
18 # along with PAL_SRC; if not, write to the Free Software
19 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 This module provides a new class :class:`StudyEditor` to complement
23 :class:`Study` and :class:`StudyBuilder` classes.
30 _DEFAULT_CONTAINER = "FactoryServer"
32 def getActiveStudyId():
34 Return the ID of the active study. In GUI mode, this function is equivalent
35 to ``salome.sg.getActiveStudyId()``. Outside GUI, it returns
36 ``salome.myStudyId`` variable.
39 if salome.hasDesktop():
40 return salome.sg.getActiveStudyId()
42 return salome.myStudyId
44 def getStudyEditor(studyId = None):
46 Return a :class:`StudyEditor` instance to edit the study with ID
47 `studyId`. If `studyId` is :const:`None`, return an editor for the current
51 studyId = getActiveStudyId()
52 if not _editors.has_key(studyId):
53 _editors[studyId] = StudyEditor(studyId)
54 return _editors[studyId]
59 This class provides utility methods to complement :class:`Study` and
60 :class:`StudyBuilder` classes. Those methods may be moved in those classes
61 in the future. The parameter `studyId` defines the ID of the study to
62 edit. If it is :const:`None`, the edited study will be the current study.
63 The preferred way to get a StudyEditor object is through the method
64 :meth:`getStudyEditor` which allows to reuse existing instances.
66 .. attribute:: studyId
68 This instance attribute contains the ID of the edited study. This
69 attribute should not be modified.
73 This instance attribute contains the underlying :class:`Study` object.
74 It can be used to access the study but the attribute itself should not
77 .. attribute:: builder
79 This instance attribute contains the underlying :class:`StudyBuilder`
80 object. It can be used to edit the study but the attribute itself
81 should not be modified.
84 def __init__(self, studyId = None):
87 studyId = getActiveStudyId()
88 self.studyId = studyId
89 self.study = salome.myStudyManager.GetStudyByID(studyId)
90 if self.study is None:
91 raise Exception("Can't create StudyEditor object: "
92 "Study %d doesn't exist" % studyId)
93 self.builder = self.study.NewBuilder()
95 def findOrCreateComponent(self, engineName, componentName = None,
96 icon = None, loadEngine = True,
97 containerName = _DEFAULT_CONTAINER):
99 Find a component corresponding to the engine named `engineName` in the
100 study, or create it if none is found. Then eventually load the
101 corresponding engine and the CORBA objects of this component.
103 :type engineName: string
104 :param engineName: name of the engine corresponding to the component.
106 :type componentName: string
107 :param componentName: name of the new component if created. If
108 :const:`None`, use `engineName` instead.
111 :param icon: icon for the new component (attribute "AttributePixMap").
113 :type loadEngine: boolean
114 :param loadEngine: If :const:`True`, find or load the corresponding
115 engine and associate it with the component.
117 :type containerName: string
118 :param containerName: name of the container in which the component
121 :return: the SComponent found or created.
124 sComponent = self.study.FindComponent(engineName)
125 if sComponent is None:
126 sComponent = self.builder.NewComponent(engineName)
127 if componentName is None:
128 componentName = engineName
129 self.builder.SetName(sComponent, componentName)
132 self.setIcon(sComponent, icon)
135 self.loadComponentEngine(sComponent, containerName)
139 def loadComponentEngine(self, sComponent,
140 containerName = _DEFAULT_CONTAINER):
142 Load the engine corresponding to `sComponent` in the container
143 `containerName`, associate the engine with the component and load the
144 CORBA objects of this component in the study.
146 engine = salome.lcc.FindOrLoadComponent(containerName,
147 sComponent.GetComment())
148 self.builder.LoadWith(sComponent, engine)
150 def getOrLoadObject(self, item):
152 Get the CORBA object associated with the SObject `item`, eventually by
153 first loading it with the corresponding engine.
155 object = item.GetObject()
156 if object is None: # the engine has not been loaded yet
157 sComponent = item.GetFatherComponent()
158 self.loadComponentEngine(sComponent)
159 object = item.GetObject()
162 def findOrCreateItem(self, fatherItem, name, fileType = None,
163 fileName = None, comment = None, icon = None,
164 IOR = None, typeId = None):
166 Find an object under `fatherItem` in the study with the given
167 attributes. Return the first one found if at least one exists,
168 otherwise create a new one with the given attributes and return it.
170 See :meth:`setItem` for the description of the parameters.
172 sObject = self.findItem(fatherItem, name, fileType, fileName, comment,
175 sObject = self.createItem(fatherItem, name, fileType, fileName,
176 comment, icon, IOR, typeId)
179 def findItem(self, fatherItem, name = None, fileType = None,
180 fileName = None, comment = None, icon = None, IOR = None,
183 Find an item with given attributes under `fatherItem` in the study. If
184 none is found, return :const:`None`. If several items correspond to
185 the parameters, only the first one is returned. The search is made
186 only on given parameters (i.e. not :const:`None`). To look explicitly
187 for an empty attribute, use an empty string in the corresponding
190 See :meth:`setItem` for the description of the parameters.
193 childIterator = self.study.NewChildIterator(fatherItem)
194 while childIterator.More() and foundItem is None:
195 childItem = childIterator.Value()
197 (name is None or childItem.GetName() == name) and \
198 (fileType is None or \
199 self.getFileType(childItem) == fileType) and \
200 (fileName is None or \
201 self.getFileName(childItem) == fileName) and \
202 (comment is None or childItem.GetComment() == comment) and \
204 self.getIcon(childItem) == icon) and \
205 (IOR is None or childItem.GetIOR() == IOR and \
207 self.getTypeId(childItem) == typeId)):
208 foundItem = childItem
212 def createItem(self, fatherItem, name, fileType = None, fileName = None,
213 comment = None, icon = None, IOR = None, typeId = None):
215 Create a new object named `name` under `fatherItem` in the study, with
216 the given attributes. If an object named `name` already exists under
217 the father object, the new object is created with a new name `name_X`
218 where X is the first available index.
220 :type fatherItem: SObject
221 :param fatherItem: item under which the new item will be added.
223 :return: new SObject created in the study
225 See :meth:`setItem` for the description of the other parameters.
227 aSObject = self.builder.NewObject(fatherItem)
229 aChildIterator = self.study.NewChildIterator(fatherItem)
233 anIdRE = re.compile("^" + aDelim + "[0-9]+")
234 aNameRE = re.compile("^" + name)
235 while aChildIterator.More():
236 aSObj = aChildIterator.Value()
237 aChildIterator.Next()
238 aName = aSObj.GetName()
239 if re.match(aNameRE,aName):
240 aTmp = aName[aLength:]
241 if re.match(anIdRE,aTmp):
243 anId = string.atol(aTmp[1:])
257 aName = aName + aDelim + str(aMaxId)
260 self.setItem(aSObject, aName, fileType, fileName, comment, icon,
265 def setItem(self, item, name = None, fileType = None, fileName = None,
266 comment = None, icon = None, IOR = None, typeId = None):
268 Modify the attributes of an item in the study. Unspecified attributes
269 (i.e. those set to :const:`None`) are left unchanged.
272 :param item: item to modify.
275 :param name: item name (attribute 'AttributeName').
277 :type fileType: string
278 :param fileType: item file type (attribute 'AttributeFileType').
280 :type fileName: string
281 :param fileName: item file name (attribute
282 'AttributeExternalFileDef').
284 :type comment: string
285 :param comment: item comment (attribute 'AttributeComment'). Note that
286 this attribute will appear in the 'Value' column in
290 :param icon: item icon name (attribute 'AttributePixMap').
293 :param IOR: IOR of a CORBA object associated with the item
294 (attribute 'AttributeIOR').
296 :type typeId: integer
297 :param typeId: item type (attribute 'AttributeLocalID').
299 #print "setItem (ID=%s): name=%s, fileType=%s, fileName=%s, comment=%s, icon=%s, IOR=%s" % (item.GetID(), name, fileType, fileName, comment, icon, IOR)
300 # Explicit cast is necessary for unicode to string conversion
302 self.builder.SetName(item, str(name))
303 if fileType is not None:
304 self.setFileType(item, fileType)
305 if fileName is not None:
306 self.setFileName(item, fileName)
307 if comment is not None:
308 self.builder.SetComment(item, str(comment))
310 self.setIcon(item, icon)
312 self.builder.SetIOR(item, str(IOR))
313 if typeId is not None:
314 self.setTypeId(item, typeId)
316 def removeItem(self, item, withChildren = False ):
318 Remove the given item from the study (the item still is in
319 the study after the removal)
320 @param item: the browser object to be removed
321 @param withChildren: remove children if True
326 self.builder.RemoveObjectWithChildren(item)
328 self.builder.RemoveObject(item)
335 def setItemAtTag(self, fatherItem, tag, name = None, fileType = None,
336 fileName = None, comment = None, icon = None, IOR = None,
339 Find an item tagged `tag` under `fatherItem` in the study tree or
340 create it if there is none, then set its attributes.
342 :type fatherItem: SObject
343 :param fatherItem: item under which the tagged item will be looked for
344 and eventually created.
347 :param tag: tag of the item to look for.
349 :return: the SObject at `tag` if found or created successfully, or
350 :const:`None` if an error happened.
352 See :meth:`setItem` for the description of the other parameters.
354 found, sObj = fatherItem.FindSubObject(tag)
356 sObj = self.builder.NewObjectToTag(fatherItem, tag)
357 self.setItem(sObj, name, fileType, fileName, comment, icon,
361 def getAttributeValue(self, sObject, attributeName, default = None):
363 Return the value of the attribute named `attributeName` on the object
364 `sObject`, or `default` if the attribute doesn't exist.
367 found, attr = self.builder.FindAttribute(sObject, attributeName)
372 def setAttributeValue(self, sObject, attributeName, attributeValue):
374 Set the value of the attribute named `attributeName` on the object
375 `sObject` to the value `attributeValue`.
377 attr = self.builder.FindOrCreateAttribute(sObject, attributeName)
378 attr.SetValue(attributeValue)
380 def getTypeId(self, sObject):
382 Return the value of the attribute "AttributeLocalID" of the object
383 `sObject`, or :const:`None` if it is not set.
385 return self.getAttributeValue(sObject, "AttributeLocalID")
387 def setTypeId(self, sObject, value):
389 Set the attribute "AttributeLocalID" of the object `sObject` to the
392 self.setAttributeValue(sObject, "AttributeLocalID", value)
394 def getFileType(self, sObject):
396 Return the value of the attribute "AttributeFileType" of the object
397 `sObject`, or an empty string if it is not set.
399 return self.getAttributeValue(sObject, "AttributeFileType", "")
401 def setFileType(self, sObject, value):
403 Set the attribute "AttributeFileType" of the object `sObject` to the
406 # Explicit cast is necessary for unicode to string conversion
407 self.setAttributeValue(sObject, "AttributeFileType", str(value))
409 def getFileName(self, sObject):
411 Return the value of the attribute "AttributeExternalFileDef" of the
412 object `sObject`, or an empty string if it is not set.
414 return self.getAttributeValue(sObject, "AttributeExternalFileDef", "")
416 def setFileName(self, sObject, value):
418 Set the attribute "AttributeExternalFileDef" of the object `sObject`
419 to the value `value`.
421 # Explicit cast is necessary for unicode to string conversion
422 self.setAttributeValue(sObject, "AttributeExternalFileDef",
425 def getIcon(self, sObject):
427 Return the value of the attribute "AttributePixMap" of the object
428 `sObject`, or an empty string if it is not set.
431 found, attr = self.builder.FindAttribute(sObject, "AttributePixMap")
432 if found and attr.HasPixMap():
433 value = attr.GetPixMap()
436 def setIcon(self, sObject, value):
438 Set the attribute "AttributePixMap" of the object `sObject` to the
441 attr = self.builder.FindOrCreateAttribute(sObject, "AttributePixMap")
442 # Explicit cast is necessary for unicode to string conversion
443 attr.SetPixMap(str(value))