Wednesday, November 7, 2012

Using a tree control


1. In the AOT, create a new class named BudgetModelTree with the following code:
class BudgetModelTree
{
    FormTreeControl tree;
    BudgetModelId modelId;
}


public void new(FormTreeControl _formTreeControl, BudgetModelId _budgetModelId)
{
    tree = _formTreeControl;
    modelId = _budgetModelId;
}


public static BudgetModelTree construct(FormTreeControl _formTreeControl, BudgetModelId_budgetModelId = '')
{
    return new BudgetModelTree(_formTreeControl, _budgetModelId);
}


private TreeItemIdx createNode(TreeItemIdx _parentIdx, BudgetModelId _modelId, RecId _recId)
{
    TreeItemIdx itemIdx;
    BudgetModel model;
    BudgetModel submodel;
    model = BudgetModel::find(HeadingSub::Heading, _modelId);
    itemIdx = SysFormTreeControl::addTreeItem(tree, _modelId + ' : ' + model.Txt, _parentIdx, _recId, 0,true);

   
    if (modelId == _modelId)
    {
        tree.select(itemIdx);
    }

    while select submodel
    where submodel.ModelId == _modelId && submodel.Type == HeadingSub::SubModel
    {
        this.createNode(itemIdx, submodel.SubModelId, submodel.RecId);
    }
    return itemIdx;
}


public void buildTree()
{
    BudgetModel model;
    BudgetModel submodel;
    TreeItemIdx itemIdx;
    tree.deleteAll();
    tree.lock();
    while select RecId, ModelId from model
    where model.Type == HeadingSub::Heading
    notExists join submodel
    where submodel.SubModelId == model.ModelId &&
    submodel.Type == HeadingSub::SubModel
    {
        itemIdx = this.createNode(FormTreeAdd::Root, model.ModelId, model.RecId);
        SysFormTreeControl::expandTree(tree, itemIdx);
    }
    tree.unLock(true);
}



2. In the AOT, open the BudgetModel form's design, expand the Body group, then
expand the GridContainer group, and change the following property of the
BudgetModel grid control:

Property  Value
Visible     No

3. Create a new Tree control right below the BudgetModel grid with the
following properties:

Property    Value
Name        Tree
Width        Column width
Height        Column height
Border       Single line
RowSelect Yes

4. Add the following code to the bottom of the form's class declaration:
BudgetModelTree modelTree;

5. Add the following code to the bottom of form's init():
modelTree = BudgetModelTree::construct(Tree);
modelTree.buildTree();

6. Override selectionChanged() on the Tree control with the following code:
public void selectionChanged(FormTreeItem _oldItem, FormTreeItem _newItem, FormTreeSelect _how)
{
    BudgetModel model;
    BudgetModelId modelId;
    super(_oldItem, _newItem, _how);
    if (_newItem.data())
    {
        select firstOnly model
        where model.RecId == _newItem.data();
  
        if (model.Type == HeadingSub::SubModel)
        {
            modelId = model.SubModelId;

            select firstOnly model
            where model.ModelId == modelId && model.Type == HeadingSub::Heading;
        }
    BudgetModel_ds.findRecord(model);
    BudgetModel_ds.refresh();
    }
}

7. Override the delete() method on the BudgetModel data source with the
following code:

public void delete()
{
    super();
    if (BudgetModel.RecId)
    {
        modelTree.buildTree();
    }
}

8. Override the delete() method on the SubModel data source with the
following code:

public void delete()
{
    super();
    if (SubModel.RecId)
    {
        modelTree.buildTree();
    }
}

9. Add the following code to the bottom of the write() method on the BudgetModel
data source:
modelTree.buildTree();

10. Override the write() method on the SubModel data source and add the following
code to its bottom:
modelTree.buildTree();

11. In the AOT, the BudgetModel form should look like the following screenshot:


12. To test the tree control, open Budgeting | Setup | Budget models. Notice how the
ledger budget models are presented as a hierarchy:




No comments: