Sparx Systems Forum
Enterprise Architect => Automation Interface, Add-Ins and Tools => Topic started by: Viking on June 11, 2020, 01:54:00 am
-
Hello,
I want to move an EmbeddedElement from one Element (“Old Element”) to another (“New Element”). In an object-oriented way I would have added the already existing EmbeddedElement to the EmbeddedElements of the New Element. But there is only a AddNew method without ID or object. So AddNew creates a new EmbeddedElement (although it is already there) and I replace the ID with the ID of the existing EmbeddedElement. Is that correct or is there a better way?
V.
-
I found this thread: https://sparxsystems.com/forums/smf/index.php?topic=3960.0
Seams that I have to set a ParentID instead of an ElementID. I will try.
-
Hello,
AddNew() creates a new object and adds it to a Collection. The Collection acts as a factory. So calling AddNew() in order to move something is wrong.
All model constituent classes in the API have an attribute specifying their owner, eg Package.ParentID, Attribute.ParentID, TaggedValue.ElementID.
In order to move anything from one Collection to another, you don't manipulate the Collections, but change the owner reference in the object you want to move.
So simply change the EmbeddedElement.ParentID from OldElement.ElementID to NewElement.ElementID, then call EmbeddedElement.Update() to write the changes to the database.
Note that the EA API will not automatically update any references. So after you've made the change, your OldElement.EmbeddedElements and NewElement.EmbeddedElements are both out of sync and need to be .Refresh()ed.
HTH,
/Uffe
-
Hello,
AddNew() creates a new object and adds it to a Collection. The Collection acts as a factory. So calling AddNew() in order to move something is wrong.
All model constituent classes in the API have an attribute specifying their owner, eg Package.ParentID, Attribute.ParentID, TaggedValue.ElementID.
In order to move anything from one Collection to another, you don't manipulate the Collections, but change the owner reference in the object you want to move.
So simply change the EmbeddedElement.ParentID from OldElement.ElementID to NewElement.ElementID, then call EmbeddedElement.Update() to write the changes to the database.
Note that the EA API will not automatically update any references. So after you've made the change, your OldElement.EmbeddedElements and NewElement.EmbeddedElements are both out of sync and need to be .Refresh()ed.
HTH, /Uffe
Many thanks, @Uffe.
I do not have to move the realtionships, right?
-
No, you don't. Connectors are bound to elements, irrelevant where they are (whether under a package or another element).
q.
-
No, you don't. Connectors are bound to elements, irrelevant where they are (whether under a package or another element).
q.
Many thanks @Uffe and @Qwerty. It works :-)
But now another question: I moved the Element to another place on the Diagram by script. The EmbeddedElement does not move. But when I move the Element by hand, the EmbeddedElement moves to its Element. I updated the diagram, reloaded it, updated the diagramobjects, etc.
Do i have to move the EmbeddedElement as well?
-
Yes, you'll have to move the embedded element as well.
Geert
-
Yes, you'll have to move the embedded element as well.
Geert
Curiously it does know its position. Why does the EmbeddedElement move to the correct position when I change the diagram by hand, but it does absolutly not via script. Is it a bug or a feature?
-
Well, by hand it goes to the hand coded part of EA that makes these things. When you use the automation you have to care for them by yourself. Looks harder, but you can make funny things via automation you can't do manually.
q.
-
Well, by hand it goes to the hand coded part of EA that makes these things. When you use the automation you have to care for them by yourself. Looks harder, but you can make funny things via automation you can't do manually.
q.
Yes, maybe. But it takes some programming effort to move the EmbeddedElements accordingly.
Many thanks to @Uffe, @Geert and @qwerty.
-
It might be worth sending in a feature request to ask that the diagram refresh function (in the GUI) should check for embedded elements which are outside of their parent.
/U
-
Hi,
I want to move a DiagramObject to another place on the diagram. Die Code changes the left-coordinate from 603 to 229, which is fine. But after Update(), it changes the coordinate again (to 513). I did this often, but not with EmbeddedElements. Is Update() to a DiagramObject wrong? But I use that often for DiagramObjects. What is wrong? V.
Debug.WriteLine("Element.Name: " + EmbeddedElement.Name + " " + ElementDiagramObject.left); // which is 603
moveHorizonal = 374;
ElementDiagramObject.left = ElementDiagramObject.left - moveHorizonal;
Debug.WriteLine("ElementOfNewElement.Name: " + EmbeddedElement.Name + " " + ElementDiagramObject.left); // 229
ElementDiagramObject.Update();
Debug.WriteLine("ElementOfNewElement.Name: " + EmbeddedElement.Name + " " + ElementDiagramObject.left); // now 513
-
It's basically correct. IIRC when moving embedded elements you need to calculate exactly (!) the border position. Else EA will do some "auto-correct".
q.
-
It's basically correct. IIRC when moving embedded elements you need to calculate exactly (!) the border position. Else EA will do some "auto-correct". q.
Many thanks, qwerty. I will try.
Do you know, if both borders need to have to same coordinates. Currently I position the Embedded Element in analogy to the old position.
-
Sorry, I don't remember (too long ago). Anyhow, you just need to experiment with one horizontal and one veritcal edge of the outer element. Best you move a port manually and look which coordinates EA gives it in comparison to its embedding element. IIRC a port has 15x15 size and so you have a 7 offset. No idea how to cope with ports that have adjustable size.
q.
-
Sorry, I don't remember (too long ago). Anyhow, you just need to experiment with one horizontal and one veritcal edge of the outer element. Best you move a port manually and look which coordinates EA gives it in comparison to its embedding element. IIRC a port has 15x15 size and so you have a 7 offset. No idea how to cope with ports that have adjustable size. q.
Size 15x15 is correct.
Do I need to change only one coordinate of the port or all 4 (I struggle with both variants) ?
-
You need to calculate BL BR TL TR for the port. Depending on which parent edge you have to add/sub 7. Just look into what a sample port shows. Not too difficult to have a look, is it?
q.
-
You need to calculate BL BR TL TR for the port. Depending on which parent edge you have to add/sub 7. Just look into what a sample port shows. Not too difficult to have a look, is it? q.
No, its not. I calculated all cordinates. I retieved the wrong coordinates for any reason :(
-
You need to calculate BL BR TL TR for the port. Depending on which parent edge you have to add/sub 7. Just look into what a sample port shows. Not too difficult to have a look, is it? q.
I did the following:
Element (parent) new position: l: 146 r: 236 t: -193 b: -263
(Port old position l: 603 r: 618 t: -215 b: -230)
Port new position l: 229 r: 244 t: -215 b: -230
Port r – l = 15 (correct)
Port b – t = 15 (correct)
Port l - Element r = -7 (correct)
Port r - Element r = 7 8 (correct)
EA OM changes only Port l and r and keeps t and b. What's wrong?
-
244 - 236 = 8
q.
-
244 - 236 = 8 q.
Shame on me :(
-
But it still does not work :(
-
You are giving me a hard time.
Orientation LRTB element and port to the right
E: 210 310 -190 -270
P: 303 318 -230 -245
-> port L 303 = element R 310 - 7
port R 318 = element R 310 + 8
to the left
E: 210 310 -190 -270
P: 202 217 -230 -245
-> port L 202 = element L 210 - 8
port R 217 = element L 210 + 7
to the top
E: 210 310 -190 -270
P: 250 265 -183 -198
-> port T -183 = element T -190 + 7
port B -198 = element T -190 - 8
to the bottom
E: 210 310 -190 -270
P: 261 276 -263 -278
-> port T -263= element B -270 + 7
port B -278 = element T -270 - 8
So: to the inside 7 px and to the outside 8 px from the element edge.
q.
-
Hi, I am working on the same 'problem' so interested in this treat. I have a related question; how can you see that there are diagramObjects embedded inside another diagram object? That one object is the parent of another does not mean that they are visualized inside one another on the diagram. I would like to format my diagram automatically and if there are display objects inside display objects inside ... I have to calculate their size and position accordingly.
-
You are giving me a hard time.
I see. I am very sorry. Thank you very much for your incredible assistance !
But it still does not work. I even tried 15/2, which I saw in an implementation of Helmut Ortmann at github.
I reload the diagram before and afterwards. I update the DiagramObject. Everything which works normally does not work in this case.
-
@viking please show your code...
@Arnoud_B you need to retrieve the object via the id from the diagram object. Only there you can see which one is an embeeded one (via the element parent relation).
q.
-
"@Arnoud_B you need to retrieve the object via the id from the diagram object. Only there you can see which one is an embeeded one (via the element parent relation)."
Well that I figured out already but that is not enough; an element that is embedded as child in a parent can be perfectly be displayed next to its parent and not inside its parent. Only if you move it inside you cannot move it out anymore.
I want to be able to detect with a script if the diagram object of the child element is inside the diagram object of the parent element so I can make the parent diagram object larger.
-
Well, EA "usually" (but as EA is, not always) puts embedded elements inside or attached to their parents. Whether or not elements are graphically overlapping can only be detected by their position (top, left, bottom, right). That's quite simple geometry to use here. There is no attribute where you can detect that a diagram object is embedded or not (except via the parent relation of the underlying objects).
q.
-
Issue solved !
I had to save (Update()) the moved ParentElement BEFORE I can expect EA to recognize changes to it. Although the ParentElement (to which I wanted to attach the EmbeddedElemenet) has been moved on the Diagram successfully, EA had the old position in "memory".
Lessons learned are (maybe wrong) that Update saves changes to the in objects in memory (maybe also to the database). Otherwise they do not exist for further processing.
@qwerty, many thanks for your valuable support.
-
Well, EA "usually" (but as EA is, not always) puts embedded elements inside or attached to their parents. Whether or not elements are graphically overlapping can only be detected by their position (top, left, bottom, right). That's quite simple geometry to use here. There is no attribute where you can detect that a diagram object is embedded or not (except via the parent relation of the underlying objects).
Well I agree that the mathematics involved are not complex but it is quite some coding as you have to check ALL elements on the diagram to see if they are in the same position (a full table scan implemented in scripting code). Then I have to check if the items are simply in the same place (they have no parent/child) relation or they should actually be embedded on diagram level.
Well I have some coding to do, however a collection of embedded (child) Diagram objects on the (parent) diagram object just like the Element itself would make life easier for me :'(
-
Well, EA "usually" (but as EA is, not always) puts embedded elements inside or attached to their parents. Whether or not elements are graphically overlapping can only be detected by their position (top, left, bottom, right). That's quite simple geometry to use here. There is no attribute where you can detect that a diagram object is embedded or not (except via the parent relation of the underlying objects).
Well I agree that the mathematics involved are not complex but it is quite some coding as you have to check ALL elements on the diagram to see if they are in the same position (a full table scan implemented in scripting code). Then I have to check if the items are simply in the same place (they have no parent/child) relation or they should actually be embedded on diagram level.
Well I have some coding to do, however a collection of embedded (child) Diagram objects on the (parent) diagram object just like the Element itself would make life easier for me :'(
There are lots of things that could make our life easier. The API is a very thing layer on top of the database.
I ended up writing a whole framework in C# that gives me a more functional interface.
Geert
-
Same here. I always wonder what a wonderful tool EA could be if not every user had to do that frameworking but if Sparx had provided it already. Well, I guess I know the answer.
q.
-
Orientation LRTB element and port to the right
E: 210 310 -190 -270
P: 303 318 -230 -245
-> port L 303 = element R 310 - 7
port R 318 = element R 310 + 8
For completness and because it makes calculations easier. Just take the middle:
port L 303 = element R 310 - (15/2)
port R 318 = element R 310 + (15/2)
-
15/2 is an integer division. It yields 7 (I'd guess in all compilers). Don't know if that would be a way to go.
So did you get it to work?
q.
-
15/2 is an integer division. It yields 7 (I'd guess in all compilers). Don't know if that would be a way to go.
So did you get it to work? q.
Yes, see above.
I also mentioned the reason. The update-statement was at the wrong place.
I just added this information with "15/2" because than it does not need to be considered if it is 8 or 7.