3D PLM Enterprise Architecture

User Interface - Frame

Expand/Collapse Specification Tree Nodes

How to put out an object in the specification tree
Use Case

Abstract

This article shows how to expand or collapse nodes of a specification tree.


What You Will Learn With This Use Case

This use case is intended to show you how to expand or collapse nodes of a specification tree. It is a graph of nodes managed by the following MVC paradigm:

This use case is based on the graph contained in the CATFrmNavigWindow class. It is the base class of the CATFrmGraphAnd3DWindow class, the Part or the Product window class. You will learn how:

[Top]

The CAACafSpecTree Use Case

CAACafSpecTree is a use case of the CAACATIAApplicationFrame.edu framework that illustrates CATIAApplicationFrame and ObjectModelerBase framework capabilities.

[Top]

What Does CAACafSpecTree Do

CAACafSpecTree is a command available in a Part document. This command, the Expand/Collapse command, is accessible through a tool bar and the menu bar.

Fig.1: The Expand/Collapse Command

The Expand/Collapse command is a state dialog command [2] which enables the end user to expand or collapse nodes of the Part document specification tree. There are two modes for this command:

The default behavior of the command is the first one (Expand/Collapse). The second is accessible by exporting the CAACafSpecTreeExpandMode variable. See the How to Launch CAACafSpecTree section. 

[Top]

How to Launch CAACafSpecTree

To launch CAACafSpecTree, you will need to set up the build time environment, then compile CAACafSpecTree along with its prerequisites, set up the run time environment, and then execute the use case [3]. 

But just before launching the execution, edit the CAAMechanicalModeler.edu.dico interface dictionary file located in the dictionary directory of the CAAMechanicalModeler.edu framework:

Windows InstallRootDirectory\CAAMechanicalModeler.edu\CNext\code\dictionary\
UNIX InstallRootDirectory/CAAMechanicalModeler.edu/CNext/code/dictionary/

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

In this file, remove the "#" character before the two following lines, and then run mkCreateRuntimeView.

...
#CAAMmrPartWksAddin          CATIWorkbenchAddin              libCAAMmrPartWksAddin
#CAAMmrPartWksAddin          CATIPrtWksAddin                 libCAAMmrPartWksAddin
...

The two line deal with the Part workshop add-in located in the CAAMmrPartWksAddin.m module of the CAAMechanicalModeler.edu framework. This add-in adds the Expand/Collapse command in the Part document user interface.

Then, in the window where you run the mkrun command, do not type the module name on the command line, but type CNEXT instead. When the application is ready, do the following:

  1. On the File menu, click New
  2. File New Dialog box click Part  and click OK
  3. Create Point, Line, Pad, ....
  4. On the Tools menu, click Expand/Collapse
  5. Select objects in the specification tree
  6. Select objects in 3D 
  7. On the Start menu, click Exit

In the window where you run the mkrun command, export the CAACafSpecTreeExpandMode environment variable such as:

Windows set CAACafSpecTreeExpandMode=CAACafSpecTreeExpandAllNodes
UNIX export CAACafSpecTreeExpandMode=CAACafSpecTreeExpandAllNodes

Then, in the window where you run the mkrun command, do not type the module name on the command line, but type CNEXT instead. When the application is ready, do the following:

  1. On the File menu, click New
  2. File New Dialog box click Part  and click OK
  3. Create Point, Line, Pad, ....
  4. On the Tools menu, click Expand/Collapse
  5. Select objects in the specification tree
  6. On the Start menu, click Exit

[Top]

Where to Find the CAACafSpecTree Code

The CAACafSpecTree use case is made of two classes:

[Top]

Step-by-Step

There are five logical steps in CAACafSpecTree:

  1. Retrieving the CATNavigController Class Instance
  2. Implementing the BuildGraph method
  3. Expanding the Spec Tree Until the Selected Object
  4. Expanding/Collapsing the Selected Object Node
  5. Expanding All Nodes from the Selected Object

[Top]

Retrieving the CATNavigController Class Instance

