Monday, 13 July 2020 13:44

Working with the Repository.CurrentSelection

Rate this item
(3 votes)

Working with the Repository.CurrentSelection

written by Phil Chudley, Principle Consultant at Dunstan Thomas Consulting

Overview

When developing a script of an extension a fairly common requirement is to process a set of selected elements. This can be achieved using either GetTreeSelectedElements (for a selection in the Project Browser), or SelectedObjects (for a selection on a Diagram). These work well enough, but there appears to be no method for processing a selection of Diagrams or Packages within the Project Browser, or a selection that contains a mixture of Diagrams, Elements and Packages. You may not need to process such a selection very often, but if you do, then this document will provide an overview of a method that will allow processing a mixed set.

This uses a property from the Repository class named CurrentSelection.

Examples of code are provided in this document and an example script is provided as a download. The language using is JScript but the same principles will apply to other languages such as VB Script and C#/

The CurrentSelection Property

The CurrentSelection property provides access to all items, regardless of their type, within a current selection. This selection can be made within the Project Browser or on a diagram. In this tutorial we will focus on a selection of items made within the Project Browser using a simple JScript example.

The CurrentSelection property returns a special form of Collection typed as an EASelection, hence it can be accessed using a simple line of code such as:

var selection as EA.EASelection;

selection = Repository.CurrentSelection;

Iterating the CurrentSelection Property

As a first simple exercise, let's just iterate the CurrentSelection so that we can discover what type each item in the selection is, once we have this information, we can think about processing each item within the collection.

Create a Normal Group for the script and create a new JScript.

When iterating the CurrentSelection, it is important that you use a simple for loop, (JScript Enumerators or C# foreach will not work). The list of items in the selection is stored within the List property in which each item in the List is of an EAContext type which has a property named ContextType which will yield the type of item being processed. In JScript this is an int, in C# it should be converted to a string using ToString().

Using simple iteration in JScript such as:

for (var index = 0; index < selection.List.Count; index++)

{

     var item as EA.EAContext;

     item = selection.List.GetAt(index);

     Session.Output("The item has type of " + item.ContextType);

}

Let's assume a selection has been made in the Project Browser which contains, diagrams, elements and packages. Execute the script and you will discover that:

Diagrams have a ContextType of 0 (or otNone if you want to use the JScript constants)

Elements have a ContextType of 4 (or otElement if you want to use the JScript constants)

Packages have a ContextType of 5 (or otPackage if you want to use the JScript constants)

The only surprise or gotcha is the ContextType for a Diagram, this is 0 (rather than 8) or otNone (rather than otDiagram) as you would expect.

Getting the Details About Each Item

Armed with the knowledge about each item's ContextType we can now turn our attention to access the properties for each different type of item in the selection. Luckily, the GUID for the item is provided as a property in the EAContext object, so to extract each item from the repository is reasonably straightforward. I use a switch case structure for this. 

In the following code references are made to functions that display details for each item type, the code for these functions is not shown here, but is included in the script which can be downloaded.

switch (item.ContextType)

{

   case otNone:

         var theDiagram as EA.Diagram;

         theDiagram = Repository.GetDiagramByGUID(item.ElementGUID);

         DisplayDiagramDetails(theDiagram);

         break;

   case otElement:

         var theElement as EA.Element;

         theElement = Repository.GetElementByGUID(item.ElementGUID);

         DisplayElementDetails(theElement);

         break;

   case otPackage:

         var thePackage as EA.Package;

         thePackage = Repository.GetPackageByGUID(item.ElementGUID);

         DisplayPackageDetails(thePackage);

         break;

}

Modifying Each Item in the CurrentSelection

So far, the coding has been straightforward, so let's consider modifying each element in the selection, regardless of its type, (for example for prefix the name of each item with a string). Or perhaps you want to apply different changes depending upon what type of item is being processed. You might think that an iteration and switch case like the one above would work, where inside the switch case you call a function to apply the modifications.

However you would be wrong! Another gotcha and it's a big one! As soon as an item in the selection is modified and updated, the selection is modified (at least one item is dropped from the selection) and you will lose the original selection! You can try this and see for yourselves. So it appears we are stuck, but help is at hand.

There may be other solutions, but the approach I use is:

1) Create three arrays (or ArrayLists in C#) one for each type of item

2) Iterate the selection as above, and add each item to its respective array.

3) Iterate each array to process the items in that array and apply the changes.

var diagramArray = new Array();

var elementArray = new Array();

var packageArray = new Array();

switch (item.ContextType)

{

   case otNone:

         var theDiagram as EA.Diagram;

         theDiagram = Repository.GetDiagramByGUID(item.ElementGUID);

         diagramArray.push(theDiagram);

         break;

   case otElement:

         var theElement as EA.Element;

         theElement = Repository.GetElementByGUID(item.ElementGUID);

         elementArray.push(theElment);

         break;

   case otPackage:

         var thePackage as EA.Package;

         thePackage = Repository.GetPackageByGUID(item.ElementGUID);

         packageArray.push(thePackage);

         break;

}

To process each array, you can use an Enumerator (C# for each) or a simple for loop, it's your choice. I tend to use Enumerators.

Let’s assume that we simply want to prefix the name of each item in the selection with some text that has been entered by the user (JScript Session.Input)

var diagramEnumerator = new Enumerator(diagramArray);

var elementEnumerator = new Enumerator(elementArray);

var packageEnumerator = new Enumerator(packageArray);

while (!diagramEnumerator.atEnd())

{

     var diagram = diagramEnumerator.item();

     diagram.Name = prefix + "-" + diagram.Name;

     diagram.Update():

     diagramEnumerator.moveNext();

}

while (!elementEnumerator.atEnd())

{

     var element = elementEnumerator.item();

     element.Name = prefix + "-" + element.Name;

     element.Update():

     elementEnumerator.moveNext();

}

while (!packageEnumerator.atEnd())

{

     var package = packageEnumerator.item();

     package.Name = prefix + "-" + package.Name;

     package.Update():

     packageEnumerator.moveNext();

}

Summary

I hope you have found this tutorial useful, this technique is not something that you will need often, but for that occasion when you do need to process a Project Browser selection then this tutorial should help you out.

Phil Chudley

Principle Consultant

Dunstan Thomas Consulting

follow me on Twiter @SparxEAGuru

Read 3332 times Last modified on Tuesday, 14 July 2020 00:54

2 comments

  • Comment Link Adam Roybal Friday, 28 January 2022 21:00 posted by Adam Roybal

    I've have the v15.2 build 1559 and CurrentSelection.List.Count still does not work in a regular JavaScript script.
    But, I am working on a JavaScript Add-In and CurrentSelection does work

  • Comment Link philchudley Sunday, 18 October 2020 15:04 posted by philchudley

    IMPORTANT
    ---------

    This script and indeed the process in general DOES NOT appear to work in the latest release of EA v 15.2

    There is a null object error reported when executing the currentSelection.List.Count statement.

    Works perfectly in EA version 15.1

    Have reported the issue as a bug to Sparx

    Phil

Login to post comments