Author Topic: Simple click->copy Add-in  (Read 9744 times)

SiliconRancher

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Simple click->copy Add-in
« on: April 04, 2013, 07:33:11 am »
Hello,

I'm trying to write a simple add-in (with C#) that allows user to copy selected element with some modifications  pre-set in my add-in (e.g. with name change).

I'm totally new to EA (although with some experience in C#) and I have no idea how to enter into element's attributes, then change them and copy to new element.

As far as it goes I have only this:

 public void EA_MenuClick(EA.Repository Repository, string Location, string
        MenuName, string ItemName)
        {
            Object o = new Object();
            o = Repository.GetContextItem(out o);

        }

Poor, isn't it?

I've searched almost all the internet and didn't find a clue.

Thanks in advance for any help.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #1 on: April 04, 2013, 10:14:04 am »
If you're completely new to EA's API I can recommend my book Scripting EA. If you are deeper in the matters you should check out Geerts EA Navigator addin: http://bit.ly/Y1pCwT

q.

Geert Bellekens

  • EA Guru
  • *****
  • Posts: 13387
  • Karma: +566/-33
  • Make EA work for YOU!
    • View Profile
    • Enterprise Architect Consultant and Value Added Reseller
Re: Simple click->copy Add-in
« Reply #2 on: April 04, 2013, 05:50:09 pm »
Hmm, ok that is indeed a long way to go.
Now how to start... :-?

You now have an Object o, but I guess you really need an EA.Element. In that case you'll have to test if your o is of type EA.Element, and then cast it.
Something like:
Code: [Select]
if (o is EA.Element)
{
    EA.Element selectedElement = (EA.Element)o;
}

So that's better already, you now have selectedElement of type EA.Element.
Then you might want to create a new element to copy to.
I'm not sure anymore if there are any 'clone' operations available in the API, you might want to search the forum for it.
But if you would want to copy your element manually you need a package or other element to add the new element to.
Suppose you want to add the element to the same package then you would need to do something like:
Code: [Select]
EA.Package parentPackage = Repository.GetPackageByID(selectedElement.PackageID);
EA.Element elementCopy = parentPackage.Elements.AddNew(selectedElement.Name + "_copy", selectedElement.ObjectType);
That gives you a copy of the Element. Now you need to copy the properties you need to your copy element (think stereotype, state, phase,etc...)
And then you might want to copy the features such as attributes.
To do this you need to loop the existing attributes and create a new attribute for each one of them something like:
Code: [Select]
foreach (EA.Attribute attribute in selectedElement.Attributes)
{
  elementCopy.Attributes.AddNew(attribute.Name + "_copy", "Attribute);
}
And then of course don't forget to copy the other properties of your attributes.

I hope this helps. I have some more EA addin tutorials on my blog: http://geertbellekens.wordpress.com/ and a whole lot of example code on github: https://github.com/GeertBellekens/

Geert

PS. I haven't syntax checked the example code above, might not compile like that.

SiliconRancher

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #3 on: April 05, 2013, 08:10:06 am »
Thank you so much for your help, you make so much good work here; also your tutorials were the first (and yet only, except the documentation...) useful thing I found in the Internet aboud writing add-ins to EA.
I'm now able to copy my Element (particulary table, because this add-in is about tables), but still I can't copy attributes.

Now my copy method looks like this:
Code: [Select]
private void copyIt(EA.Repository Repository, EA.Diagram diagram)
        {
            Object o = new Object();
            Repository.GetContextItem(out o).ToString();
          
           if (o is EA.Element)
            {
                EA.Element selectedElement = (EA.Element)o;
                if (selectedElement.Stereotype == "table")
                {
                    
                    EA.Package parentPackage = Repository.GetPackageByID(selectedElement.PackageID);
                      EA.Element elementCopy = parentPackage.Elements.AddNew(selectedElement.Name.ToString() + "_copy",selectedElement.Type.ToString());
                  


                    MessageBox.Show(selectedElement.Properties.Count.ToString() + selectedElement.Methods.Count.ToString());
// element that I try to copy has 2 properties and 3 methods; also 3 attributes - table columns
                    elementCopy.Status = selectedElement.Status;
                    elementCopy.Phase = selectedElement.Phase;
                    elementCopy.Stereotype = selectedElement.Stereotype;
                    elementCopy.MetaType = selectedElement.MetaType;
                    elementCopy.Notes = selectedElement.Notes;
                  
                    

                      foreach (EA.Attribute attribute in selectedElement.Attributes)
                      {
                          
                          
                          elementCopy.Attributes.AddNew(attribute.Name + "_copy", "Attribute");
                          
                      }
                      MessageBox.Show(elementCopy.Attributes.Count.ToString() + " " + selectedElement.Attributes.Count.ToString());
// new element doesn't get any new attributes
                      foreach (EA.Method method in selectedElement.Methods)
                      {
                          elementCopy.Methods.AddNew(method.Name + "_copy", "Method");
                          MessageBox.Show(elementCopy.Methods.Count.ToString());
// the same is true for methods
                      }
                      
                      foreach (EA.CustomProperty customProperty in selectedElement.CustomProperties)
                      {
                          elementCopy.CustomProperties.AddNew(customProperty.Name + "_copy", "CustomProperty");
                          
                      }
                    
                      elementCopy.Update();
                      Repository.RefreshModelView(parentPackage.PackageID);
                      diagram.Update();
                    
                }
                else
                {
                   MessageBox.Show("That's not a table, that's "+selectedElement.Stereotype);
                }
            }
            else
            {
                MessageBox.Show("That's not Element, that's "+o.GetType().ToString());
            }    
            
          
        }


Quote
If you're completely new to EA's API I can recommend my book Scripting EA. If you are deeper in the matters you should check out Geerts EA Navigator addin: http://bit.ly/Y1pCwT
Someday I propably will, but not yet, I'm not even sure if I'll use EA anymore (that strongly depends of this particular add-in to be honest) :)
« Last Edit: April 05, 2013, 08:11:50 am by SiliconRancher »

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #4 on: April 05, 2013, 09:02:42 am »
You need to call Update after the addnew. Further the 2nd parameter is taken as Type of the attr. I guess it should not be "Attribute" but rather blank or "int" or something.