The specification tree controller is retrieval from the current window. This piece of code is done in the CAACafCollapseExpandCmd  class constructor.

  CATFrmLayout * pLayout = CATFrmLayout::GetCurrentLayout();
  if ( NULL != pLayout )
  {
     CATFrmWindow * pCurrentWindow = pLayout->GetCurrentWindow();

     if ( NULL != pCurrentWindow )
     {
         if ( 1 == pCurrentWindow->IsAKindOf("CATFrmNavigGraphicWindow") )
         {
             CATFrmNavigGraphicWindow * pFrmNavigGraphicWindow = 
                 (CATFrmNavigGraphicWindow*) pCurrentWindow ;

             CATNavigBox * pNavigBox = NULL ;
             pNavigBox = pFrmNavigGraphicWindow->GetNavigBox();

             if ( NULL != pNavigBox )
             {
                _pNavigController = pNavigBox->GetController();
             }
         }
     }
  }

The unique CATFrmLayout class instance [4] manages the list of windows during the session. The GetCurrentWindow method retrieves the current one. If you want expand the graph inside all windows of  the active document, refer to the frame article [4] which explains how to retrieve all the windows for a document.

If the current window is a CATFrmNavigGraphicWindow class instance, you can access to an object (the CATNavigBox class instance) which keeps the graph controller. _pNavigController is a CATNavigController class instance declared as data member of the command. 

[Top]

Implementing the BuildGraph Method

As usual the BuildGraph method is divided in three parts:

  1. Creating the agents
  2. Creating the states
  3. Creating the transitions between states according to the agents.
...
   _daObjectToExpandNode = new CATPathElementAgent("SelObjectToExpandNodeId");
   _daObjectToExpandNode->AddElementType(IID_CATINavigateObject);
   _daObjectToExpandNode->SetBehavior(CATDlgEngRepeat | CATDlgEngWithPSOHSO );
                            
 
   CATDialogState *stGetObjState = GetInitialState("stGetObjStateId");
   stGetObjState->AddDialogAgent(_daObjectToExpandNode);

   CATDialogTransition *pTransition =    AddTransition
   (
      stGetObjState,
      stGetObjState,
      IsLastModifiedAgentCondition(_daObjectToExpandNode)  , 
      Action((ActionMethod) & CAACafCollapseExpandCmd::ExpandObject)
   );  
...

_daObjectToExpandNode is an acquisition agent to select an object in the specification tree or in 3D. This object should implement the CATINavigateObject interface (specify by the AddElementType method) [5]. After the selection, the object is highlighted (specify by the CATDlgEngWithPSOHSO behavior). The CATDlgEngRepeat behavior enables you to re-use the agent without reinitialize it. 

This state command has only state, a state, stGetObjState , whose the name is stGetObjStateId

When the end user selects a valid element, the unique transition is triggered and the ExpandObject method is called. 

[Top]

Expanding the Spec Tree Until the Selected Object

The first part of the ExpandObject method consists in to retrieve the selected object. The GetValue method, applied to _daObjectToExpandNode, the CATPathElement class instance pointer, retrieves the complete path of the selected object. 

