Editing Requirements format with P4C

Hello,
I have created some requirements in my model and I was thinking if it was possible to modify the requirement block format (the colour for instance) depending on the value of an attribute of the same requirement.
Being more specific I would like to know if it is possible to automatically set the colour green to the requiremnt block if a boolean requirement attribute “verification” is set “true”, and red if the same attribute is set “false”. Connecting in this way the value of an attribute and the req format so that the different colours could be visible from a diagram.
My main focus is in changing the requiremnt block format with Python4Capella because once I am able to do that it will be possible to modify the format depending also on other values.
I am opening this topic beacuse it seems that a function that does something like “set_colour(req)” doesn’t exist and I do not if it possible to create it.
Thanks for any help,
Davide

This thread should give you some hints on how to do it:

Thank you for the answer,
actually I already tried that script with Requirement elements and it works for retrieving the color but doesn’t work for changing it, the functions “setColor” or “setStrokeColor” seem not to exist and I get this error in the console:

org.eclipse.ease.ScriptExecutionException: Traceback (most recent call last):
  File "workspace://test_1/test_8.py", line 45, in <module>
  File "C:\Users\Utente\Desktop\capella test 2\capella\plugins\py4j-python_0.10.9.5-bnd-2odeag\src\py4j\java_gateway.py", line 1321, in __call__
    return_value = get_return_value(
  File "C:\Users\Utente\Desktop\capella test 2\capella\plugins\py4j-python_0.10.9.5-bnd-2odeag\src\py4j\protocol.py", line 330, in get_return_value
    raise Py4JError(
py4j.protocol.Py4JError: An error occurred while calling o10013.setColor. Trace:
py4j.Py4JException: Method setColor([class org.eclipse.sirius.viewpoint.RGBValues]) does not exist
	at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318)
	at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:326)
	at py4j.Gateway.invoke(Gateway.java:274)
	at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
	at py4j.commands.CallCommand.execute(CallCommand.java:79)
	at py4j.ClientServerConnection.sendCommand(ClientServerConnection.java:244)
	at py4j.CallbackClient.sendCommand(CallbackClient.java:384)
	at py4j.CallbackClient.sendCommand(CallbackClient.java:356)
	at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:106)
	at jdk.proxy15/jdk.proxy15.$Proxy28.executeScript(Unknown Source)
	at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.internalExecute(Py4jScriptEngine.java:240)
	at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.execute(Py4jScriptEngine.java:227)
	at org.eclipse.ease.AbstractScriptEngine.inject(AbstractScriptEngine.java:189)
	at org.eclipse.ease.AbstractScriptEngine.run(AbstractScriptEngine.java:242)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

Line 45 is “ElementStyle.setColor(color)” in your script

Yes, this code is “too simple” as you can have different types of elements in a diagram (nodes, edges…), and depending on the type, you may use different methods for setting the color. This is beyond my knowledge and in the end, this type of code should be provided by the Python4Capella API so that you do not have to struggle with this.

Try your script on a diagram that has only nodes, it should work.

Moreover, I don’t believe we should be using these setColor methods as they are gone when you refresh the diagram. If you want to keep the colors when a diagram is refreshed, then we should add some custom features to the element style I think, but again this is beyond my knowledge.

Stephane

You will need to use a Java static method:

# you can ignore the PyDev error not recognizing "org" 
color = org.eclipse.sirius.viewpoint.RGBValues.create(50, 50, 50)
print("(" + str(color.getRed()) + ", " + str(color.getGreen()) + ", " + str(color.getBlue()) + ")")

Then you can set the variable color to the graphical element. For instance on an EdgeStyle:

myEdgeStyle.setStrokeColor(color)

What about if this is not an Edge but a Node style?

The NodeStyle class is abstract but there is a list of other places you could set a color:

NodeStyle:

myDot.setBackgroundColor(color)
myEllipse.setColor(color)
myLozenge.setColor(color)
myNote.setColor(color)
mySquare.setColor(color)

Others:

myBorderedStyle.setBorderColor(color)
myBundledImage.setBorderColor(color)
myFlatContainerStyle.setBackgroundColor(color)
myFlatContainerStyle.setForegroundColor(color)
myGaugeSection.setBackgroundColor(color)
myGaugeSection.setForegroundColor(color)
myShapeContainerStyle.setBackgroundColor(color)
myBasicLabelStyle.setLabelColor(color)

This should cover most cases.

I tried in this way as suggested by @YvanLussaud but I still have an error printed out
Script:

# include needed for the Capella modeller API
include('workspace://Python4Capella/simplified_api/capella.py')
if False:
    from simplified_api.capella import *
    
# include needed for the PVMT API
include('workspace://Python4Capella/simplified_api/pvmt.py')
if False:
    from simplified_api.pvmt import *
    
