emailuis/uicomponents/src/fstree.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 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:  Freestyle tree node implementation.
       
    15 *
       
    16 */
       
    17 
       
    18 #include "emailtrace.h"
       
    19 #include "fstree.h"
       
    20 #include "fstreeiterator.h"
       
    21 #include "fstreeobserver.h"
       
    22 #include "fsgenericpanic.h"
       
    23 #include "fstreenodevisualizer.h"
       
    24 
       
    25 // ======== MEMBER FUNCTIONS ========
       
    26 
       
    27 // ---------------------------------------------------------------------------
       
    28 // Two-phased constructor.
       
    29 // ---------------------------------------------------------------------------
       
    30 //
       
    31 EXPORT_C CFsTree* CFsTree::NewL(  MFsTreeObserver& aObserver,
       
    32                                   MFsTreeItemData& aItemD,
       
    33                                   MFsTreeNodeVisualizer& aItemV )
       
    34     {
       
    35     FUNC_LOG;
       
    36     CFsTree* self = new (ELeave) CFsTree( aObserver, aItemD, aItemV );
       
    37     self->ConstructL();
       
    38     return self;
       
    39     }
       
    40 
       
    41 // ---------------------------------------------------------------------------
       
    42 // C++ destructor.
       
    43 // ---------------------------------------------------------------------------
       
    44 //
       
    45 CFsTree::~CFsTree()
       
    46     {
       
    47     FUNC_LOG;
       
    48     iItems.ResetAndDestroy();
       
    49     iItems.Close();
       
    50     }
       
    51 
       
    52 // ---------------------------------------------------------------------------
       
    53 // Inserts new item as a child of parent given by Id at the given position.
       
    54 // ---------------------------------------------------------------------------
       
    55 //
       
    56 TFsTreeItemId CFsTree::InsertItemL( MFsTreeItemData& aItemD,
       
    57                                     MFsTreeItemVisualizer& aItemV,
       
    58                                     const TFsTreeItemId aParentId,
       
    59                                     const TInt aIndex )
       
    60     {
       
    61     FUNC_LOG;
       
    62     CFsTreeNode* parentNode = Node( aParentId );
       
    63 
       
    64     CFsTreeItem* item = CFsTreeItem::NewLC( *parentNode, aItemD, aItemV );
       
    65 
       
    66     TFsTreeItemId itemId = InsertL( item, parentNode, aIndex );
       
    67 
       
    68     NotifyObserverL( MFsTreeObserver::EFsTreeItemAdded, MFsTreeObserver::TFsTreeEventParams(itemId, aParentId, aIndex) );
       
    69 
       
    70     CleanupStack::Pop( item );
       
    71 
       
    72     return itemId;
       
    73     }
       
    74 
       
    75 // ---------------------------------------------------------------------------
       
    76 // Inserts new node as a child of parent given by Id at the given position.
       
    77 // ---------------------------------------------------------------------------
       
    78 //
       
    79 TFsTreeItemId CFsTree::InsertNodeL( MFsTreeItemData& aItemD,
       
    80 		                            MFsTreeNodeVisualizer& aItemV,
       
    81                                     const TFsTreeItemId aParentId,
       
    82                                     const TInt aIndex )
       
    83     {
       
    84     FUNC_LOG;
       
    85     CFsTreeNode* parentNode = Node( aParentId );
       
    86 
       
    87     CFsTreeNode* node = CFsTreeNode::NewL( *parentNode, aItemD, aItemV );
       
    88 
       
    89     CleanupStack::PushL( node );
       
    90 
       
    91     TFsTreeItemId itemId = InsertL( node, parentNode, aIndex );
       
    92 
       
    93     NotifyObserverL( MFsTreeObserver::EFsTreeNodeAdded, MFsTreeObserver::TFsTreeEventParams(itemId, aParentId, aIndex) );
       
    94 
       
    95     CleanupStack::Pop( node );
       
    96 
       
    97     return itemId;
       
    98     }
       
    99 
       
   100 // ---------------------------------------------------------------------------
       
   101 // Removes the item with given Id from the list. If aItemId is a node all
       
   102 // its children will be removed as well.
       
   103 // ---------------------------------------------------------------------------
       
   104 //
       
   105 TBool CFsTree::RemoveL( const TFsTreeItemId aItemId )
       
   106     {
       
   107     FUNC_LOG;
       
   108     if ( aItemId != KFsTreeRootID )
       
   109     //do not try to delete the tree itself
       
   110         {
       
   111         CFsTreeItem* removedItem = Item( aItemId );
       
   112 
       
   113         CFsTreeNode* parentNode = removedItem->Parent();
       
   114 
       
   115         //check if last item is removed
       
   116         if ((parentNode==this) && (parentNode->CountChildren()==1))
       
   117             {
       
   118             iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeRemovedAll,
       
   119                     MFsTreeObserver::TFsTreeEventParams(KFsTreeNoneID, KFsTreeNoneID, -1));
       
   120             }
       
   121         else
       
   122             {
       
   123             iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeItemRemoved,
       
   124                     MFsTreeObserver::TFsTreeEventParams(aItemId, Id(parentNode), -1));
       
   125             }
       
   126 
       
   127 
       
   128         if (removedItem->IsNode())
       
   129             {
       
   130             // <cmail>
       
   131             RFsTreeItemList itemsToBeDeleted;
       
   132             TFsTreeIterator iter = Iterator( aItemId, aItemId );
       
   133             CFsTreeNode* removedNode = static_cast<CFsTreeNode*>(removedItem);
       
   134             // </cmail>
       
   135 
       
   136             while (iter.HasNext())
       
   137                 {
       
   138                 CFsTreeItem* iterItem = Item(iter.Next());
       
   139                 itemsToBeDeleted.Append( iterItem );
       
   140                 iItems.Remove( iItems.FindInAddressOrder(iterItem) );
       
   141                 }
       
   142             itemsToBeDeleted.ResetAndDestroy();
       
   143             //remove children
       
   144             for (TInt childIndex=removedNode->CountChildren()-1;
       
   145                     childIndex>=0;
       
   146                     childIndex--)
       
   147                 {
       
   148                 removedNode->RemoveChild(childIndex);
       
   149                 }
       
   150             }
       
   151 
       
   152         parentNode->RemoveChild( parentNode->Index(removedItem) );
       
   153         iItems.Remove( iItems.FindInAddressOrder(removedItem) );
       
   154         delete removedItem;
       
   155         }
       
   156     else
       
   157         {
       
   158         if (iItems.Count() > 0)
       
   159             {
       
   160             iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeRemovedAll,
       
   161                     MFsTreeObserver::TFsTreeEventParams(KFsTreeNoneID, KFsTreeNoneID, -1));
       
   162             iItems.ResetAndDestroy();
       
   163             iChildren.Reset();
       
   164             }
       
   165         }
       
   166 
       
   167     return ETrue;
       
   168     }
       
   169 
       
   170 // ---------------------------------------------------------------------------
       
   171 // Moves the specified item to the specified target node.
       
   172 // ---------------------------------------------------------------------------
       
   173 //
       
   174 TBool CFsTree::MoveL( const TFsTreeItemId aItemId,
       
   175                      const TFsTreeItemId aTargetNodeId,
       
   176                      const TInt aIndex )
       
   177     {
       
   178     FUNC_LOG;
       
   179     CFsTreeItem* movedItem = Item( aItemId );
       
   180     CFsTreeNode* parentNode = movedItem->Parent();
       
   181     CFsTreeNode* targetParent = Node( aTargetNodeId );
       
   182 
       
   183     iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemRemoved, MFsTreeObserver::TFsTreeEventParams(aItemId, aTargetNodeId, aIndex));
       
   184     parentNode->RemoveChild(parentNode->Index(movedItem));
       
   185 
       
   186     targetParent->InsertChild(movedItem, aIndex);
       
   187     movedItem->SetParent(*targetParent);
       
   188     iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemAdded, MFsTreeObserver::TFsTreeEventParams(aItemId, aTargetNodeId, aIndex));
       
   189 
       
   190     if (movedItem->IsNode())
       
   191         {
       
   192         CFsTreeNode* node = Node(aItemId);
       
   193         for (TUint childNo=0; childNo<node->CountChildren(); childNo++)
       
   194             {
       
   195             iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemAdded,
       
   196                     MFsTreeObserver::TFsTreeEventParams(Id(node->Child(childNo)), aTargetNodeId, aIndex));
       
   197             }
       
   198         }
       
   199 
       
   200     return ETrue;
       
   201     }
       
   202 
       
   203 // ---------------------------------------------------------------------------
       
   204 // Function returns number of elements in the tree.
       
   205 // ---------------------------------------------------------------------------
       
   206 //
       
   207 TUint CFsTree::Count() const
       
   208     {
       
   209     FUNC_LOG;
       
   210     return iItems.Count();
       
   211     }
       
   212 
       
   213 // ---------------------------------------------------------------------------
       
   214 // Function checks whether an item with a given id exists in the tree.
       
   215 // ---------------------------------------------------------------------------
       
   216 //
       
   217 TBool CFsTree::Contains( const TFsTreeItemId aItemId ) const
       
   218     {
       
   219     FUNC_LOG;
       
   220     TBool itemFound = EFalse;
       
   221 
       
   222     TInt index = iItems.FindInAddressOrder(
       
   223                                     reinterpret_cast<CFsTreeItem*>( aItemId ) );
       
   224     if ( index != KErrNotFound )
       
   225         {
       
   226         itemFound = ETrue;
       
   227         }
       
   228 
       
   229     return itemFound;
       
   230     }
       
   231 
       
   232 // ---------------------------------------------------------------------------
       
   233 // Creates an iterator object set to point at the specified item in the tree.
       
   234 // ---------------------------------------------------------------------------
       
   235 //
       
   236 TFsTreeIterator CFsTree::Iterator( const TFsTreeItemId aNodeId,
       
   237                                    const TFsTreeItemId aCurrentItemId,
       
   238                                    const TUint aFlags )
       
   239     {
       
   240     FUNC_LOG;
       
   241     CFsTreeNode* node = Node( aNodeId );
       
   242     CFsTreeItem* currentItem = Item( aCurrentItemId );
       
   243 
       
   244     return TFsTreeIterator( node, this, currentItem, aFlags );
       
   245     }
       
   246 
       
   247 // ---------------------------------------------------------------------------
       
   248 // Checks whether the item with specified id is a node.
       
   249 // ---------------------------------------------------------------------------
       
   250 //
       
   251 TBool CFsTree::IsNode( const TFsTreeItemId aItemId ) const
       
   252     {
       
   253     FUNC_LOG;
       
   254 
       
   255     CFsTreeItem* item = Item(aItemId);
       
   256 
       
   257     return ( item ? Item(aItemId)->IsNode() : EFalse );
       
   258     }
       
   259 
       
   260 // ---------------------------------------------------------------------------
       
   261 // Gets the number of children of the given node.
       
   262 // ---------------------------------------------------------------------------
       
   263 //
       
   264 TUint CFsTree::CountChildren( const TFsTreeItemId aNodeId ) const
       
   265     {
       
   266     FUNC_LOG;
       
   267     return Node( aNodeId )->CountChildren();
       
   268     }
       
   269 
       
   270 // ---------------------------------------------------------------------------
       
   271 // Gets recursively the number of all children under the given node
       
   272 // ---------------------------------------------------------------------------
       
   273 //
       
   274 TUint CFsTree::CountChildrenRecursively( const TFsTreeItemId aNodeId ) const
       
   275     {
       
   276     FUNC_LOG;
       
   277     return Node( aNodeId )->CountChildrenRecursively();
       
   278     }
       
   279 
       
   280 // ---------------------------------------------------------------------------
       
   281 // Gets the id of a child of the specified node with the position given.
       
   282 // ---------------------------------------------------------------------------
       
   283 //
       
   284 TFsTreeItemId CFsTree::Child( const TFsTreeItemId aNodeId,
       
   285         const TUint aIndex ) const
       
   286     {
       
   287     FUNC_LOG;
       
   288     return Id( Node(aNodeId)->Child(aIndex) );
       
   289     }
       
   290 
       
   291 // ---------------------------------------------------------------------------
       
   292 // Returns the index of a child for a given parent.
       
   293 // ---------------------------------------------------------------------------
       
   294 //
       
   295 TInt CFsTree::ChildIndex( const TFsTreeItemId aNodeId,
       
   296                            const TFsTreeItemId aItemId ) const
       
   297     {
       
   298     FUNC_LOG;
       
   299     return Node(aNodeId)->Index(Item(aItemId));
       
   300     }
       
   301 
       
   302 
       
   303 // ---------------------------------------------------------------------------
       
   304 // Gets a pointer to the node visualizer (const).
       
   305 // ---------------------------------------------------------------------------
       
   306 //
       
   307 MFsTreeNodeVisualizer* CFsTree::NodeVisualizer(
       
   308                                            const TFsTreeItemId aNodeId ) const
       
   309     {
       
   310     FUNC_LOG;
       
   311     return Node( aNodeId )->NodeVisualizer();
       
   312     }
       
   313 
       
   314 
       
   315 // ---------------------------------------------------------------------------
       
   316 // Sets the reference to the node visualizer.
       
   317 // ---------------------------------------------------------------------------
       
   318 //
       
   319 void CFsTree::SetNodeVisualizer( MFsTreeItemVisualizer& aVisualizer,
       
   320                                  const TFsTreeItemId aNodeId )
       
   321     {
       
   322     FUNC_LOG;
       
   323     Node(aNodeId)->SetItemVisualizer(aVisualizer);
       
   324     }
       
   325 
       
   326 // ---------------------------------------------------------------------------
       
   327 // Gets the parent's id for the specified item. If KFsTreeRootID is passed
       
   328 // then KFsTreeNoneID is returned.
       
   329 // ---------------------------------------------------------------------------
       
   330 //
       
   331 TFsTreeItemId CFsTree::Parent( const TFsTreeItemId aItemId ) const
       
   332     {
       
   333     FUNC_LOG;
       
   334     TFsTreeItemId parentId;
       
   335 
       
   336     if ( aItemId == KFsTreeRootID )
       
   337         parentId = KFsTreeNoneID;
       
   338     else
       
   339         parentId = Id(Item(aItemId)->Parent());
       
   340 
       
   341     return parentId;
       
   342     }
       
   343 
       
   344 // ---------------------------------------------------------------------------
       
   345 // Gets a reference to the item visualizer (const).
       
   346 // ---------------------------------------------------------------------------
       
   347 //
       
   348 MFsTreeItemVisualizer* CFsTree::ItemVisualizer( const TFsTreeItemId aItemId ) const
       
   349     {
       
   350     FUNC_LOG;
       
   351     CFsTreeItem* item = Item( aItemId );
       
   352     MFsTreeItemVisualizer* visualizer = NULL;
       
   353 
       
   354     if (item)
       
   355         {
       
   356         visualizer = item->ItemVisualizer();
       
   357         }
       
   358 
       
   359     return visualizer;
       
   360     }
       
   361 
       
   362 // ---------------------------------------------------------------------------
       
   363 // Gets a reference to the item/node data (const).
       
   364 // ---------------------------------------------------------------------------
       
   365 //
       
   366 MFsTreeItemData& CFsTree::ItemData( const TFsTreeItemId aItemId ) const
       
   367     {
       
   368     FUNC_LOG;
       
   369     return Item( aItemId )->ItemData();
       
   370     }
       
   371 
       
   372 // ---------------------------------------------------------------------------
       
   373 // Sets a reference to the item visualizer.
       
   374 // ---------------------------------------------------------------------------
       
   375 //
       
   376 void CFsTree::SetItemVisualizer( MFsTreeItemVisualizer& aVisualizer,
       
   377                                  const TFsTreeItemId aItemId )
       
   378     {
       
   379     FUNC_LOG;
       
   380     Item(aItemId)->SetItemVisualizer(aVisualizer);
       
   381     }
       
   382 
       
   383 // ---------------------------------------------------------------------------
       
   384 // Sets the reference to the item/node data.
       
   385 // ---------------------------------------------------------------------------
       
   386 //
       
   387 void CFsTree::SetItemData( MFsTreeItemData& aData,
       
   388                            const TFsTreeItemId aItemId )
       
   389     {
       
   390     FUNC_LOG;
       
   391     Item(aItemId)->SetItemData(aData);
       
   392     }
       
   393 
       
   394 // ---------------------------------------------------------------------------
       
   395 // Returns the ID assigned for the specified tree item.
       
   396 // ---------------------------------------------------------------------------
       
   397 //
       
   398 TFsTreeItemId CFsTree::Id( const CFsTreeItem* aItem ) const
       
   399     {
       
   400     FUNC_LOG;
       
   401     TFsTreeItemId id = KFsTreeNoneID;
       
   402 
       
   403     if (aItem == this)
       
   404         {
       
   405         id = KFsTreeRootID;
       
   406         }
       
   407     else
       
   408         if (aItem == NULL)
       
   409             {
       
   410             id = KFsTreeNoneID;
       
   411             }
       
   412         else
       
   413             {
       
   414             id = reinterpret_cast<TInt>( aItem );
       
   415             }
       
   416 
       
   417     return id;
       
   418     }
       
   419 
       
   420 // ---------------------------------------------------------------------------
       
   421 // Returns the level of the item in the tree.
       
   422 // ---------------------------------------------------------------------------
       
   423 //
       
   424 TUint CFsTree::Level( const TFsTreeItemId aItemId ) const
       
   425     {
       
   426     FUNC_LOG;
       
   427     CFsTreeItem* item = Item( aItemId );
       
   428     return item->Level();
       
   429     }
       
   430 
       
   431 // ---------------------------------------------------------------------------
       
   432 // Internal use.Retrieves the specified item from the tree structure.
       
   433 // ---------------------------------------------------------------------------
       
   434 //
       
   435 CFsTreeItem* CFsTree::Item( const TFsTreeItemId aItemId ) const
       
   436     {
       
   437     FUNC_LOG;
       
   438     CFsTreeItem* item = NULL;
       
   439 
       
   440     switch (aItemId)
       
   441         {
       
   442         case KFsTreeRootID :
       
   443             item = const_cast<CFsTree*>( this );
       
   444             break;
       
   445 
       
   446         case KFsTreeNoneID :
       
   447             //FsGenericPanic(EFsListPanicInvalidItemId);
       
   448             break;
       
   449 
       
   450         default :
       
   451             TInt index = iItems.FindInAddressOrder(
       
   452                                     reinterpret_cast<CFsTreeItem*>( aItemId ) );
       
   453             if ( index != KErrNotFound )
       
   454                 {
       
   455                 item = iItems[index];
       
   456                 }
       
   457             else
       
   458                 {
       
   459                 //FsGenericPanic(EFsListPanicInvalidItemId);
       
   460                 }
       
   461             break;
       
   462         }
       
   463 
       
   464     return item;
       
   465     }
       
   466 
       
   467 // ---------------------------------------------------------------------------
       
   468 // Internal use.Retrieves the specified node from the tree structure.
       
   469 // ---------------------------------------------------------------------------
       
   470 //
       
   471 CFsTreeNode* CFsTree::Node( const TFsTreeItemId aItemId ) const
       
   472     {
       
   473     FUNC_LOG;
       
   474     CFsTreeItem* item = Item(aItemId);
       
   475     CFsTreeNode* node = NULL;
       
   476 
       
   477     if (item->IsNode())
       
   478         {
       
   479         node = item->Node();
       
   480         }
       
   481     else
       
   482         {
       
   483         FsGenericPanic(EFsListPanicInvalidItemType);
       
   484         }
       
   485 
       
   486     return node;
       
   487     }
       
   488 
       
   489 // ---------------------------------------------------------------------------
       
   490 // Notifies the tree observer about an event in the tree.
       
   491 // ---------------------------------------------------------------------------
       
   492 //
       
   493 void CFsTree::NotifyObserverL( const MFsTreeObserver::TFsTreeEvent aEvent,
       
   494         const MFsTreeObserver::TFsTreeEventParams& aParams )
       
   495     {
       
   496     FUNC_LOG;
       
   497     iTreeObserver.TreeEventL( aEvent, aParams );
       
   498     }
       
   499 
       
   500 // ---------------------------------------------------------------------------
       
   501 // Internal use.Inserts given item into given parent at specified positon.
       
   502 // ---------------------------------------------------------------------------
       
   503 //
       
   504 TFsTreeItemId CFsTree::InsertL( CFsTreeItem* aItem,
       
   505                                CFsTreeNode* aParent,
       
   506                                TInt aIndex )
       
   507     {
       
   508     FUNC_LOG;
       
   509     TInt error = 0;
       
   510 
       
   511     error = aParent->InsertChild( aItem, aIndex );
       
   512     User::LeaveIfError( error );
       
   513     //the if statement to avoid multiple entries
       
   514     if (iItems.Find(aItem) == KErrNotFound)
       
   515         {
       
   516         //store item's pointer in the tree's lookup array
       
   517         error = iItems.InsertInAddressOrder( aItem );
       
   518         User::LeaveIfError( error );
       
   519         }
       
   520 
       
   521     return Id( aItem );
       
   522     }
       
   523 
       
   524 // ---------------------------------------------------------------------------
       
   525 //  C++ constructor.
       
   526 // ---------------------------------------------------------------------------
       
   527 //
       
   528 CFsTree::CFsTree( MFsTreeObserver& aObserver,
       
   529                   MFsTreeItemData& aItemD,
       
   530                   MFsTreeNodeVisualizer& aItemV )
       
   531     :   CFsTreeNode(NULL, aItemD, aItemV),
       
   532         iTreeObserver( aObserver )
       
   533     {
       
   534     FUNC_LOG;
       
   535 
       
   536     }
       
   537 
       
   538 // ---------------------------------------------------------------------------
       
   539 //  Second phase constructor.
       
   540 // ---------------------------------------------------------------------------
       
   541 //
       
   542 void CFsTree::ConstructL(  )
       
   543     {
       
   544     FUNC_LOG;
       
   545 
       
   546     }
       
   547