q.
« Last Edit: April 05, 2013, 09:04:42 am by qwerty »

SiliconRancher

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #5 on: April 09, 2013, 04:37:55 am »
I added update and refresh, but it's not the case :( And I think it's not about the type of the attribute. I tried e.g. this:

Code: [Select]
foreach (EA.Attribute attribute in selectedElement.Attributes)
                      {
elementCopy.Attributes.AddNew(attribute.Name + "_copy", attribute.Type);                          
                          elementCopy.Attributes.Refresh();
                          elementCopy.Update();  
                      }
I even tried doing it in ulgy way:
Code: [Select]
elementCopy = selectedElement;But it didn't get me anywhere. I also thought that I sholud get "inside" each attribute:

Code: [Select]
short i = 0;
                      foreach (EA.Attribute att in elementCopy.Attributes)
                      {
                          att.Type = selectedElement.Attributes.GetAt(i).Type;
                          att.Style = selectedElement.Attributes.GetAt(i).Style;
                          att.Stereotype = selectedElement.Attributes.GetAt(i).Stereotype;
                          att.Containment = selectedElement.Attributes.GetAt(i).Containment;
                          att.Container = selectedElement.Attributes.GetAt(i).Container;
                          
                          elementCopy.Attributes.Refresh();
                          elementCopy.Update();
                          i++;
                      }
But it also was pointless. I can't copy columns of my original element (table), maybe it's just not possible to do it this way? So maybe there's a different way - taking SQL code from the first element and "inserting" it into the copy? But then - how?

Aaron B

  • EA Administrator
  • EA User
  • *****
  • Posts: 941
  • Karma: +18/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #6 on: April 09, 2013, 10:01:37 am »
Here is a basic example of how I would copy an element and it's attributes:

Code: [Select]
EA.Element selectedElement = (EA.Element)repository.GetContextObject();
EA.Package thePackage = repository.GetPackageByID(selectedElement.PackageID);