...
CATBoolean CAACafCollapseExpandCmd::ExpandObject(void *iDummy)
{
     CATPathElement * pObjPath = _daObjectToExpandNode->GetValue();
     CATBaseUnknown * pObjectToExpand = NULL;
     
     if ( NULL != pObjPath) 
     {
         if ( pObjPath->GetSize() > 0 )
         { 
            // The leaf of the selection
            pObjectToExpand = (*pObjPath)[pObjPath->GetSize()-1];
         }
...

pObjectToExpand is the leaf of the path. It is the object to display in the specification tree if it is not already visible. Effectively to display the contents of an object, it should be visible. The piece of code below explains how to carry out that.

...
         for ( int j = 0 ; j <= pObjPath->GetSize()-2 ; j++)
         {
            CATBaseUnknown * pFatherObjectToExpand = (*pObjPath)[j];

            CATListValCATBaseUnknown_var * pNodeList = NULL ;
            pNodeList = _pNavigController->GetAssociatedElements(pFatherObjectToExpand);
        
            if ( NULL != pNodeList )
            {
               int nbNodes = pNodeList->Size();
               for ( int k= 1 ; k <= nbNodes ; k++ )
               {
                  CATIGraphNode_var graphNode = (*pNodeList)[k];
                  if ( NULL_var != graphNode )
                  {
                     if ( 0 == graphNode->IsExpanded() )
                     {
                        CATINavigElement_var spNavigElement = graphNode ;
                        if ( NULL_var != spNavigElement )
                        {
                           spNavigElement->ProcessAfterExpand();
...

The path of selection follows the specification tree strcuture. So from the top of the path until the element just above the leaf, it is necessary to check that the element's contents is visible. pFatherObjectToExpand is the current element to chek. The GetAssociatedElements method of the CATNavigController class retrieves the nodes associated with the element set as argument. (In a product, a Part can be instantiated several times). A node can be handled by either the CATIGraphNode interface or the CATINavigElement interface. The first one enables you to know its expand status thanks to the IsExpanded method. If the node is not expanded the ProcessAfterExpand method of the second interface enables you to expand it. 

Once the selected object is displayed in the specification tree, in taken into account of the environment variable, _pExpandMode, an expand of all its contents is done, see Expanding All Nodes from the Selected Object section, or the element is only expanded or collapsed, see the Expanding the Selected Object Node section. 

...
         if ( (NULL != _pExpandMode) && 
          (0==strcmp("CAACafSpecTreeExpandAllNodes",_pExpandMode)) )
         {
             ExpandAllNode(pObjectToExpand);
         }else
         {
             ExpandCollapseNode(pObjectToExpand);
         }
...

_pExpandMode has been initialized in the CAACafCollapseExpandCmd  class constructor by using the CATGetEnvValue global function. Refer to the code for implementation details.

[Top]

Expanding the Selected Object Node

It is almost the same process as the other elements in the path just above the leaf. iObject is the leaf of the selection path. See the previous section. Since the expand status is not check just before calling the ProcessAfterExpand method, this method carries out an expand if the element is collapsed otherwise collapses it. 

...
void CAACafCollapseExpandCmd::ExpandCollapseNode(CATBaseUnknown_var iObject)
{
   ...     
        CATListValCATBaseUnknown_var * pNodeList = NULL ;
        pNodeList = _pNavigController->GetAssociatedElements(iObject);

        if ( NULL != pNodeList )
        {
           int nbNodes = pNodeList->Size();
           for ( int i= 1 ; i <= nbNodes ; i++ )
           {
               CATBaseUnknown_var spNode = (*pNodeList)[i];
               if ( NULL_var != spNode )
               {
                   CATINavigElement_var spNavigElement = spNode ;
                   if ( NULL_var != spNavigElement )
                   {
                      spNavigElement->ProcessAfterExpand();          
 ...
}
...

[Top]

Expanding All Nodes from the Selected Object

It is the same process as the other elements in the path just above the leaf. iObject is the leaf of the selection path. The ProcessAfterExpand method is called only if the leaf is not expanded.

...
void CAACafCollapseExpandCmd::ExpandAllNode(CATBaseUnknown_var iObject)
{     
    if ( NULL_var != iObject )
    {
        CATListValCATBaseUnknown_var * pNodeList = NULL ;
        pNodeList = _pNavigController->GetAssociatedElements(iObject);

        if ( NULL != pNodeList )
        {
           int nbNodes = pNodeList->Size();
           for ( int i= 1 ; i <= nbNodes ; i++ )
           {
              CATIGraphNode_var graphNode = (*pNodeList)[i];
              if ( NULL_var != graphNode )
              {
                  if ( 0 == graphNode->IsExpanded() )
                  {
                      CATINavigElement_var spNavigElement = graphNode ;
                      if ( NULL_var != spNavigElement )
                      {
                         spNavigElement->ProcessAfterExpand();
...

Once, you are sure that the spec tree is expanded until the contents of the selected object, you have to do the same things with its children. The CATINavigateObject interface enables you to retrieve the element's children [1]. 

...
        CATINavigateObject_var spNavigateObject = iObject ;
        if ( NULL_var != spNavigateObject )
        {
           CATListValCATBaseUnknown_var* pListChild = NULL ;
           pListChild = spNavigateObject->GetChildren();

           if ( NULL != pListChild )
           {
              for ( int t = 1 ; t <= pListChild->Size() ; t++)
              {
                 CATBaseUnknown_var spOnChild = (*pListChild)[t];
                 ExpandAllNode(spOnChild);
}
...

[Top]


In Short

This use case explains how to visualize an element in a specification tree and how to expand (or collapse) its contents.  

[Top]


References

[1] The Object Navigator
[2] Getting Started with State Dialog Commands
[3] Building and Launching a CAA V5 Use Case
[4] Understanding the Application Frame Layout
[5] Managing Selection
[Top]

History

Version: 1 [May 2003] Document created
[Top]

Copyright © 2003, Dassault Systèmes. All rights reserved.