--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/emailuis/uicomponents/src/fstree.cpp Thu Dec 17 08:39:21 2009 +0200
@@ -0,0 +1,547 @@
+/*
+* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: Freestyle tree node implementation.
+*
+*/
+
+#include "emailtrace.h"
+#include "fstree.h"
+#include "fstreeiterator.h"
+#include "fstreeobserver.h"
+#include "fsgenericpanic.h"
+#include "fstreenodevisualizer.h"
+
+// ======== MEMBER FUNCTIONS ========
+
+// ---------------------------------------------------------------------------
+// Two-phased constructor.
+// ---------------------------------------------------------------------------
+//
+EXPORT_C CFsTree* CFsTree::NewL( MFsTreeObserver& aObserver,
+ MFsTreeItemData& aItemD,
+ MFsTreeNodeVisualizer& aItemV )
+ {
+ FUNC_LOG;
+ CFsTree* self = new (ELeave) CFsTree( aObserver, aItemD, aItemV );
+ self->ConstructL();
+ return self;
+ }
+
+// ---------------------------------------------------------------------------
+// C++ destructor.
+// ---------------------------------------------------------------------------
+//
+CFsTree::~CFsTree()
+ {
+ FUNC_LOG;
+ iItems.ResetAndDestroy();
+ iItems.Close();
+ }
+
+// ---------------------------------------------------------------------------
+// Inserts new item as a child of parent given by Id at the given position.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::InsertItemL( MFsTreeItemData& aItemD,
+ MFsTreeItemVisualizer& aItemV,
+ const TFsTreeItemId aParentId,
+ const TInt aIndex )
+ {
+ FUNC_LOG;
+ CFsTreeNode* parentNode = Node( aParentId );
+
+ CFsTreeItem* item = CFsTreeItem::NewLC( *parentNode, aItemD, aItemV );
+
+ TFsTreeItemId itemId = InsertL( item, parentNode, aIndex );
+
+ NotifyObserverL( MFsTreeObserver::EFsTreeItemAdded, MFsTreeObserver::TFsTreeEventParams(itemId, aParentId, aIndex) );
+
+ CleanupStack::Pop( item );
+
+ return itemId;
+ }
+
+// ---------------------------------------------------------------------------
+// Inserts new node as a child of parent given by Id at the given position.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::InsertNodeL( MFsTreeItemData& aItemD,
+ MFsTreeNodeVisualizer& aItemV,
+ const TFsTreeItemId aParentId,
+ const TInt aIndex )
+ {
+ FUNC_LOG;
+ CFsTreeNode* parentNode = Node( aParentId );
+
+ CFsTreeNode* node = CFsTreeNode::NewL( *parentNode, aItemD, aItemV );
+
+ CleanupStack::PushL( node );
+
+ TFsTreeItemId itemId = InsertL( node, parentNode, aIndex );
+
+ NotifyObserverL( MFsTreeObserver::EFsTreeNodeAdded, MFsTreeObserver::TFsTreeEventParams(itemId, aParentId, aIndex) );
+
+ CleanupStack::Pop( node );
+
+ return itemId;
+ }
+
+// ---------------------------------------------------------------------------
+// Removes the item with given Id from the list. If aItemId is a node all
+// its children will be removed as well.
+// ---------------------------------------------------------------------------
+//
+TBool CFsTree::RemoveL( const TFsTreeItemId aItemId )
+ {
+ FUNC_LOG;
+ if ( aItemId != KFsTreeRootID )
+ //do not try to delete the tree itself
+ {
+ CFsTreeItem* removedItem = Item( aItemId );
+
+ CFsTreeNode* parentNode = removedItem->Parent();
+
+ //check if last item is removed
+ if ((parentNode==this) && (parentNode->CountChildren()==1))
+ {
+ iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeRemovedAll,
+ MFsTreeObserver::TFsTreeEventParams(KFsTreeNoneID, KFsTreeNoneID, -1));
+ }
+ else
+ {
+ iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeItemRemoved,
+ MFsTreeObserver::TFsTreeEventParams(aItemId, Id(parentNode), -1));
+ }
+
+
+ if (removedItem->IsNode())
+ {
+ // <cmail>
+ RFsTreeItemList itemsToBeDeleted;
+ TFsTreeIterator iter = Iterator( aItemId, aItemId );
+ CFsTreeNode* removedNode = static_cast<CFsTreeNode*>(removedItem);
+ // </cmail>
+
+ while (iter.HasNext())
+ {
+ CFsTreeItem* iterItem = Item(iter.Next());
+ itemsToBeDeleted.Append( iterItem );
+ iItems.Remove( iItems.FindInAddressOrder(iterItem) );
+ }
+ itemsToBeDeleted.ResetAndDestroy();
+ //remove children
+ for (TInt childIndex=removedNode->CountChildren()-1;
+ childIndex>=0;
+ childIndex--)
+ {
+ removedNode->RemoveChild(childIndex);
+ }
+ }
+
+ parentNode->RemoveChild( parentNode->Index(removedItem) );
+ iItems.Remove( iItems.FindInAddressOrder(removedItem) );
+ delete removedItem;
+ }
+ else
+ {
+ if (iItems.Count() > 0)
+ {
+ iTreeObserver.TreeEventL( MFsTreeObserver::EFsTreeRemovedAll,
+ MFsTreeObserver::TFsTreeEventParams(KFsTreeNoneID, KFsTreeNoneID, -1));
+ iItems.ResetAndDestroy();
+ iChildren.Reset();
+ }
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+// Moves the specified item to the specified target node.
+// ---------------------------------------------------------------------------
+//
+TBool CFsTree::MoveL( const TFsTreeItemId aItemId,
+ const TFsTreeItemId aTargetNodeId,
+ const TInt aIndex )
+ {
+ FUNC_LOG;
+ CFsTreeItem* movedItem = Item( aItemId );
+ CFsTreeNode* parentNode = movedItem->Parent();
+ CFsTreeNode* targetParent = Node( aTargetNodeId );
+
+ iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemRemoved, MFsTreeObserver::TFsTreeEventParams(aItemId, aTargetNodeId, aIndex));
+ parentNode->RemoveChild(parentNode->Index(movedItem));
+
+ targetParent->InsertChild(movedItem, aIndex);
+ movedItem->SetParent(*targetParent);
+ iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemAdded, MFsTreeObserver::TFsTreeEventParams(aItemId, aTargetNodeId, aIndex));
+
+ if (movedItem->IsNode())
+ {
+ CFsTreeNode* node = Node(aItemId);
+ for (TUint childNo=0; childNo<node->CountChildren(); childNo++)
+ {
+ iTreeObserver.TreeEventL(MFsTreeObserver::EFsTreeItemAdded,
+ MFsTreeObserver::TFsTreeEventParams(Id(node->Child(childNo)), aTargetNodeId, aIndex));
+ }
+ }
+
+ return ETrue;
+ }
+
+// ---------------------------------------------------------------------------
+// Function returns number of elements in the tree.
+// ---------------------------------------------------------------------------
+//
+TUint CFsTree::Count() const
+ {
+ FUNC_LOG;
+ return iItems.Count();
+ }
+
+// ---------------------------------------------------------------------------
+// Function checks whether an item with a given id exists in the tree.
+// ---------------------------------------------------------------------------
+//
+TBool CFsTree::Contains( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ TBool itemFound = EFalse;
+
+ TInt index = iItems.FindInAddressOrder(
+ reinterpret_cast<CFsTreeItem*>( aItemId ) );
+ if ( index != KErrNotFound )
+ {
+ itemFound = ETrue;
+ }
+
+ return itemFound;
+ }
+
+// ---------------------------------------------------------------------------
+// Creates an iterator object set to point at the specified item in the tree.
+// ---------------------------------------------------------------------------
+//
+TFsTreeIterator CFsTree::Iterator( const TFsTreeItemId aNodeId,
+ const TFsTreeItemId aCurrentItemId,
+ const TUint aFlags )
+ {
+ FUNC_LOG;
+ CFsTreeNode* node = Node( aNodeId );
+ CFsTreeItem* currentItem = Item( aCurrentItemId );
+
+ return TFsTreeIterator( node, this, currentItem, aFlags );
+ }
+
+// ---------------------------------------------------------------------------
+// Checks whether the item with specified id is a node.
+// ---------------------------------------------------------------------------
+//
+TBool CFsTree::IsNode( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+
+ CFsTreeItem* item = Item(aItemId);
+
+ return ( item ? Item(aItemId)->IsNode() : EFalse );
+ }
+
+// ---------------------------------------------------------------------------
+// Gets the number of children of the given node.
+// ---------------------------------------------------------------------------
+//
+TUint CFsTree::CountChildren( const TFsTreeItemId aNodeId ) const
+ {
+ FUNC_LOG;
+ return Node( aNodeId )->CountChildren();
+ }
+
+// ---------------------------------------------------------------------------
+// Gets recursively the number of all children under the given node
+// ---------------------------------------------------------------------------
+//
+TUint CFsTree::CountChildrenRecursively( const TFsTreeItemId aNodeId ) const
+ {
+ FUNC_LOG;
+ return Node( aNodeId )->CountChildrenRecursively();
+ }
+
+// ---------------------------------------------------------------------------
+// Gets the id of a child of the specified node with the position given.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::Child( const TFsTreeItemId aNodeId,
+ const TUint aIndex ) const
+ {
+ FUNC_LOG;
+ return Id( Node(aNodeId)->Child(aIndex) );
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the index of a child for a given parent.
+// ---------------------------------------------------------------------------
+//
+TInt CFsTree::ChildIndex( const TFsTreeItemId aNodeId,
+ const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ return Node(aNodeId)->Index(Item(aItemId));
+ }
+
+
+// ---------------------------------------------------------------------------
+// Gets a pointer to the node visualizer (const).
+// ---------------------------------------------------------------------------
+//
+MFsTreeNodeVisualizer* CFsTree::NodeVisualizer(
+ const TFsTreeItemId aNodeId ) const
+ {
+ FUNC_LOG;
+ return Node( aNodeId )->NodeVisualizer();
+ }
+
+
+// ---------------------------------------------------------------------------
+// Sets the reference to the node visualizer.
+// ---------------------------------------------------------------------------
+//
+void CFsTree::SetNodeVisualizer( MFsTreeItemVisualizer& aVisualizer,
+ const TFsTreeItemId aNodeId )
+ {
+ FUNC_LOG;
+ Node(aNodeId)->SetItemVisualizer(aVisualizer);
+ }
+
+// ---------------------------------------------------------------------------
+// Gets the parent's id for the specified item. If KFsTreeRootID is passed
+// then KFsTreeNoneID is returned.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::Parent( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ TFsTreeItemId parentId;
+
+ if ( aItemId == KFsTreeRootID )
+ parentId = KFsTreeNoneID;
+ else
+ parentId = Id(Item(aItemId)->Parent());
+
+ return parentId;
+ }
+
+// ---------------------------------------------------------------------------
+// Gets a reference to the item visualizer (const).
+// ---------------------------------------------------------------------------
+//
+MFsTreeItemVisualizer* CFsTree::ItemVisualizer( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ CFsTreeItem* item = Item( aItemId );
+ MFsTreeItemVisualizer* visualizer = NULL;
+
+ if (item)
+ {
+ visualizer = item->ItemVisualizer();
+ }
+
+ return visualizer;
+ }
+
+// ---------------------------------------------------------------------------
+// Gets a reference to the item/node data (const).
+// ---------------------------------------------------------------------------
+//
+MFsTreeItemData& CFsTree::ItemData( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ return Item( aItemId )->ItemData();
+ }
+
+// ---------------------------------------------------------------------------
+// Sets a reference to the item visualizer.
+// ---------------------------------------------------------------------------
+//
+void CFsTree::SetItemVisualizer( MFsTreeItemVisualizer& aVisualizer,
+ const TFsTreeItemId aItemId )
+ {
+ FUNC_LOG;
+ Item(aItemId)->SetItemVisualizer(aVisualizer);
+ }
+
+// ---------------------------------------------------------------------------
+// Sets the reference to the item/node data.
+// ---------------------------------------------------------------------------
+//
+void CFsTree::SetItemData( MFsTreeItemData& aData,
+ const TFsTreeItemId aItemId )
+ {
+ FUNC_LOG;
+ Item(aItemId)->SetItemData(aData);
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the ID assigned for the specified tree item.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::Id( const CFsTreeItem* aItem ) const
+ {
+ FUNC_LOG;
+ TFsTreeItemId id = KFsTreeNoneID;
+
+ if (aItem == this)
+ {
+ id = KFsTreeRootID;
+ }
+ else
+ if (aItem == NULL)
+ {
+ id = KFsTreeNoneID;
+ }
+ else
+ {
+ id = reinterpret_cast<TInt>( aItem );
+ }
+
+ return id;
+ }
+
+// ---------------------------------------------------------------------------
+// Returns the level of the item in the tree.
+// ---------------------------------------------------------------------------
+//
+TUint CFsTree::Level( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ CFsTreeItem* item = Item( aItemId );
+ return item->Level();
+ }
+
+// ---------------------------------------------------------------------------
+// Internal use.Retrieves the specified item from the tree structure.
+// ---------------------------------------------------------------------------
+//
+CFsTreeItem* CFsTree::Item( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ CFsTreeItem* item = NULL;
+
+ switch (aItemId)
+ {
+ case KFsTreeRootID :
+ item = const_cast<CFsTree*>( this );
+ break;
+
+ case KFsTreeNoneID :
+ //FsGenericPanic(EFsListPanicInvalidItemId);
+ break;
+
+ default :
+ TInt index = iItems.FindInAddressOrder(
+ reinterpret_cast<CFsTreeItem*>( aItemId ) );
+ if ( index != KErrNotFound )
+ {
+ item = iItems[index];
+ }
+ else
+ {
+ //FsGenericPanic(EFsListPanicInvalidItemId);
+ }
+ break;
+ }
+
+ return item;
+ }
+
+// ---------------------------------------------------------------------------
+// Internal use.Retrieves the specified node from the tree structure.
+// ---------------------------------------------------------------------------
+//
+CFsTreeNode* CFsTree::Node( const TFsTreeItemId aItemId ) const
+ {
+ FUNC_LOG;
+ CFsTreeItem* item = Item(aItemId);
+ CFsTreeNode* node = NULL;
+
+ if (item->IsNode())
+ {
+ node = item->Node();
+ }
+ else
+ {
+ FsGenericPanic(EFsListPanicInvalidItemType);
+ }
+
+ return node;
+ }
+
+// ---------------------------------------------------------------------------
+// Notifies the tree observer about an event in the tree.
+// ---------------------------------------------------------------------------
+//
+void CFsTree::NotifyObserverL( const MFsTreeObserver::TFsTreeEvent aEvent,
+ const MFsTreeObserver::TFsTreeEventParams& aParams )
+ {
+ FUNC_LOG;
+ iTreeObserver.TreeEventL( aEvent, aParams );
+ }
+
+// ---------------------------------------------------------------------------
+// Internal use.Inserts given item into given parent at specified positon.
+// ---------------------------------------------------------------------------
+//
+TFsTreeItemId CFsTree::InsertL( CFsTreeItem* aItem,
+ CFsTreeNode* aParent,
+ TInt aIndex )
+ {
+ FUNC_LOG;
+ TInt error = 0;
+
+ error = aParent->InsertChild( aItem, aIndex );
+ User::LeaveIfError( error );
+ //the if statement to avoid multiple entries
+ if (iItems.Find(aItem) == KErrNotFound)
+ {
+ //store item's pointer in the tree's lookup array
+ error = iItems.InsertInAddressOrder( aItem );
+ User::LeaveIfError( error );
+ }
+
+ return Id( aItem );
+ }
+
+// ---------------------------------------------------------------------------
+// C++ constructor.
+// ---------------------------------------------------------------------------
+//
+CFsTree::CFsTree( MFsTreeObserver& aObserver,
+ MFsTreeItemData& aItemD,
+ MFsTreeNodeVisualizer& aItemV )
+ : CFsTreeNode(NULL, aItemD, aItemV),
+ iTreeObserver( aObserver )
+ {
+ FUNC_LOG;
+
+ }
+
+// ---------------------------------------------------------------------------
+// Second phase constructor.
+// ---------------------------------------------------------------------------
+//
+void CFsTree::ConstructL( )
+ {
+ FUNC_LOG;
+
+ }
+