uifw/AvKon/aknhlist/src/akntree.cpp
changeset 0 2f259fa3e83a
child 15 08e69e956a8c
equal deleted inserted replaced
-1:000000000000 0:2f259fa3e83a
       
     1 /*
       
     2 * Copyright (c) 2006, 2007 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Implementation for CAknTree class.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 #include <AknUtils.h>
       
    21 #include <aknlayoutscalable_avkon.cdl.h>
       
    22 #include <AknsUtils.h>
       
    23 #include <avkon.mbg>
       
    24 #include <AknMarqueeControl.h>
       
    25 
       
    26 #include "akntree.h"
       
    27 #include "akntreelist.h"
       
    28 #include "akntreeordering.h"
       
    29 #include "aknhlistlib.h"
       
    30 #include "akntreeiterator.h"
       
    31 #include "akntreelisticon.h"
       
    32 #include "akncustomtreeordering.h"
       
    33 #include "akntreelistinternalconstants.h"
       
    34 
       
    35 const TInt KObserverArrayGranularity = 1;
       
    36 
       
    37 // Tree flag definitions
       
    38 enum TAknTreeFlags
       
    39     {
       
    40     ETabModeFunctionIndicators
       
    41     };
       
    42 
       
    43 
       
    44 // ======== MEMBER FUNCTIONS ========
       
    45 
       
    46 // ---------------------------------------------------------------------------
       
    47 // Two-phased constructor.
       
    48 // ---------------------------------------------------------------------------
       
    49 //
       
    50 CAknTree* CAknTree::NewL( CAknTreeList& aList, CAknTreeOrdering* aOrdering )
       
    51     {
       
    52     CAknTree* self = new( ELeave ) CAknTree( aList, aOrdering );
       
    53     CleanupStack::PushL( self );
       
    54     self->ConstructL();
       
    55     CleanupStack::Pop( self );
       
    56     return self;
       
    57     }
       
    58 
       
    59 
       
    60 // ---------------------------------------------------------------------------
       
    61 // Destructor.
       
    62 // ---------------------------------------------------------------------------
       
    63 //
       
    64 CAknTree::~CAknTree()
       
    65     {
       
    66     delete iOrdering; iOrdering = NULL;
       
    67     iCustomOrdering = NULL;
       
    68     iObservers.Close();
       
    69     iItems.Close();
       
    70     iIcons.ResetAndDestroy();
       
    71     delete iMarquee; iMarquee = NULL;
       
    72     iMarqueeItem = NULL;
       
    73     }
       
    74 
       
    75 
       
    76 // ---------------------------------------------------------------------------
       
    77 // Id for the given item.
       
    78 // ---------------------------------------------------------------------------
       
    79 //
       
    80 TAknTreeItemID CAknTree::Id( const CAknTreeItem* aItem ) const
       
    81     {
       
    82     if ( aItem == this )
       
    83         {
       
    84         return KAknTreeIIDRoot;
       
    85         }
       
    86     else
       
    87         {
       
    88         return reinterpret_cast<TInt>( aItem );
       
    89         }
       
    90     }
       
    91 
       
    92 
       
    93 // ---------------------------------------------------------------------------
       
    94 // Sets ordering for tree items. Previously set ordering is deleted and
       
    95 // customized ordering interface discarded.
       
    96 // ---------------------------------------------------------------------------
       
    97 //
       
    98 void CAknTree::SetOrdering( CAknTreeOrdering* aOrdering, TBool aDrawNow )
       
    99     {
       
   100     delete iOrdering;
       
   101     iOrdering = aOrdering;
       
   102 
       
   103     iCustomOrdering = NULL;
       
   104 
       
   105     Sort( aDrawNow );
       
   106     }
       
   107 
       
   108 
       
   109 // ---------------------------------------------------------------------------
       
   110 // Sets custom ordering for tree items.
       
   111 // ---------------------------------------------------------------------------
       
   112 //
       
   113 void CAknTree::SetCustomOrdering( MAknCustomTreeOrdering* aOrdering,
       
   114     TBool aDrawNow )
       
   115     {
       
   116     iCustomOrdering = aOrdering;
       
   117 
       
   118     delete iOrdering;
       
   119     iOrdering = NULL;
       
   120 
       
   121     Sort( aDrawNow );
       
   122     }
       
   123 
       
   124 
       
   125 // ---------------------------------------------------------------------------
       
   126 // Sorts the specified tree node.
       
   127 // ---------------------------------------------------------------------------
       
   128 //
       
   129 void CAknTree::Sort( TAknTreeItemID aNode, TBool aSortDescendants,
       
   130     TBool aDrawNow )
       
   131     {
       
   132     // The sorting can be done only when ordering is set for the tree.
       
   133     if ( iCustomOrdering || iOrdering )
       
   134         {
       
   135         CAknTreeNode* node = Node( aNode );
       
   136         node->Sort();
       
   137         if ( aSortDescendants )
       
   138             {
       
   139             // Iterate through the descendants of the node and sort
       
   140             // each descendant node separately.
       
   141             TAknTreeIterator iterator( node, NULL );
       
   142             while ( iterator.HasNext() )
       
   143                 {
       
   144                 node = iterator.Next()->Node();
       
   145                 if ( node )
       
   146                     {
       
   147                     node->Sort();
       
   148                     }
       
   149                 }
       
   150             }
       
   151         }
       
   152 
       
   153     NotifyObservers( MAknTreeObserver::ETreeSorted, this, aDrawNow );
       
   154     }
       
   155 
       
   156 
       
   157 // ---------------------------------------------------------------------------
       
   158 // Compares two tree list items.
       
   159 // ---------------------------------------------------------------------------
       
   160 //
       
   161 TInt CAknTree::Compare( const CAknTreeItem& aFirst,
       
   162     const CAknTreeItem& aSecond ) const
       
   163     {
       
   164     TInt value = NULL;
       
   165     if ( iCustomOrdering )
       
   166         {
       
   167         value = iCustomOrdering->Compare( Id( &aFirst ), Id( &aSecond ) );
       
   168         }
       
   169     else if ( iOrdering )
       
   170         {
       
   171         value = iOrdering->Compare( aFirst, aSecond );
       
   172         }
       
   173     else
       
   174         {
       
   175         TInt first = KMaxTInt;
       
   176         TInt second = KMaxTInt;
       
   177         if ( aFirst.Parent() )
       
   178             {
       
   179             first = aFirst.Parent()->Index( &aFirst );
       
   180             }
       
   181         if  ( aSecond.Parent() )
       
   182             {
       
   183             second = aSecond.Parent()->Index( &aSecond );
       
   184             }
       
   185         value = first - second;
       
   186         }
       
   187     return value;
       
   188     }
       
   189 
       
   190 
       
   191 // ---------------------------------------------------------------------------
       
   192 // Returns the number of items in the tree.
       
   193 // ---------------------------------------------------------------------------
       
   194 //
       
   195 TInt CAknTree::ItemCount() const
       
   196     {
       
   197     return iItems.Count();
       
   198     }
       
   199 
       
   200 
       
   201 // ---------------------------------------------------------------------------
       
   202 // Returns the number of visible items in the tree.
       
   203 // ---------------------------------------------------------------------------
       
   204 //
       
   205 TInt CAknTree::VisibleItemCount() const
       
   206     {
       
   207     return VisibleDescendantCount();
       
   208     }
       
   209 
       
   210 
       
   211 // ---------------------------------------------------------------------------
       
   212 // Returns the index of specified item. The index equals to the number of
       
   213 // tree items in the tree structure before the specified item.
       
   214 // The value KErrNotFound is returned, if the specified item is not found,
       
   215 // and this applies also to the root node.
       
   216 // ---------------------------------------------------------------------------
       
   217 //
       
   218 TInt CAknTree::ItemIndex( const CAknTreeItem* aItem ) const
       
   219     {
       
   220     TInt count = KErrNotFound; // ( -1 )
       
   221     if ( iItems.FindInAddressOrder( aItem ) >= 0 )
       
   222         {
       
   223         const CAknTreeItem* item = aItem;
       
   224         const CAknTreeNode* parent = item->Parent();
       
   225         while ( parent )
       
   226             {
       
   227             // Add the number of descendants of each sibling preceeding the
       
   228             // item to the count.
       
   229             const TInt index = parent->Index( item );
       
   230             __ASSERT_DEBUG( index >= 0, User::Invariant() );
       
   231             for ( TInt ii = 0; ii < index; ++ii )
       
   232                 {
       
   233                 const CAknTreeNode* node = parent->Child( ii )->Node();
       
   234                 if ( node )
       
   235                     {
       
   236                     count += node->DescendantCount();
       
   237                     }
       
   238                 }
       
   239 
       
   240             // Add the item and its preceeding siblings to the count.
       
   241             count += index + 1;
       
   242 
       
   243             item = parent;
       
   244             parent = item->Parent();
       
   245             }
       
   246         }
       
   247     return count;
       
   248     }
       
   249 
       
   250 
       
   251 // ---------------------------------------------------------------------------
       
   252 // Similar to ItemIndex, but returns the index from subset of items that
       
   253 // belong to expanded part of the tree.
       
   254 // ---------------------------------------------------------------------------
       
   255 //
       
   256 TInt CAknTree::VisibleItemIndex( const CAknTreeItem* aItem ) const
       
   257     {
       
   258     TInt count = KErrNotFound; // ( -1 )
       
   259     if ( iItems.FindInAddressOrder( aItem ) >= 0 )
       
   260         {
       
   261         const CAknTreeItem* item = aItem;
       
   262         const CAknTreeNode* parent = item->Parent();
       
   263         while ( parent )
       
   264             {
       
   265             if ( !parent->IsExpanded() )
       
   266                 {
       
   267                 return KErrNotFound;
       
   268                 }
       
   269 
       
   270             // Add the number of visible descentants of each sibling preceeding
       
   271             // the item to the count.
       
   272             const TInt index = parent->Index( item );
       
   273             __ASSERT_DEBUG( index >= 0, User::Invariant() );
       
   274             for ( TInt ii = 0; ii < index; ++ii )
       
   275                 {
       
   276                 const CAknTreeNode* node = parent->Child( ii )->Node();
       
   277                 if ( node )
       
   278                     {
       
   279                     count += node->VisibleDescendantCount();
       
   280                     }
       
   281                 }
       
   282 
       
   283             // Add the item and its preceeding siblings to the count.
       
   284             count += index + 1;
       
   285 
       
   286             // All ancestors of specified item has to be expanded in order to
       
   287             // the item to be in expanded tree structure.
       
   288             if ( parent->IsExpanded() )
       
   289                 {
       
   290                 item = parent;
       
   291                 parent = item->Parent();
       
   292                 }
       
   293             else
       
   294                 {
       
   295                 // Specified item is not visible, KErrNotFound returned.
       
   296                 parent = NULL;
       
   297                 count = KErrNotFound;
       
   298                 }
       
   299             }
       
   300         }
       
   301     return count;
       
   302     }
       
   303 
       
   304 
       
   305 // ---------------------------------------------------------------------------
       
   306 // Returns the tree item at the specified index of the expanded tree.
       
   307 // ---------------------------------------------------------------------------
       
   308 //
       
   309 CAknTreeItem* CAknTree::VisibleItem( TInt aIndex ) const
       
   310     {
       
   311     if ( aIndex < 0 || aIndex >= iItems.Count() )
       
   312         {
       
   313         return NULL;
       
   314         }
       
   315 
       
   316     TAknTreeIterator iterator = Iterator();
       
   317     while( aIndex && iterator.HasNext() )
       
   318         {
       
   319         iterator.Next();
       
   320         --aIndex;
       
   321         }
       
   322 
       
   323     return iterator.Next();
       
   324     }
       
   325 
       
   326 
       
   327 // ---------------------------------------------------------------------------
       
   328 // Returns the depth of the tree. Iterates through the whole tree structure.
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 TInt CAknTree::Depth() const
       
   332     {
       
   333     TAknTreeIterator iterator = Iterator();
       
   334     TInt depth = 0;
       
   335     while ( iterator.HasNext() )
       
   336         {
       
   337         CAknTreeItem* item = iterator.Next();
       
   338         depth = Max( depth, item->Level() );
       
   339         }
       
   340     return depth;
       
   341     }
       
   342 
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // Finds the specified item from the sorted array of tree items. The constants
       
   346 // KAknTreeIIDRoot and KAknTreeIIDNone are handled as special cases.
       
   347 // 
       
   348 // Note: Recently used items could be cached somehow to eliminate the need to
       
   349 // lookup them from the table when consecutive calls refer to the same items,
       
   350 // for example, when adding several items to the same node.
       
   351 // ---------------------------------------------------------------------------
       
   352 //
       
   353 TInt CAknTree::GetItem( TAknTreeItemID aItemId, CAknTreeItem*& aItem ) const
       
   354     {
       
   355     TInt error = KErrNone;
       
   356     if ( aItemId == KAknTreeIIDRoot )
       
   357         {
       
   358         aItem = const_cast<CAknTree*>( this );
       
   359         }
       
   360     else if ( aItemId == KAknTreeIIDNone )
       
   361         {
       
   362         error = KErrNotFound;
       
   363         }
       
   364     else
       
   365         {
       
   366         TInt index = iItems.FindInAddressOrder(
       
   367             reinterpret_cast<CAknTreeItem*>( aItemId ) );
       
   368         if ( index == KErrNotFound )
       
   369             {
       
   370             error = KErrNotFound;
       
   371             }
       
   372         else
       
   373             {
       
   374             aItem = iItems[index];
       
   375             }
       
   376         }
       
   377     return error;
       
   378     }
       
   379 
       
   380 
       
   381 // ---------------------------------------------------------------------------
       
   382 // Retrieves an item from the tree structure. Panics if the item is not found.
       
   383 // ---------------------------------------------------------------------------
       
   384 //
       
   385 CAknTreeItem* CAknTree::Item( TAknTreeItemID aItemId ) const
       
   386     {
       
   387     CAknTreeItem* item = NULL;
       
   388     TInt error = GetItem( aItemId, item );
       
   389     __ASSERT_ALWAYS( item && !error, Panic( EAknHListPanicInvalidItemID ) );
       
   390     return item;
       
   391     }
       
   392 
       
   393 
       
   394 // ---------------------------------------------------------------------------
       
   395 // Retrieves a node from the tree structure. Panics if the node is not found,
       
   396 // or if the specified item is not a node.
       
   397 // ---------------------------------------------------------------------------
       
   398 //
       
   399 CAknTreeNode* CAknTree::Node( TAknTreeItemID aNodeId ) const
       
   400     {
       
   401     CAknTreeNode* node = Item( aNodeId )->Node();
       
   402     __ASSERT_ALWAYS( node, Panic( EAknHListPanicInvalidItemType ) );
       
   403     return node;
       
   404     }
       
   405 
       
   406 
       
   407 // ---------------------------------------------------------------------------
       
   408 // Adds an item to the tree structure.
       
   409 // ---------------------------------------------------------------------------
       
   410 //
       
   411 TAknTreeItemID CAknTree::AddItemL( CAknTreeItem* aItem,
       
   412     TAknTreeItemID aParent, TBool aDrawNow )
       
   413     {
       
   414     __ASSERT_DEBUG( aItem, User::Invariant() );
       
   415 
       
   416     // Add item to the specified parent node.
       
   417     CAknTreeNode* parent = Node( aParent );
       
   418 
       
   419     if ( iOrdering )
       
   420         {
       
   421         // Let ordering determine the position of the new child.
       
   422         parent->AddChildL( aItem );
       
   423         }
       
   424     else
       
   425         {
       
   426         // Append to the end, as custom ordering cannot be used to determine
       
   427         // the correct position when inserting new items to the tree.
       
   428         parent->AddChildL( aItem, parent->ChildCount() );
       
   429         }
       
   430 
       
   431     // Store pointer also in lookup table.
       
   432     TInt error = iItems.InsertInAddressOrder( aItem );
       
   433     if ( error )
       
   434         {
       
   435         parent->RemoveChild( aItem );
       
   436         User::Leave( error );
       
   437         }
       
   438 
       
   439     aItem->SetParent( parent );
       
   440 
       
   441     NotifyObservers( MAknTreeObserver::EItemAdded, aItem, aDrawNow );
       
   442 
       
   443     return Id( aItem );
       
   444     }
       
   445 
       
   446 
       
   447 // ---------------------------------------------------------------------------
       
   448 // Moves the specified item to specified target node. The method has to make
       
   449 // sure that the target node is not a descendant of the moved item in order
       
   450 // to keep the tree structure intact.
       
   451 // ---------------------------------------------------------------------------
       
   452 //
       
   453 void CAknTree::MoveItemL( TAknTreeItemID aItem, TAknTreeItemID aTargetNode,
       
   454     TBool aDrawNow )
       
   455     {
       
   456     CAknTreeItem* item = Item( aItem );
       
   457     CAknTreeNode* targetNode = Node( aTargetNode );
       
   458 
       
   459     // The current parent of the moved item.
       
   460     CAknTreeNode* parent = item->Parent();
       
   461 
       
   462     // Move is necessary only when target node differs from current node.
       
   463     if ( targetNode != parent )
       
   464         {
       
   465         // Check that the moved item is neither the target node nor an ancestor
       
   466         // of target node. This should also ensure that the root is not moved.
       
   467         CAknTreeNode* ancestor = targetNode;
       
   468         while ( ancestor )
       
   469             {
       
   470             if ( ancestor == item )
       
   471                 {
       
   472                 User::Leave( KErrArgument );
       
   473                 }
       
   474             ancestor = ancestor->Parent();
       
   475             }
       
   476 
       
   477         // Move the item to the target node.
       
   478         targetNode->AddChildL( item );
       
   479         item->SetParent( targetNode );
       
   480         if ( parent )
       
   481             {
       
   482             parent->RemoveChild( item );
       
   483             }
       
   484         
       
   485         NotifyObservers( MAknTreeObserver::EItemMoved, item, aDrawNow );
       
   486         }
       
   487     }
       
   488 
       
   489 
       
   490 // ---------------------------------------------------------------------------
       
   491 // Removes an item from the tree structure. If the specified item is not
       
   492 // found, method is paniced with panic code EAknHListPanicInvalidItemID.
       
   493 //
       
   494 // When removed item is a node with descendants, the node and its descendants
       
   495 // are removed from the list separately and each removal is also reported
       
   496 // separately to the observers.
       
   497 //
       
   498 // Note: Observers are notified of the removal before the item is actually
       
   499 // removed from the tree and deleted, so that the observers can still query
       
   500 // the item's position in the tree.
       
   501 // ---------------------------------------------------------------------------
       
   502 //
       
   503 void CAknTree::RemoveItem( TAknTreeItemID aItem, TBool aDrawNow )
       
   504     {
       
   505     // Get the item from the array.    
       
   506     CAknTreeItem* item = Item( aItem );
       
   507     
       
   508     TBool drawNow( EFalse );
       
   509 
       
   510     // Remove from array and delete the descendants of node non-recursively.
       
   511     if ( item->IsNode() )
       
   512         {
       
   513         TAknTreeIterator iterator = Iterator( item->Node(), NULL );
       
   514         CAknTreeItem* current = iterator.Last();
       
   515         iterator.SetCurrent( current ); 
       
   516         while ( current )
       
   517             {
       
   518             CAknTreeItem* previous = iterator.Previous();
       
   519             if ( previous == NULL)
       
   520             	{
       
   521             	drawNow = aDrawNow;
       
   522             	}
       
   523 
       
   524             // Notify tree observers of removal before the item is removed.
       
   525             NotifyObservers( MAknTreeObserver::EItemRemoveBegin, current, EFalse );
       
   526 
       
   527             // Remove item from the table.
       
   528             TInt index = iItems.FindInAddressOrder( current );
       
   529             __ASSERT_DEBUG( index >= 0, User::Invariant()  );
       
   530             iItems.Remove( index );
       
   531 
       
   532             // Remove item from its parent node.
       
   533             CAknTreeNode* parent = current->Parent();
       
   534             __ASSERT_DEBUG( parent, User::Invariant() );
       
   535             parent->RemoveChild( current );
       
   536             current->SetParent( NULL );
       
   537 
       
   538             __ASSERT_DEBUG( current->IsLeaf() || 
       
   539                 current->Node()->ChildCount() == 0, User::Invariant() );
       
   540 
       
   541             // Notify tree observers when the item has been removed.
       
   542             NotifyObservers( MAknTreeObserver::EItemRemoveEnd, current, drawNow );
       
   543 
       
   544             // Notify also tree list observers of removal.
       
   545             iList.NotifyObservers( MAknTreeListObserver::EItemRemoved,
       
   546                 Id( current ) );
       
   547 
       
   548             delete current;
       
   549             current = previous;
       
   550             }
       
   551         }
       
   552 
       
   553     // Remove the specified item, unless it is the root node.
       
   554     if ( item != this )
       
   555         {
       
   556         // Notify tree observers before removing the item.
       
   557         NotifyObservers( MAknTreeObserver::EItemRemoveBegin, item, EFalse );
       
   558 
       
   559         // Remove the item from array and from the tree and delete it.
       
   560         TInt index = iItems.FindInAddressOrder( item );
       
   561         __ASSERT_DEBUG( index >= 0, User::Invariant() );
       
   562         iItems.Remove( index );
       
   563 
       
   564         CAknTreeNode* parent = item->Parent();
       
   565         __ASSERT_DEBUG( parent, User::Invariant() );
       
   566         parent->RemoveChild( item );
       
   567         item->SetParent( NULL );
       
   568 
       
   569         __ASSERT_DEBUG( item->IsLeaf() || item->Node()->ChildCount() == 0,
       
   570             User::Invariant() );
       
   571 
       
   572         // Notify tree observers after the item has been removed.
       
   573         NotifyObservers( MAknTreeObserver::EItemRemoveEnd, item, aDrawNow );
       
   574 
       
   575         // Notify also tree list observers of removal.
       
   576         iList.NotifyObservers( MAknTreeListObserver::EItemRemoved,
       
   577             Id( item ) );
       
   578 
       
   579         delete item;
       
   580         }
       
   581     }
       
   582 
       
   583 
       
   584 // ---------------------------------------------------------------------------
       
   585 // Expands the specified node.
       
   586 // ---------------------------------------------------------------------------
       
   587 //
       
   588 void CAknTree::ExpandNode( TAknTreeItemID aNode, TBool aDrawNow )
       
   589     {
       
   590     CAknTreeNode* node = Node( aNode );
       
   591     DoExpandNode( node, aDrawNow );
       
   592     }
       
   593 
       
   594 
       
   595 // ---------------------------------------------------------------------------
       
   596 // Collapses the specified node and removes the children from collapsed node
       
   597 // that are not set perisitent or do not contain any persistent descendants.
       
   598 // ---------------------------------------------------------------------------
       
   599 //
       
   600 void CAknTree::CollapseNode( TAknTreeItemID aNode, TBool aDrawNow )
       
   601     {
       
   602     CAknTreeNode* node = Node( aNode );
       
   603 
       
   604     node->Collapse();
       
   605     iList.NotifyObservers( MAknTreeListObserver::ENodeCollapsed, aNode );
       
   606     NotifyObservers( MAknTreeObserver::ENodeCollapsed, node, aDrawNow );
       
   607 
       
   608     if ( aNode != KAknTreeIIDRoot )
       
   609         {
       
   610         // Remove all the children from the node that are not persistent or
       
   611         // marked and do not contain any persistent or marked descendants.
       
   612         for ( TInt ii = node->ChildCount() - 1; ii >= 0; --ii )
       
   613             {
       
   614             CAknTreeItem* item = node->Child( ii );
       
   615             __ASSERT_DEBUG( item, User::Invariant() );
       
   616             if ( item->IsRemovableFromCollapsedNode() )
       
   617                 {
       
   618                 RemoveItem( Id( item ), EFalse );
       
   619                 }
       
   620             }
       
   621         }
       
   622     }
       
   623 
       
   624 
       
   625 // ---------------------------------------------------------------------------
       
   626 // Checks whether the specified node is expanded.
       
   627 // ---------------------------------------------------------------------------
       
   628 //
       
   629 TBool CAknTree::IsExpanded( TAknTreeItemID aNode ) const
       
   630     {
       
   631     return Node( aNode )->IsExpanded();
       
   632     }
       
   633 
       
   634 
       
   635 // ---------------------------------------------------------------------------
       
   636 // Returns the child count for the specified node.
       
   637 // ---------------------------------------------------------------------------
       
   638 //
       
   639 TInt CAknTree::ChildCount( TAknTreeItemID aNode ) const
       
   640     {
       
   641     return Node( aNode )->ChildCount();
       
   642     }
       
   643 
       
   644 
       
   645 // ---------------------------------------------------------------------------
       
   646 // Returns the item ID of specified child for a tree node.
       
   647 // ---------------------------------------------------------------------------
       
   648 //
       
   649 TAknTreeItemID CAknTree::Child( TAknTreeItemID aNode, TInt aIndex ) const
       
   650     {
       
   651     return Id( Node( aNode )->Child( aIndex ) );
       
   652     }
       
   653 
       
   654 
       
   655 // ---------------------------------------------------------------------------
       
   656 // Returns the item ID of a parent of specified item.
       
   657 // ---------------------------------------------------------------------------
       
   658 //
       
   659 TAknTreeItemID CAknTree::Parent( TAknTreeItemID aItem ) const
       
   660     {
       
   661     return Id( Item( aItem )->Parent() );
       
   662     }
       
   663 
       
   664 
       
   665 // ---------------------------------------------------------------------------
       
   666 // Adds a tree observer.
       
   667 // ---------------------------------------------------------------------------
       
   668 //
       
   669 void CAknTree::AddObserverL( MAknTreeObserver* aObserver )
       
   670     {
       
   671     iObservers.InsertInAddressOrderL( aObserver );
       
   672     }
       
   673 
       
   674 
       
   675 // ---------------------------------------------------------------------------
       
   676 // Removes a tree observer.
       
   677 // ---------------------------------------------------------------------------
       
   678 //
       
   679 TInt CAknTree::RemoveObserver( MAknTreeObserver* aObserver )
       
   680     {
       
   681     TInt index = iObservers.FindInAddressOrder( aObserver );
       
   682     if ( index != KErrNotFound )
       
   683         {
       
   684         iObservers.Remove( index );
       
   685         return KErrNone;
       
   686         }
       
   687     else
       
   688         {
       
   689         return KErrNotFound;
       
   690         }
       
   691     }
       
   692 
       
   693 
       
   694 // ---------------------------------------------------------------------------
       
   695 // Checks whether the specified item is marked.
       
   696 // ---------------------------------------------------------------------------
       
   697 //
       
   698 TBool CAknTree::IsMarked( TAknTreeItemID aItem ) const
       
   699     {
       
   700     return Item( aItem )->IsMarked();
       
   701     }
       
   702 
       
   703 
       
   704 // ---------------------------------------------------------------------------
       
   705 // Sets the specified item marked or unmarked.
       
   706 // ---------------------------------------------------------------------------
       
   707 //
       
   708 void CAknTree::SetMarked( TAknTreeItemID aItem, TBool aMarked, TBool aDrawNow )
       
   709     {
       
   710     CAknTreeItem* item = Item( aItem );
       
   711     if ( item->IsMarkable() )
       
   712         {        
       
   713         if ( item->IsNode() )
       
   714             {
       
   715             // When specified item is a node, the same marking is set to
       
   716             // every descendant as well.
       
   717             TAknTreeIterator iterator = Iterator( item->Node(), NULL );
       
   718             while ( iterator.HasNext() )
       
   719                 {
       
   720                 iterator.Next()->SetMarked( aMarked );
       
   721                 }
       
   722             }
       
   723 
       
   724         item->SetMarked( aMarked );
       
   725         
       
   726         if ( aMarked == EFalse)
       
   727         	{
       
   728         	CAknTreeNode* parent = item->Parent();
       
   729         	if ( parent && parent->IsNode() && parent->IsMarkable() && parent->IsMarked() )
       
   730         		{
       
   731         		TAknTreeIterator iterator = Iterator( parent->Node(), NULL );
       
   732             	TBool marked = EFalse;	
       
   733             	
       
   734             	while ( iterator.HasNext() )
       
   735                 	{
       
   736                 	CAknTreeItem* item = iterator.Next();
       
   737                 	if ( item->IsMarkable() && item->IsMarked() )
       
   738                 		{
       
   739                 		marked = ETrue;
       
   740                 		break;
       
   741                 		}
       
   742                 	}
       
   743                 // all items under the parent are unmarked, unmark parent	
       
   744         		if ( !marked )
       
   745         			{
       
   746         			parent->SetMarked( EFalse );
       
   747         			}
       
   748         		
       
   749         		}
       
   750         	
       
   751         	}
       
   752         
       
   753         iList.NotifyObservers( aMarked ? MAknTreeListObserver::EItemMarked :
       
   754             MAknTreeListObserver::EItemUnmarked, Id( item ) );
       
   755         NotifyObservers( MAknTreeObserver::EItemModified, item, aDrawNow );        
       
   756         }
       
   757     }
       
   758 
       
   759 
       
   760 // ---------------------------------------------------------------------------
       
   761 // Enables/disables marking for specified list item.
       
   762 // ---------------------------------------------------------------------------
       
   763 //
       
   764 void CAknTree::EnableMarking( TAknTreeItemID aItem, TBool aEnable )
       
   765     {
       
   766     CAknTreeItem* item = Item( aItem );
       
   767     item->SetMarkable( aEnable );
       
   768     }
       
   769 
       
   770 
       
   771 // ---------------------------------------------------------------------------
       
   772 // Gets all the marked items from the specified node to the given array.
       
   773 // ---------------------------------------------------------------------------
       
   774 //
       
   775 void CAknTree::GetMarkedItemsL( TAknTreeItemID aNode,
       
   776     RArray<TAknTreeItemID>& aMarkedItems ) const
       
   777     {
       
   778     aMarkedItems.Reset();
       
   779     if ( aNode == KAknTreeIIDRoot )
       
   780         {
       
   781         // Get marked items from the tree by iterating through array.
       
   782         CAknTreeItem* item = NULL;
       
   783         const TInt count = iItems.Count();
       
   784         for ( TInt ii = 0; ii < count; ++ii )
       
   785             {
       
   786             item = iItems[ii];
       
   787             __ASSERT_DEBUG( item, User::Invariant() );
       
   788             if ( item->IsMarked() )
       
   789                 {
       
   790                 aMarkedItems.AppendL( Id( item ) );
       
   791                 }
       
   792             }
       
   793         }
       
   794     else
       
   795         {
       
   796         // Get marked items only from the specified node with iterator.
       
   797         TAknTreeIterator iterator( Node( aNode ), NULL );
       
   798         CAknTreeItem* item = NULL;
       
   799         while ( iterator.HasNext() )
       
   800             {
       
   801             item = iterator.Next();
       
   802             __ASSERT_DEBUG( item, User::Invariant() );
       
   803             if ( item->IsMarked() )
       
   804                 {
       
   805                 aMarkedItems.AppendL( Id( item ) );
       
   806                 }
       
   807             }
       
   808         }
       
   809     }
       
   810 
       
   811 
       
   812 // ---------------------------------------------------------------------------
       
   813 // Checks whether the specified node is empty.
       
   814 // ---------------------------------------------------------------------------
       
   815 //
       
   816 TBool CAknTree::IsEmpty( TAknTreeItemID aNode ) const
       
   817     {
       
   818     return Node( aNode )->IsEmpty();
       
   819     }
       
   820 
       
   821 
       
   822 // ---------------------------------------------------------------------------
       
   823 // Sets whether the node appears as non-empty when it is empty.
       
   824 // ---------------------------------------------------------------------------
       
   825 //
       
   826 void CAknTree::SetNonEmpty( TAknTreeItemID aNode, TBool aNonEmpty,
       
   827     TBool aDrawNow )
       
   828     {
       
   829     CAknTreeNode* node = Node( aNode );
       
   830     node->SetNonEmpty( aNonEmpty );
       
   831     NotifyObservers( MAknTreeObserver::EItemModified, node, aDrawNow );
       
   832     }
       
   833 
       
   834 
       
   835 // ---------------------------------------------------------------------------
       
   836 // Checks whether the specified item is persistent.
       
   837 // ---------------------------------------------------------------------------
       
   838 //
       
   839 TBool CAknTree::IsPersistent( TAknTreeItemID aItem ) const
       
   840     {
       
   841     return Item( aItem )->IsPersistent();
       
   842     }
       
   843 
       
   844 
       
   845 // ---------------------------------------------------------------------------
       
   846 // Sets the specified item persistent or non-persistent.
       
   847 // ---------------------------------------------------------------------------
       
   848 //
       
   849 void CAknTree::SetPersistent( TAknTreeItemID aItem, TBool aPersistent )
       
   850     {
       
   851     Item( aItem )->SetPersistent( aPersistent );
       
   852     }
       
   853 
       
   854 
       
   855 // ---------------------------------------------------------------------------
       
   856 // Returns iterator for the expanded tree structure.
       
   857 // ---------------------------------------------------------------------------
       
   858 //
       
   859 TAknTreeIterator CAknTree::Iterator() const
       
   860     {
       
   861     return TAknTreeIterator( const_cast<CAknTree*>( this ),
       
   862         KAknSkipCollapsedNodeContents );
       
   863     }
       
   864 
       
   865 
       
   866 // ---------------------------------------------------------------------------
       
   867 // Returns iterator for the specified node.
       
   868 // ---------------------------------------------------------------------------
       
   869 //
       
   870 TAknTreeIterator CAknTree::Iterator( CAknTreeNode* aNode, TUint aFlags ) const
       
   871     {
       
   872     return TAknTreeIterator( aNode, aFlags );
       
   873     }
       
   874 
       
   875 
       
   876 // ---------------------------------------------------------------------------
       
   877 // Notifies the observers that an item in the tree has been modified.
       
   878 // ---------------------------------------------------------------------------
       
   879 //
       
   880 void CAknTree::ItemModified( CAknTreeItem* aItem )
       
   881     {
       
   882     NotifyObservers( MAknTreeObserver::EItemModified, aItem, ETrue );
       
   883     }
       
   884 
       
   885 
       
   886 // ---------------------------------------------------------------------------
       
   887 // Adds an icon to the tree and returns the index of created icon.
       
   888 // ---------------------------------------------------------------------------
       
   889 //
       
   890 TInt CAknTree::AddIconL( const TAknsItemID& aId, const TDesC& aFilename,
       
   891     TInt aBitmapId, TInt aMaskId, TScaleMode aScaleMode )
       
   892     {
       
   893     TInt newIconId = AvailableIconId();
       
   894     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( newIconId, aId,
       
   895         aFilename, aBitmapId, aMaskId, aScaleMode );
       
   896     AddIconL( icon );
       
   897     CleanupStack::Pop( icon );
       
   898     return newIconId;
       
   899     }
       
   900 
       
   901 
       
   902 // ---------------------------------------------------------------------------
       
   903 // Adds an icon to the tree and returns the index of created icon.
       
   904 // ---------------------------------------------------------------------------
       
   905 //
       
   906 TInt CAknTree::AddIconL( CFbsBitmap* aIcon, CFbsBitmap* aMask, 
       
   907     TBool aTransferOwnership, TScaleMode aScaleMode )
       
   908     {
       
   909     TInt newIconId = AvailableIconId();
       
   910     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( newIconId, aIcon, aMask,
       
   911         aTransferOwnership, aScaleMode );
       
   912     AddIconL( icon );
       
   913     CleanupStack::Pop( icon );
       
   914     return newIconId;
       
   915     }
       
   916 
       
   917 
       
   918 // ---------------------------------------------------------------------------
       
   919 // Adds colored icon to the tree.
       
   920 // ---------------------------------------------------------------------------
       
   921 //
       
   922 TInt CAknTree::AddColorIconL( const TAknsItemID& aId,
       
   923     const TAknsItemID& aColorId, TInt aColorIndex, const TDesC& aFilename,
       
   924     TInt aBitmapId, TInt aMaskId, TRgb aDefaultColor, TScaleMode aScaleMode )
       
   925     {
       
   926     TInt newIconId = AvailableIconId();
       
   927     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( newIconId, aId,
       
   928         aColorId, aColorIndex, aFilename, aBitmapId, aMaskId, aDefaultColor,
       
   929         aScaleMode );
       
   930     AddIconL( icon );
       
   931     CleanupStack::Pop( icon );
       
   932     return newIconId;
       
   933     }
       
   934 
       
   935 
       
   936 // ---------------------------------------------------------------------------
       
   937 // Sets icon for specified ID.
       
   938 // ---------------------------------------------------------------------------
       
   939 //
       
   940 void CAknTree::SetIconL( TInt aIconId, const TAknsItemID& aId,
       
   941     const TDesC& aFilename, TInt aBitmapId, TInt aMaskId,
       
   942     TScaleMode aScaleMode )
       
   943     {
       
   944     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( aIconId, aId, aFilename,
       
   945         aBitmapId, aMaskId, aScaleMode );
       
   946     AddIconL( icon );
       
   947     CleanupStack::Pop( icon );
       
   948     }
       
   949 
       
   950 
       
   951 void CAknTree::SetIconL( TInt aIconId, CFbsBitmap* aIcon, CFbsBitmap* aMask,
       
   952     TBool aTransferOwnership, TScaleMode aScaleMode )
       
   953     {
       
   954     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( aIconId, aIcon, aMask,
       
   955         aTransferOwnership, aScaleMode );
       
   956     AddIconL( icon );
       
   957     CleanupStack::Pop( icon );
       
   958     }
       
   959 
       
   960 
       
   961 // ---------------------------------------------------------------------------
       
   962 // Sets color icon for specified ID.
       
   963 // ---------------------------------------------------------------------------
       
   964 //
       
   965 void CAknTree::SetColorIconL( TInt aIconId, const TAknsItemID& aId,
       
   966     const TAknsItemID& aColorId, TInt aColorIndex, const TDesC& aFilename,
       
   967     TInt aBitmapId, TInt aMaskId, TRgb aDefaultColor, TScaleMode aScaleMode )
       
   968     {
       
   969     CAknTreeListIcon* icon = CAknTreeListIcon::NewLC( aIconId, aId, aColorId,
       
   970         aColorIndex, aFilename, aBitmapId, aMaskId, aDefaultColor,
       
   971         aScaleMode );
       
   972     AddIconL( icon );
       
   973     CleanupStack::Pop( icon );
       
   974     }
       
   975 
       
   976 
       
   977 // ---------------------------------------------------------------------------
       
   978 // Removes previously added icon from the tree.
       
   979 // ---------------------------------------------------------------------------
       
   980 //
       
   981 void CAknTree::RemoveIconL( TInt aIconId )
       
   982     {
       
   983     // Pre-defined icons constructed by the tree cannot be removed.
       
   984     if ( aIconId <= EPreDefinedIconIdRange )
       
   985         {
       
   986         User::Leave( KErrArgument );
       
   987         }
       
   988 
       
   989     TInt index = iIcons.FindInOrder( aIconId, CAknTreeListIcon::CompareId );
       
   990     if ( index != KErrNotFound )
       
   991         {
       
   992         delete iIcons[index];
       
   993         iIcons.Remove( index );
       
   994         }
       
   995     }
       
   996 
       
   997 
       
   998 // ---------------------------------------------------------------------------
       
   999 // Returns pointer to the requested icon.
       
  1000 // ---------------------------------------------------------------------------
       
  1001 //
       
  1002 CAknTreeListIcon* CAknTree::Icon( TInt aIconId ) const
       
  1003     {
       
  1004     CAknTreeListIcon* icon = NULL;
       
  1005     TInt index = iIcons.FindInOrder( aIconId, CAknTreeListIcon::CompareId );
       
  1006     if ( index >= NULL )
       
  1007         {
       
  1008         icon = iIcons[index];
       
  1009         }
       
  1010     return icon;
       
  1011     }
       
  1012 
       
  1013 
       
  1014 // ---------------------------------------------------------------------------
       
  1015 // Draws the specified icon.
       
  1016 // ---------------------------------------------------------------------------
       
  1017 //
       
  1018 TInt CAknTree::DrawIcon( TInt aIconId, const TSize& aSize, CWindowGc& aGc,
       
  1019     const TPoint& aPoint, const TRect& aSourceRect )
       
  1020     {
       
  1021     TInt value = KErrNotFound;
       
  1022     CAknTreeListIcon* icon = Icon( aIconId );
       
  1023     if ( icon && icon->Bitmap() )
       
  1024         {
       
  1025         icon->SetSize( aSize );
       
  1026         aGc.BitBltMasked( aPoint, icon->Bitmap(), aSourceRect,
       
  1027             icon->Mask(), ETrue );
       
  1028         value = KErrNone;
       
  1029         }
       
  1030     return value;
       
  1031     }
       
  1032 
       
  1033 
       
  1034 // ---------------------------------------------------------------------------
       
  1035 // Draws the given text string.
       
  1036 // ---------------------------------------------------------------------------
       
  1037 //
       
  1038 void CAknTree::DrawText( CWindowGc& aGc, const TRect& aRect,
       
  1039     const TAknTextComponentLayout& aTextLayout, const TDesC& aText,
       
  1040     const CFont* aFont, const CAknTreeItem* aItem, TBool aFocused,
       
  1041     TBool aMarquee )
       
  1042     {
       
  1043     TRgb textColor;
       
  1044     TAknsQsnTextColorsIndex index = 
       
  1045         aFocused ? EAknsCIQsnTextColorsCG10 : EAknsCIQsnTextColorsCG6;
       
  1046     AknsUtils::GetCachedColor( AknsUtils::SkinInstance(), textColor,
       
  1047         KAknsIIDQsnTextColors, index );
       
  1048 
       
  1049     TAknLayoutText layoutText;
       
  1050     layoutText.LayoutText( aRect, aTextLayout.LayoutLine(), aFont );
       
  1051 
       
  1052     if ( iMarquee )
       
  1053         {
       
  1054         if ( aFocused && aItem != iMarqueeItem )
       
  1055             {
       
  1056             iMarqueeItem = aItem;
       
  1057             iMarquee->Reset();
       
  1058             }
       
  1059         else if ( !aFocused && aItem == iMarqueeItem )
       
  1060             {
       
  1061             iMarqueeItem = NULL;
       
  1062             iMarquee->Stop();
       
  1063             }
       
  1064         }
       
  1065 
       
  1066     // Marquee scrolling is used when the given text does not fit in the given
       
  1067     // layout rectangle, but only if text is focused, marquee is allowed to be
       
  1068     // used with the given text, and marquee is enabled for the list.
       
  1069     TBool useMarquee = aFocused && aMarquee && iMarquee &&
       
  1070         iMarquee->IsMarqueeOn() && layoutText.TextRect().Width() < 
       
  1071             layoutText.Font()->TextWidthInPixels( aText );
       
  1072     
       
  1073     if ( !useMarquee || iMarquee->DrawText( aGc, aRect, aTextLayout, aText,
       
  1074             aFont, textColor ) )
       
  1075         {
       
  1076         layoutText.DrawText( aGc, aText, ETrue, textColor );
       
  1077         }
       
  1078     }
       
  1079 
       
  1080 
       
  1081 // ---------------------------------------------------------------------------
       
  1082 // Handles skin change by reconstruction all the used icons.
       
  1083 // ---------------------------------------------------------------------------
       
  1084 //
       
  1085 void CAknTree::HandleSkinChangeL()
       
  1086     {
       
  1087     for ( TInt ii = 0; ii < iIcons.Count(); ++ii )
       
  1088         {
       
  1089         iIcons[ii]->ReconstructL();
       
  1090         }
       
  1091     }
       
  1092 
       
  1093 
       
  1094 // ---------------------------------------------------------------------------
       
  1095 // Enables or disables marquee scrolling.
       
  1096 // ---------------------------------------------------------------------------
       
  1097 //
       
  1098 void CAknTree::EnableMarquee( TBool aEnable )
       
  1099     {
       
  1100     if ( iMarquee )
       
  1101         {
       
  1102         iMarquee->EnableMarquee( aEnable );
       
  1103         }
       
  1104     }
       
  1105 
       
  1106 
       
  1107 // ---------------------------------------------------------------------------
       
  1108 // Returns whether marquee scrolling is enabled.
       
  1109 // ---------------------------------------------------------------------------
       
  1110 //
       
  1111 TBool CAknTree::IsMarqueeOn() const
       
  1112     {
       
  1113     return iMarquee ? iMarquee->IsMarqueeOn() : EFalse;
       
  1114     }
       
  1115 
       
  1116 
       
  1117 // ---------------------------------------------------------------------------
       
  1118 // Redraw request from marquee control.
       
  1119 // ---------------------------------------------------------------------------
       
  1120 //
       
  1121 TInt CAknTree::MarqueeRedrawRequest( TAny* aThis )
       
  1122     {
       
  1123     CAknTree* tree = static_cast<CAknTree*>( aThis );
       
  1124     return tree ? tree->DoMarqueeRedrawRequest() : NULL;
       
  1125     }
       
  1126 
       
  1127 
       
  1128 // ---------------------------------------------------------------------------
       
  1129 // Enables tabulator mode expand/collapse function indicators.
       
  1130 // ---------------------------------------------------------------------------
       
  1131 //
       
  1132 void CAknTree::EnableTabModeFunctionIndicatorsL( TBool aEnable )
       
  1133     {
       
  1134     if ( iFlags.IsSet( ETabModeFunctionIndicators ) && !aEnable )
       
  1135         {
       
  1136         // Change to normal expand/collapse function indicators.
       
  1137         SetIconL( ECollapseFunctionIndication, KAknsIIDQgnIndiHlColSuper,
       
  1138             AknIconUtils::AvkonIconFileName(),
       
  1139             EMbmAvkonQgn_indi_hl_col_super,
       
  1140             EMbmAvkonQgn_indi_hl_col_super_mask,
       
  1141             EAspectRatioPreserved );
       
  1142 
       
  1143         SetIconL( EExpandFunctionIndication, KAknsIIDQgnIndiHlExpSuper,
       
  1144             AknIconUtils::AvkonIconFileName(),
       
  1145             EMbmAvkonQgn_indi_hl_exp_super,
       
  1146             EMbmAvkonQgn_indi_hl_exp_super_mask,
       
  1147             EAspectRatioPreserved );
       
  1148 
       
  1149         iFlags.Clear( ETabModeFunctionIndicators );
       
  1150         }
       
  1151     else if ( !iFlags.IsSet( ETabModeFunctionIndicators ) && aEnable )
       
  1152         {
       
  1153         // Change to tab mode expand/collapse function indicators.
       
  1154         SetIconL( ECollapseFunctionIndication, KAknsIIDQgnIndiHlTabColSuper,
       
  1155             AknIconUtils::AvkonIconFileName(),
       
  1156             EMbmAvkonQgn_indi_col_super,
       
  1157             EMbmAvkonQgn_indi_col_super_mask,
       
  1158             EAspectRatioPreserved );
       
  1159 
       
  1160         SetIconL( EExpandFunctionIndication, KAknsIIDQgnIndiHlTabExpSuper,
       
  1161             AknIconUtils::AvkonIconFileName(),
       
  1162             EMbmAvkonQgn_indi_exp_super,
       
  1163             EMbmAvkonQgn_indi_exp_super_mask,
       
  1164             EAspectRatioPreserved );
       
  1165 
       
  1166         iFlags.Set( ETabModeFunctionIndicators );
       
  1167         }
       
  1168     }
       
  1169 
       
  1170 
       
  1171 // ---------------------------------------------------------------------------
       
  1172 // Checks whether tabulator mode expand/collapse function indicators are
       
  1173 // enabled.
       
  1174 // ---------------------------------------------------------------------------
       
  1175 //
       
  1176 TBool CAknTree::TabModeFunctionIndicators() const
       
  1177     {
       
  1178     return iFlags.IsSet( ETabModeFunctionIndicators );
       
  1179     }
       
  1180 
       
  1181 
       
  1182 // ---------------------------------------------------------------------------
       
  1183 // From class CAknTreeItem.
       
  1184 // Returns the type of concrete item class.
       
  1185 // ---------------------------------------------------------------------------
       
  1186 //
       
  1187 TInt CAknTree::Type() const
       
  1188     {
       
  1189     return AknTreeList::KTree;
       
  1190     }
       
  1191 
       
  1192 
       
  1193 // ---------------------------------------------------------------------------
       
  1194 // From class CAknTreeItem.
       
  1195 // Instance of CAknTree is always set as tree root, so it can just return
       
  1196 // pointer to itself.
       
  1197 // ---------------------------------------------------------------------------
       
  1198 //
       
  1199 CAknTree* CAknTree::Root() const
       
  1200     {
       
  1201     return const_cast<CAknTree*>( this );
       
  1202     }
       
  1203 
       
  1204 
       
  1205 // ---------------------------------------------------------------------------
       
  1206 // From class CAknTreeNode.
       
  1207 // Changes the state of every node in the tree to expanded.
       
  1208 // ---------------------------------------------------------------------------
       
  1209 //
       
  1210 void CAknTree::Expand()
       
  1211     {
       
  1212     TAknTreeIterator iterator( this, NULL );
       
  1213     while ( iterator.HasNext() )
       
  1214         {
       
  1215         CAknTreeItem* item = iterator.Next();
       
  1216         if ( item->IsNode() )
       
  1217             {
       
  1218             DoExpandNode( item->Node(), EFalse );
       
  1219             }
       
  1220         }
       
  1221     }
       
  1222 
       
  1223 
       
  1224 // ---------------------------------------------------------------------------
       
  1225 // From class CAknTreeNode.
       
  1226 // Changes the state of every node in the tree to collapsed.
       
  1227 // ---------------------------------------------------------------------------
       
  1228 //
       
  1229 void CAknTree::Collapse()
       
  1230     {
       
  1231     TAknTreeIterator iterator( this, NULL );
       
  1232     iterator.SetCurrent( iterator.Last() );
       
  1233     iterator.Next();
       
  1234     while( iterator.HasPrevious() )
       
  1235         {
       
  1236         CAknTreeItem* item = iterator.Previous();
       
  1237         if ( item->IsNode() )
       
  1238             {
       
  1239             // Note: Might be a good idea to add for internal use an overload
       
  1240             // accepting the pointer to the collapsed node as parameter.
       
  1241             CollapseNode( Id( item->Node() ), EFalse );
       
  1242             }
       
  1243         }
       
  1244     }
       
  1245 
       
  1246 
       
  1247 // ---------------------------------------------------------------------------
       
  1248 // C++ constructor.
       
  1249 // ---------------------------------------------------------------------------
       
  1250 //
       
  1251 CAknTree::CAknTree( CAknTreeList& aList, CAknTreeOrdering* aOrdering )
       
  1252     : CAknTreeNode( EExpanded ),
       
  1253       iList( aList ),
       
  1254       iOrdering( aOrdering ),
       
  1255       iObservers( KObserverArrayGranularity )
       
  1256     {
       
  1257     }
       
  1258 
       
  1259 
       
  1260 // ---------------------------------------------------------------------------
       
  1261 // Second phase constructor.
       
  1262 // ---------------------------------------------------------------------------
       
  1263 //
       
  1264 void CAknTree::ConstructL()
       
  1265     {
       
  1266     TCallBack callBack( CAknTree::MarqueeRedrawRequest, this );
       
  1267     iMarquee = CAknMarqueeControl::NewL();
       
  1268     iMarquee->SetRedrawCallBack( callBack );
       
  1269 
       
  1270     SetIconL( ECollapseFunctionIndication, KAknsIIDQgnIndiHlColSuper,
       
  1271         AknIconUtils::AvkonIconFileName(),
       
  1272         EMbmAvkonQgn_indi_hl_col_super,
       
  1273         EMbmAvkonQgn_indi_hl_col_super_mask,
       
  1274         EAspectRatioPreserved );
       
  1275 
       
  1276     SetIconL( EExpandFunctionIndication, KAknsIIDQgnIndiHlExpSuper,
       
  1277         AknIconUtils::AvkonIconFileName(),
       
  1278         EMbmAvkonQgn_indi_hl_exp_super,
       
  1279         EMbmAvkonQgn_indi_hl_exp_super_mask,
       
  1280         EAspectRatioPreserved );
       
  1281 
       
  1282     SetIconL( ELineBranchIndication, KAknsIIDQgnIndiHlLineBranch,
       
  1283         AknIconUtils::AvkonIconFileName(),
       
  1284         EMbmAvkonQgn_indi_hl_line_branch,
       
  1285         EMbmAvkonQgn_indi_hl_line_branch,
       
  1286         EAspectRatioNotPreserved );
       
  1287 
       
  1288     SetIconL( ELineEndIndication, KAknsIIDQgnIndiHlLineEnd,
       
  1289         AknIconUtils::AvkonIconFileName(),
       
  1290         EMbmAvkonQgn_indi_hl_line_end,
       
  1291         EMbmAvkonQgn_indi_hl_line_end_mask,
       
  1292         EAspectRatioNotPreserved );
       
  1293 
       
  1294     SetIconL( ELineStraightIndication, KAknsIIDQgnIndiHlLineStraight,
       
  1295         AknIconUtils::AvkonIconFileName(),
       
  1296         EMbmAvkonQgn_indi_hl_line_straight,
       
  1297         EMbmAvkonQgn_indi_hl_line_straight_mask,
       
  1298         EAspectRatioNotPreserved );
       
  1299 
       
  1300     SetIconL( EDefaultFileIndication, KAknsIIDQgnPropHlFile,
       
  1301         AknIconUtils::AvkonIconFileName(),
       
  1302         EMbmAvkonQgn_prop_hl_file,
       
  1303         EMbmAvkonQgn_prop_hl_file_mask,
       
  1304         EAspectRatioPreserved );
       
  1305 
       
  1306     SetIconL( EClosedFolderIndication, KAknsIIDQgnPropHlFolder,
       
  1307         AknIconUtils::AvkonIconFileName(),
       
  1308         EMbmAvkonQgn_prop_hl_folder,
       
  1309         EMbmAvkonQgn_prop_hl_folder_mask,
       
  1310         EAspectRatioPreserved );
       
  1311 
       
  1312     SetIconL( EOpenFolderIndication, KAknsIIDQgnPropHlFolderOpen,
       
  1313         AknIconUtils::AvkonIconFileName(),
       
  1314         EMbmAvkonQgn_prop_hl_folder_open,
       
  1315         EMbmAvkonQgn_prop_hl_folder_open_mask,
       
  1316         EAspectRatioPreserved );
       
  1317 
       
  1318     SetColorIconL( EMarkedIndication, KAknsIIDQgnIndiMarkedAdd,
       
  1319         KAknsIIDQsnIconColors, EAknsCIQsnIconColorsCG13,
       
  1320         AknIconUtils::AvkonIconFileName(),
       
  1321         EMbmAvkonQgn_indi_marked_add,
       
  1322         EMbmAvkonQgn_indi_marked_add_mask,
       
  1323         KRgbBlack, EAspectRatioPreserved );
       
  1324 
       
  1325     SetColorIconL( EHighlightedMarkedIndication, KAknsIIDQgnIndiMarkedAdd,
       
  1326         KAknsIIDQsnIconColors, EAknsCIQsnIconColorsCG16,
       
  1327         AknIconUtils::AvkonIconFileName(),
       
  1328         EMbmAvkonQgn_indi_marked_add,
       
  1329         EMbmAvkonQgn_indi_marked_add_mask,
       
  1330         KRgbBlack, EAspectRatioPreserved );
       
  1331 
       
  1332     }
       
  1333 
       
  1334 
       
  1335 // ---------------------------------------------------------------------------
       
  1336 // Sends the specified event to every registered observer.
       
  1337 // ---------------------------------------------------------------------------
       
  1338 //
       
  1339 void CAknTree::NotifyObservers( MAknTreeObserver::TEvent aEvent,
       
  1340     CAknTreeItem* aItem, TBool aDrawNow )
       
  1341     {
       
  1342     const TInt count = iObservers.Count();
       
  1343     for ( TInt ii = 0; ii < count; ++ii )
       
  1344         {
       
  1345         iObservers[ii]->HandleTreeEvent( aEvent, aItem, aDrawNow );
       
  1346         }
       
  1347     }
       
  1348 
       
  1349 
       
  1350 // ---------------------------------------------------------------------------
       
  1351 // Sends notification to tree observers when requested by the marquee control.
       
  1352 // ---------------------------------------------------------------------------
       
  1353 //
       
  1354 TInt CAknTree::DoMarqueeRedrawRequest()
       
  1355     {
       
  1356     // Makes sure the tree still contains the scrolled item before sending
       
  1357     // the notification to the observers.
       
  1358     CAknTreeItem* item;
       
  1359     if ( !GetItem( Id( iMarqueeItem ), item ) )
       
  1360         {
       
  1361         ItemModified( item );
       
  1362         return 1;
       
  1363         }
       
  1364     return NULL;
       
  1365     }
       
  1366 
       
  1367 
       
  1368 // ---------------------------------------------------------------------------
       
  1369 // Searches for available icon ID.
       
  1370 // ---------------------------------------------------------------------------
       
  1371 //
       
  1372 TInt CAknTree::AvailableIconId() const
       
  1373     {
       
  1374     const TInt count = iIcons.Count();
       
  1375     TInt last = count ? iIcons[count - 1]->Id() : NULL;
       
  1376     TInt next = Max( last, EPreDefinedIconIdRange ) + 1;
       
  1377 
       
  1378     if ( next <= EPreDefinedIconIdRange )
       
  1379         {
       
  1380         next = KMaxTInt;
       
  1381         TBool found = EFalse;
       
  1382         for ( TInt ii = 0; ii < count - 1 && !found; ++ii )
       
  1383             {
       
  1384             if ( iIcons[ii]->Id() < iIcons[ii + 1]->Id() - 1 )
       
  1385                 {
       
  1386                 next = iIcons[ii]->Id() + 1;
       
  1387                 found = ETrue;
       
  1388                 }
       
  1389             }
       
  1390         }
       
  1391 
       
  1392     return next;
       
  1393     }
       
  1394 
       
  1395 
       
  1396 // ---------------------------------------------------------------------------
       
  1397 // Adds icon to the icon array.
       
  1398 // ---------------------------------------------------------------------------
       
  1399 //
       
  1400 void CAknTree::AddIconL( CAknTreeListIcon* aIcon )
       
  1401     {
       
  1402     __ASSERT_DEBUG( aIcon, User::Invariant() );
       
  1403     TLinearOrder<CAknTreeListIcon> order( CAknTreeListIcon::Compare );
       
  1404     TInt index = iIcons.FindInOrder( aIcon, order );
       
  1405     if ( index == KErrNotFound )
       
  1406         {
       
  1407         // Add icon to the array.
       
  1408         iIcons.InsertInOrderL( aIcon, order );
       
  1409         }
       
  1410     else
       
  1411         {
       
  1412         // Replace existing icon in the array.
       
  1413         delete iIcons[index];
       
  1414         iIcons[index] = aIcon;
       
  1415         }
       
  1416     }
       
  1417 
       
  1418 
       
  1419 // ---------------------------------------------------------------------------
       
  1420 // Sorts the list by sorting every node in the tree separately.
       
  1421 // ---------------------------------------------------------------------------
       
  1422 //
       
  1423 void CAknTree::Sort( TBool aDrawNow )
       
  1424     {
       
  1425     CAknTreeNode::Sort();
       
  1426     for ( TInt ii = 0; ii < iItems.Count(); ++ii )
       
  1427         {
       
  1428         CAknTreeNode* node = iItems[ii]->Node();
       
  1429         if ( node )
       
  1430             {
       
  1431             node->Sort();
       
  1432             }
       
  1433         }
       
  1434 
       
  1435     NotifyObservers( MAknTreeObserver::ETreeSorted, NULL, aDrawNow );
       
  1436     }
       
  1437 
       
  1438 
       
  1439 // ---------------------------------------------------------------------------
       
  1440 // Expands the specified node.
       
  1441 // ---------------------------------------------------------------------------
       
  1442 //
       
  1443 void CAknTree::DoExpandNode( CAknTreeNode* aNode, TBool aDrawNow )
       
  1444     {
       
  1445     __ASSERT_DEBUG( aNode, User::Invariant() );
       
  1446     iList.NotifyObservers( MAknTreeListObserver::ENodeExpanded, Id( aNode ) );
       
  1447     aNode->Expand();
       
  1448     NotifyObservers( MAknTreeObserver::ENodeExpanded, aNode, aDrawNow );
       
  1449     }
       
  1450 
       
  1451 
       
  1452 // ---------------------------------------------------------------------------
       
  1453 // From class CAknTreeItem.
       
  1454 // Empty implementation for the pure virtal function declared in CAknTreeItem.
       
  1455 // ---------------------------------------------------------------------------
       
  1456 //
       
  1457 void CAknTree::Draw( CWindowGc& /*aGc*/, const TRect& /*aItemRect*/,
       
  1458     const TRect& /*aRect*/, TBool /*aFocused*/ ) const
       
  1459     {
       
  1460     // The root node should never be drawn!
       
  1461     __ASSERT_DEBUG( EFalse, User::Invariant() );
       
  1462     }
       
  1463