3D PLM PPR Hub Open Gateway

Product Modeler

Inserting Components Stored in Foreign Files

Implementing the CATIProductFileSelection Interface

Use Case

Abstract

This article presents  the CAAPstProductFileSelection use case which illustrates how to add products contained in a foreign file format.


What You Will Learn With This Use Case

Using the CATIProductFileSelection interface, a component stored in a foreign file format can be loaded and inserted into an existing product.

[Top]

The CAAPstProductFileSelection Use Case

CAAPstProductFileSelection is a use case of the CAAProductStructure.edu framework that illustrates the ProductStructure framework capabilities.

[Top]

What Does CAAPstProductFileSelection Do

Components are inserted into a product by activating the Components -> Existing Component... contextual menu and selecting one or more files. By implementing the CATIProductFileSelection interface, we will show how to make that menu recognize new file types and how those files can be processed for insertion.

This implementation is designed specifically to

The sample CAAProduct file is in fact a CATProduct file that has been renamed. It has five child products and can be found at

InstallRoot/CAAProductStructure.edu/CNext/resources/graphic/CAAPstProductFileSelection_MainPrd.CAAProduct

[Top]

How to Launch CAAPstProductFileSelection

To launch CAAPstProductFileSelection:

  1. Set the current directory to InstallRoot/CAAProductStructure.edu
  2. Set up  the build time environment and build the CAAPstProductFileSelection.m module (see reference [2])
  3. Edit the  CNext/code/dictionary/CAAProductStructure.edu.dico dictionary by uncommenting the line beginning with CAAPstPrdFileSel
    # CAAPstProductFileSelection use case
    CAAPstPrdFileSel CATIProductFileSelection libCAAPstProductFileSelection
  4. Install the dictionary and other resource files by executing mkCreateRuntimeView
  5. Start CATIA by executing mkrun
  6. Create a new product and select Components -> Existing Component... on the product contextual menu
  7. Select CAAProduct as file type and browse to InstallRoot/CAAProductStructure.edu/CNext/resource/graphic to pick the only eligible file CAAPstPrdFileSel_MainPrd.CAAProduct
  8. This is the result once the CAAPstPrdFileSel_MainPrd.CAAProduct file has been selected

    As you can see, it is the second child product (CAAPstPrdFileSel_Prd2) that has been inserted (instead of CAAPstPrdFileSel_MainPrd if it is a CATProduct.)

[Top]

Where to Find the CAAPstProductFileSelection Code

CAAPstProductFileSelection code is located in the CAAPstProductFileSelection.m module of the CAAProductStructure.edu framework.

[Top]

Step-by-Step

There are two parts in CAAPstProductFileSelection:

  1. User Interface
  2. Actual Implementation Code

[Top]

User Interface

The impact on the user interface is the appearance of the new CAAProduct file type with a corresponding label in the file selection dialog. This is done with the help of the dictionary and two resource files.

In the dictionary we indicate that our implementation CAAPstPrdFileSel, implements the CATIProductFileSelection interface with code residing in the libCAAPstProductFileSelection library:

# CAAPstProductFileSelection use case
CAAPstPrdFileSel CATIProductFileSelection libCAAPstProductFileSelection

As a consequence, there must be a CAAPstPrdFileSel.CATRsc file describing the file type that CAAPstPrdFileSel will handle. This file can found at

InstallRoot/CAAProductStructure.edu/CNext/resources/msgcatalog/CAAPstPrdFileSel.CATRsc

ExtensionCount="1";
1.Method="CAA Product File";
1.Extension="CAAProduct";

The CAAPstPrdFileSel.CATRsc file indicates that one type is handled (ExtensionCount="1") and that the extension is "CAAProduct". The Method line serves as a unique identification in case there are more than one implementation handling the CAAProduct file type.

Finally we need a localized label for the CAAProduct file type. It is defined by the CAAPstPrdFileSel.CATNls file that is located at

InstallRoot/CAAProductStructure.edu/CNext/resources/msgcatalog/CAAPstPrdFileSel.CATNls

1="CAA Product Files ";

The contents of this file can be translated for other locales if needed. In that case, they should be located in the corresponding locale directory. For example, you can find the French version in

InstallRoot/CAAProductStructure.edu/CNext/resources/msgcatalog/French/CAAPstPrdFileSel.CATNls

Now that the user interface recognizes the new file type, the logic that processes the files must also be provided.

[Top]

Actual Implementation Code

The CATIProductFileSelection interface implementation has to be derived from the CATPrdCommonFileSelection class. It has two methods that can be redefined:

In our CAAPstProductFileSelection class, we need to redefine only ExtractProducts for the specific behavior (of extracting only the second child product) and the constructor/destructor to add the CAAProduct file type.

class CAAPstProductFileSelection: public CATPrdCommonFileSelection
{
CATDeclareClass;

public:

        // Standard constructor and destructor for an implementation class
        // -----------------------------------------------------------------
        CAAPstProductFileSelection ();
        virtual ~CAAPstProductFileSelection ();