# include needed for utilities
include('workspace://Python4Capella/utilities/CapellaPlatform.py')
if False:
    from utilities.CapellaPlatform import *

# include needed for the requirement API
include('workspace://Python4Capella/simplified_api/requirement.py')
if False:
    from simplified_api.requirement import *

aird_path = '/TMS_test_6/TMS_test_5.aird'

model = CapellaModel()
model.open(aird_path)
se = model.get_system_engineering()

#(hardcoded) gets a DRepresentation Descriptor for the first diagram of the first function....
diagram = se.get_all_contents_by_type(Requirement)[1].get_representing_diagrams()[0]
#gets the representation
representation = diagram.get_java_object().getRepresentation()

model.start_transaction()
try:

    for repElements in representation.getRepresentationElements():
        #Gets its style# 
        ElementStyle = repElements.getOwnedStyle()
        # you can ignore the PyDev error not recognizing "org" 
        color = org.eclipse.sirius.viewpoint.RGBValues.create(50, 50, 50)
        print("(" + str(color.getRed()) + ", " + str(color.getGreen()) + ", " + str(color.getBlue()) + ")")
        ElementStyle.setStrokeColor(color)      
except:
    # if something went wrong we rollback the transaction
    model.rollback_transaction()
    raise
else:
    # if everything is ok we commit the transaction
    model.commit_transaction()
 
model.save()

Error:

org.eclipse.ease.ScriptExecutionException: Traceback (most recent call last):
  File "workspace://test_1/test_8.py", line 48, in <module>
    # Python 3.*
  File "C:\Users\Utente\Desktop\capella test 2\capella\plugins\py4j-python_0.10.9.5-bnd-2odeag\src\py4j\java_gateway.py", line 1321, in __call__
    return_value = get_return_value(
  File "C:\Users\Utente\Desktop\capella test 2\capella\plugins\py4j-python_0.10.9.5-bnd-2odeag\src\py4j\protocol.py", line 330, in get_return_value
    raise Py4JError(
py4j.protocol.Py4JError: An error occurred while calling o10091.setStrokeColor. Trace:
py4j.Py4JException: Method setStrokeColor([class org.eclipse.sirius.viewpoint.RGBValues]) does not exist
	at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:318)
	at py4j.reflection.ReflectionEngine.getMethod(ReflectionEngine.java:326)
	at py4j.Gateway.invoke(Gateway.java:274)
	at py4j.commands.AbstractCommand.invokeMethod(AbstractCommand.java:132)
	at py4j.commands.CallCommand.execute(CallCommand.java:79)
	at py4j.ClientServerConnection.sendCommand(ClientServerConnection.java:244)
	at py4j.CallbackClient.sendCommand(CallbackClient.java:384)
	at py4j.CallbackClient.sendCommand(CallbackClient.java:356)
	at py4j.reflection.PythonProxyHandler.invoke(PythonProxyHandler.java:106)
	at jdk.proxy13/jdk.proxy13.$Proxy26.executeScript(Unknown Source)
	at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.internalExecute(Py4jScriptEngine.java:240)
	at org.eclipse.ease.lang.python.py4j.internal.Py4jScriptEngine.execute(Py4jScriptEngine.java:227)
	at org.eclipse.ease.AbstractScriptEngine.inject(AbstractScriptEngine.java:189)
	at org.eclipse.ease.AbstractScriptEngine.run(AbstractScriptEngine.java:242)
	at org.eclipse.core.internal.jobs.Worker.run(Worker.java:63)

The elements whose colour I want to change are these requirements allocated in this way:

Maybe it is not feasible but anyway I thought it was worth asking for help

Here you are getting any style from your diagram for instance Dot, BorderedStyle, … But only EdgeStyle has the method setStrokeColor(), so you need to filter on this type before calling the setStrokeColor() method:

        elementStyle = repElements.getOwnedStyle()
        if get_e_classifier("http://www.eclipse.org/sirius/diagram/1.1.0", "EdgeStyle").isInstance(elementStyle):
           color = org.eclipse.sirius.viewpoint.RGBValues.create(50, 50, 50)
           elementStyle.setStrokeColor(color)

If you need to filter only edges you want to change, you can check if the diagram element is a DEdge:

        if get_e_classifier("http://www.eclipse.org/sirius/diagram/1.1.0", "DEdge").isInstance(repElements):
           elementStyle = repElements.getOwnedStyle()
           color = org.eclipse.sirius.viewpoint.RGBValues.create(50, 50, 50)
           elementStyle.setStrokeColor(color)

Then you can call repElements.getSourceNode() and repElements.getTargetNode() to check if you need to customize this edge. You can have a look at the Java API from Sirius here. You can open the ecore file in your Capella.

PS: repElements should probably be called repElement.