EA.Element elementCopy = (EA.Element)thePackage.Elements.AddNew("Copy of " + selectedElement.Name, selectedElement.Type);
elementCopy.Notes = selectedElement.Notes;
//TODO: insert any other properties here that you need to copy for the element
elementCopy.Update();

for (short i = 0; i < selectedElement.Attributes.Count; i++)
{
    EA.Attribute originalAtt = (EA.Attribute)selectedElement.Attributes.GetAt(i);
    EA.Attribute copyAtt = (EA.Attribute)elementCopy.Attributes.AddNew(originalAtt.Name, originalAtt.Type);
    copyAtt.Style = originalAtt.Style;
    copyAtt.StereotypeEx = originalAtt.StereotypeEx;
    copyAtt.Pos = originalAtt.Pos;
    //TODO: insert any other properties here that you need to copy for the attribute
    copyAtt.Update();
}

You do not need to call Refresh() on a collection unless there have been additions or deletions to the collection and you need to loop over it again.  Never call Refresh() while in a loop.

SiliconRancher

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #7 on: April 10, 2013, 01:26:30 am »
Thanks, it did the trick :) Now I have to try with methods to make original table's PK aa FK in the copy and I will have fun with other attributes and such.

One last question - is there a way to make the copy appear in the diagram (the same diagram as the original element)?

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #8 on: April 10, 2013, 01:39:46 am »
Sure. You need to create diagram objects for the currently open diagram.

q.

SiliconRancher

  • EA Novice
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #9 on: April 11, 2013, 05:22:11 am »
Of course I'm stuck again :( Now I am able to copy attributes and methods, but while I'm copying parameters of methods:
Code: [Select]
for (short k = 0; k < originalMethod.Parameters.Count; k++)
                        {
                            EA.Parameter origParameter = (EA.Parameter)originalMethod.Parameters.GetAt(k);
                          
                          EA.Parameter copyParameter = (EA.Parameter)copyParameter.Parameters.AddNew(origParameter.Name+"copy", origParameter.Type);
                
                            cV.Update();
                            cM.Update();

                        }


 I receive an error:



Also I tried to find out - without succes - which attribute of the column attribute holds the info about input data type (what type - eg. integer or char - is put inside a column) and how much data can user put inside (eg. char[15]). Also where can I set which column is primary key? And set the column's values as "unique" - or switch it off.

Thank you in advance.


P.S. about adding objects (in my case - link to object) to diagram:
Code: [Select]
                   Repository.GetCurrentDiagram().DiagramLinks.AddNew(elementCopy.Name, elementCopy.Type);
                      Repository.GetCurrentDiagram().Update();
                     Repository.RefreshOpenDiagrams(true);
Of course it doesn't work. What am I missing?
« Last Edit: April 11, 2013, 05:23:41 am by SiliconRancher »

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #10 on: April 11, 2013, 10:27:27 am »
Have you once in a while thought of RTFM?

q.

Gary

  • EA User
  • **
  • Posts: 84
  • Karma: +1/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #11 on: April 18, 2013, 08:52:22 pm »
I know this is a bit simplistic and may be missing the point but if you want to create a direct copy of an element on a diagram just ctrl drag it and give it a new name. No coding required.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #12 on: April 18, 2013, 09:48:06 pm »
Sure :-) But the reason for writing an add-in is to avoid doing it manually - for many reasons.

q.

zalbina

  • EA User
  • **
  • Posts: 149
  • Karma: +0/-0
    • View Profile
Re: Simple click->copy Add-in
« Reply #13 on: May 08, 2013, 05:03:49 pm »
Hi,

I just wondering if is it possible to copy elements between packages without this long way by copying attributes, tagged values, operations and so on?

Thanks.

qwerty

  • EA Guru
  • *****
  • Posts: 13584
  • Karma: +396/-301
  • I'm no guru at all
    • View Profile
Re: Simple click->copy Add-in
« Reply #14 on: May 08, 2013, 05:12:14 pm »
See EaPackage.Clone()

q.