        /**
         * @see ProductStructure.CATIProductFileSelection#ExtractProducts()
         */
        HRESULT ExtractProducts (CATIContainer*, CATIProduct*,
                                 CATListValCATBaseUnknown_var*&);


private:
        // The copy constructor and the = operator must not be implemented
        // -------------------------------------------------------------------
        CAAPstProductFileSelection (CAAPstProductFileSelection &);
        CAAPstProductFileSelection& operator=(CAAPstProductFileSelection&);

};

There are roughly three parts in the CAAPstProductFileSelection.cpp source file:

  1. Interface binding
  2. Constructor and Destructor
  3. ExtractProducts Method

[Top]

Interface binding

The C++ class is linked to the interface with the TIEchain macro.The ClassImplementClass macro indicates that the C++ class is a data extension and that it is extending CAAPstPrdFileSel.

TIEchain_CATIProductFileSelection(CAAPstProductFileSelection);

CATImplementClass(CAAPstProductFileSelection,
                  DataExtension,
                  CATBaseUnknown,
                  CAAPstPrdFileSel);

[Top]

Constructor and destructor

In the constructor, the _typesList data member is allocated and initialized with a list consisting of "CAAProduct". This is how CATIA determines which implementation to invoke for a given file type. This data member is freed in the destructor if necessary.

//-----------------------------------------------------------------------------
// Constructor
//-----------------------------------------------------------------------------
CAAPstProductFileSelection::CAAPstProductFileSelection():
CATPrdCommonFileSelection()
{
        CAAPstPFSTRACE("CAAPstProductFileSelection - Constructor");

        _typesList = new CATListOfCATUnicodeString(1);
        if (NULL != _typesList) {
                // must be identical to the one in CAApstPrdFileSel.CATRsc
                _typesList->Append("CAAProduct");
        }
}

//-----------------------------------------------------------------------------
// Destructor
//-----------------------------------------------------------------------------
CAAPstProductFileSelection::~CAAPstProductFileSelection()
{
        CAAPstPFSTRACE("CAAPstProductFileSelection - Destructor");

        if (NULL != _typesList) {
                delete _typesList;
        _typesList = NULL;
        }
}

[Top]

ExtractProducts Method

Once the user has selected one or more files, this method is invoked. The purpose of this method is to process the selected files and return a list of components from it.

ExtractProducts is called with three input parameters (one data member and two arguments) and one output parameter:

  1. _pathsList: the data member contains the list of files that have been selected
  2. iContainer: the container of the parent product
  3. iParentProduct: the product into which the insertion(s) will be made
  4. oList: the list of products to be inserted
//-----------------------------------------------------------------------------
// ExtractProducts
//-----------------------------------------------------------------------------
HRESULT CAAPstProductFileSelection::ExtractProducts
        (CATIContainer* iContainer,            // container of parent product
         CATIProduct* iParentProduct,          // parent product to insert to
         CATListValCATBaseUnknown_var*& oList) // products to be inserted
{
        HRESULT rc;
        CAAPstPFSTRACE("Entering CAAPstProductFileSelection::ExtractProducts");

The inputs are verified and the output list is allocated.

...
        if (NULL == _pathsList || NULL == iContainer || NULL == iParentProduct)
                return E_FAIL;
        int pathCount = _pathsList->Size();
        if (NULL == oList) {
                // allocate product list
                oList = new CATLISTV(CATBaseUnknown_var) (pathCount);
                if (NULL == oList) {
                        CAAPstPFSTRACE("Failed to allocate output list");
                return E_FAIL;
                }
        }
...

Then for each file, we extract the second child product and add it to the output list.

...
        for (int pathNum = 1; pathNum <= pathCount; pathNum++) {

                //
                // For each file selected,
                // retrieve the 2nd child product for insertion
                //
                CATUnicodeString& curPath = (*_pathsList)[pathNum];
                CATDocument* pSelectedDoc = NULL;
                rc = CATDocumentServices::Open(curPath, pSelectedDoc);
...
                CATIDocRoots* pDocRoots = NULL;
                rc = pSelectedDoc->QueryInterface(IID_CATIDocRoots,
                                                  (void **) &pDocRoots);
...
                CATListValCATBaseUnknown_var* pRootProducts = 
                        pDocRoots->GiveDocRoots();
...
                CATIProduct_var spRootProduct = (*pRootProducts)[1];
                delete pRootProducts;
                pRootProducts = NULL;
...
                CATIProduct *pProductOnRoot = NULL;
                rc = spRootProduct->QueryInterface(IID_CATIProduct,
                                                   (void **) &pProductOnRoot);
...
                CATListValCATBaseUnknown_var* childrenList =
                        pProductOnRoot->GetAllChildren();
                if (NULL == childrenList || childrenList->Size() < 2) {
                        CAAPstPFSTRACE("Failed to get 2nd children of root product");
                        return E_FAIL;
                }

                CATIProduct_var spProductToAdd = (*childrenList)[selectedChild];
                oList->Append(spProductToAdd);

...
        }

        CAAPstPFSTRACE("Exiting CAAPstProductFileSelection::ExtractProducts");
        return S_OK;
}

[Top]


In Short

This use case has demonstrated how to handle a new file type:

[Top]


References

[1] The Product Structure Model
[2] Building and Launching a CAA V5 Use Case
[Top]

History

Version: 1 [Aug 2004] Document revised
Version: 1 [Sep 2003] Document created
[Top]

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