webengine/widgetengine/src/MenuClient.cpp
changeset 0 dd21522fd290
child 5 10e98eab6f85
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2006 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 the License "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:  This class represents the Widget Extension object
       
    15 *
       
    16 */
       
    17 
       
    18 // INCLUDE FILES
       
    19 #include "MenuClient.h"
       
    20 #include "MenuItemClient.h"
       
    21 #include "Menu.h"
       
    22 #include "MenuItem.h"
       
    23 
       
    24 // EXTERNAL DATA STRUCTURES
       
    25 
       
    26 // EXTERNAL FUNCTION PROTOTYPES
       
    27 
       
    28 // CONSTANTS
       
    29 const TInt KMenuItemCommandIdBase = 20000;
       
    30 const TInt KMaxOptionsMenu = 63;
       
    31 
       
    32 // MACROS
       
    33 
       
    34 // LOCAL CONSTANTS AND MACROS
       
    35 
       
    36 // MODULE DATA STRUCTURES
       
    37 
       
    38 // LOCAL FUNCTION PROTOTYPES
       
    39 // The binary tree representation of a multiway tree is based on
       
    40 // first child-next sibling representation of the tree. In this representation
       
    41 // every node is linked with its leftmost child and its next (right nearest)
       
    42 // sibling.
       
    43 
       
    44 /*
       
    45 Example: Consider the following multiway tree
       
    46 
       
    47                         1
       
    48                       / | \
       
    49                      /  |  \
       
    50                     /   |   \
       
    51                    2    3    4
       
    52                   / \        |
       
    53                  5   6       7
       
    54                             / \
       
    55                            8   9
       
    56 
       
    57 
       
    58 This tree can be represented in first child-next sibling manner as follows :
       
    59 
       
    60                         1
       
    61                        /
       
    62                       /
       
    63                      /
       
    64                     2---3---4
       
    65                    /       /
       
    66                   5---6   7
       
    67                          /
       
    68                         8---9
       
    69 
       
    70 
       
    71 If we look at the first child-next sibling representation of the tree closely,
       
    72 we will see that it forms a binary tree. To see this better, rotate every
       
    73 next-sibling edge 45 degrees clockwise. After that, the following binary tree is got:
       
    74 
       
    75                         1
       
    76                        /
       
    77                       2
       
    78                      / \
       
    79                     5   3
       
    80                      \   \
       
    81                       6   4
       
    82                          /
       
    83                         7
       
    84                        /
       
    85                       8
       
    86                        \
       
    87                         9
       
    88 
       
    89 */
       
    90 
       
    91 
       
    92 // ----------------------------------------------------------------------------
       
    93 // CMenuClient::NewL
       
    94 //
       
    95 //
       
    96 //
       
    97 // ----------------------------------------------------------------------------
       
    98 CMenuClient* CMenuClient::NewL(MWidgetCallback& aWidgetCallback, 
       
    99                                MWidgetEngineCallbacks& aWidgetEngineCallback)
       
   100 {
       
   101     CMenuClient* self = new ( ELeave ) CMenuClient(aWidgetCallback,aWidgetEngineCallback);
       
   102     CleanupStack::PushL( self );
       
   103     self->ConstructL();
       
   104     CleanupStack::Pop();
       
   105     return self;
       
   106 }
       
   107 
       
   108 
       
   109 // ----------------------------------------------------------------------------
       
   110 // CMenuClient::CMenuClient
       
   111 //
       
   112 //
       
   113 //
       
   114 // ----------------------------------------------------------------------------
       
   115 CMenuClient::CMenuClient(MWidgetCallback& aWidgetCallback, 
       
   116                          MWidgetEngineCallbacks& aWidgetEngineCallback) : 
       
   117                         iWidgetCallback(&aWidgetCallback), 
       
   118                         m_widgetenginecallback(&aWidgetEngineCallback),
       
   119                         m_jsmenu(0),            
       
   120                         m_jsmenuitemctr(0)
       
   121 {
       
   122 }
       
   123 
       
   124 
       
   125 // ----------------------------------------------------------------------------
       
   126 // CMenuClient::~CMenuClient
       
   127 //
       
   128 //
       
   129 //
       
   130 // ----------------------------------------------------------------------------
       
   131 CMenuClient::~CMenuClient()
       
   132 {
       
   133     // delete tree
       
   134     if ( iMenuRoot )
       
   135         {
       
   136         deleteTree( iMenuRoot->firstChild() );
       
   137         delete iMenuRoot;
       
   138         iMenuRoot = NULL;
       
   139         }
       
   140 
       
   141     iCascadeArr.Close();
       
   142     
       
   143     if (m_jsmenu) {
       
   144         KJS::Collector::unprotect(m_jsmenu);                
       
   145     }
       
   146     
       
   147     if (m_jsmenuitemctr) {
       
   148         KJS::Collector::unprotect(m_jsmenuitemctr);                            
       
   149     }
       
   150     
       
   151 }
       
   152 
       
   153 
       
   154 // ----------------------------------------------------------------------------
       
   155 // CMenuClient::ConstructL
       
   156 //
       
   157 //
       
   158 //
       
   159 // ----------------------------------------------------------------------------
       
   160 void CMenuClient::ConstructL()
       
   161 {        
       
   162 }
       
   163 
       
   164 
       
   165 // ----------------------------------------------------------------------------
       
   166 // CMenuClient::jsmenu
       
   167 //
       
   168 //
       
   169 //
       
   170 // ----------------------------------------------------------------------------
       
   171 KJS::JSMenu* CMenuClient::jsmenu() 
       
   172 { 
       
   173     if (!m_jsmenu) {
       
   174         m_jsmenu = new KJS::JSMenu(this);   
       
   175         KJS::Collector::protect(m_jsmenu);        
       
   176     }
       
   177     
       
   178     return m_jsmenu; 
       
   179 }
       
   180 
       
   181 
       
   182 // ----------------------------------------------------------------------------
       
   183 // CMenuClient::jsmenuitem
       
   184 //
       
   185 //
       
   186 //
       
   187 // ----------------------------------------------------------------------------
       
   188 KJS::JSMenuItemConstructor* CMenuClient::jsmenuitem() 
       
   189 {
       
   190     if (!m_jsmenuitemctr){
       
   191         m_jsmenuitemctr = new KJS::JSMenuItemConstructor(this);    
       
   192         KJS::Collector::protect(m_jsmenuitemctr);                
       
   193     }
       
   194 
       
   195     return m_jsmenuitemctr;    
       
   196 }
       
   197 
       
   198 
       
   199 // ----------------------------------------------------------------------------
       
   200 // CMenuClient::addOptionMenuItemsL
       
   201 //
       
   202 //
       
   203 //
       
   204 // ----------------------------------------------------------------------------
       
   205 //
       
   206 void CMenuClient::addOptionMenuItemsL(CEikMenuPane& aMenuPane, TInt aResourceId)
       
   207 {
       
   208 
       
   209     CMenuItem* node = NULL;
       
   210     CMenuItem* parentNode = NULL;
       
   211     TInt parentInternalId = -1;
       
   212 
       
   213     //one of the cascade menu pane
       
   214     if ( aResourceId >= R_CASCADE_MENU_1 )  {
       
   215         for ( TInt i = 0; i < iCascadeArr.Count(); i++ ) {
       
   216             if ( iCascadeArr[i].iResourceId == aResourceId ) {
       
   217                 parentInternalId = iCascadeArr[i].parentInternalId;
       
   218                 parentNode = findNodeById( iMenuRoot, parentInternalId, EReal );
       
   219                 if ( parentNode )
       
   220                     break;
       
   221             }
       
   222         }
       
   223         
       
   224         if ( parentInternalId != -1 && parentNode ) {
       
   225             menuItemSelected( parentInternalId + KMenuItemCommandIdBase );
       
   226             node = parentNode->firstChild();
       
   227         }
       
   228     }
       
   229     else {
       
   230         // constructing root pane
       
   231         iResourceId = R_CASCADE_MENU_1;
       
   232 
       
   233         //invoke menu onshow callback
       
   234         if ( m_jsmenu && m_jsmenu->onShowCallback() ) {
       
   235             m_jsmenu->onShowCallback()->InvokeCall();
       
   236         }
       
   237 
       
   238         if ( aMenuPane.NumberOfItemsInPane() > 1 ) {
       
   239             aMenuPane.DeleteBetweenMenuItems( 0, aMenuPane.NumberOfItemsInPane() - 2 );
       
   240         }
       
   241         
       
   242         if ( iMenuRoot ) {
       
   243             node = iMenuRoot->firstChild();
       
   244         }
       
   245     }
       
   246 
       
   247     if ( node ) {
       
   248     
       
   249         //add first child
       
   250         addMenuItem( aMenuPane, node, parentInternalId == -1 );
       
   251 
       
   252         //add all other children (siblings of first child)
       
   253         CMenuItem* sibling = node->nextSibling();
       
   254         while( sibling ) {
       
   255             addMenuItem( aMenuPane, sibling, parentInternalId == -1 );
       
   256             sibling = sibling->nextSibling();
       
   257         }
       
   258     }
       
   259 
       
   260 }
       
   261 
       
   262 
       
   263 // -----------------------------------------------------------------------------
       
   264 // CMenuClient::menuShowed
       
   265 //
       
   266 //
       
   267 //
       
   268 // -----------------------------------------------------------------------------
       
   269 void CMenuClient::menuShowed()
       
   270 {
       
   271     if ( m_jsmenu && m_jsmenu->onShowCallback() ) {
       
   272         m_jsmenu->onShowCallback()->InvokeCall();
       
   273     }
       
   274 }
       
   275 
       
   276 // -----------------------------------------------------------------------------
       
   277 // CMenuClient::menuItemSelected
       
   278 //
       
   279 //
       
   280 //
       
   281 // -----------------------------------------------------------------------------
       
   282 void CMenuClient::menuItemSelected( TInt aInternalId )
       
   283 {
       
   284     TInt cmdId = 0;
       
   285     if (menuItemObserver(aInternalId, cmdId )) {
       
   286         menuItemObserver(aInternalId, cmdId)->InvokeCall(cmdId);
       
   287     }
       
   288 }
       
   289 
       
   290 
       
   291 
       
   292 ////////////////////////////////////////////////////////////////////////////////
       
   293 // From MWidgetExtension
       
   294 // -----------------------------------------------------------------------------
       
   295 // CMenuClient::HandleCommandL
       
   296 //
       
   297 //
       
   298 //
       
   299 // -----------------------------------------------------------------------------
       
   300 //
       
   301 TBool CMenuClient::HandleCommandL( TInt aCommandId )
       
   302 {
       
   303     if ( aCommandId == EAknSoftkeyExit && m_jsmenu && m_jsmenu->rightKeyCallback() ) {
       
   304         m_jsmenu->rightKeyCallback()->InvokeCall();
       
   305         return ETrue;
       
   306     }
       
   307     
       
   308     if ( aCommandId == EAknSoftkeyOptions && m_jsmenu && m_jsmenu->leftKeyCallback() ) {
       
   309             m_jsmenu->leftKeyCallback()->InvokeCall();
       
   310             return ETrue;
       
   311     }
       
   312 
       
   313     return EFalse;
       
   314 }
       
   315 
       
   316 
       
   317 ////////////////////////////////////////////////////////////////////////////////
       
   318 //From MJSMenuCallbacks
       
   319 // -----------------------------------------------------------------------------
       
   320 // CMenuClient::setRightSoftKeyLabel
       
   321 //
       
   322 //
       
   323 //
       
   324 // -----------------------------------------------------------------------------
       
   325 //
       
   326 void CMenuClient::setRightSoftKeyLabel( const TDesC& aText )
       
   327 {
       
   328     m_widgetenginecallback->setRightSoftKeyLabel(aText); 
       
   329 }
       
   330 
       
   331 ////////////////////////////////////////////////////////////////////////////////
       
   332 //From MJSMenuCallbacks
       
   333 // -----------------------------------------------------------------------------
       
   334 // CMenuClient::setLeftSoftKeyLabel
       
   335 //
       
   336 //
       
   337 //
       
   338 // -----------------------------------------------------------------------------
       
   339 //
       
   340 void CMenuClient::setLeftSoftKeyLabel( const TDesC& aText )
       
   341 {
       
   342     m_widgetenginecallback->setLeftSoftKeyLabel(aText); 
       
   343 }
       
   344 
       
   345 // -----------------------------------------------------------------------------
       
   346 // CMenuClient::clearMenuItems
       
   347 //
       
   348 //
       
   349 //
       
   350 // -----------------------------------------------------------------------------
       
   351 //
       
   352 void CMenuClient::clearMenuItems()
       
   353 {
       
   354     if ( iMenuRoot )
       
   355         showTree( iMenuRoot->firstChild(), EFalse );  
       
   356 }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // CMenuClient::getFromMenuItemCollection
       
   360 //
       
   361 //
       
   362 //
       
   363 // -----------------------------------------------------------------------------
       
   364 //
       
   365 void* CMenuClient::getFromMenuItemCollection( const TDesC& aTextVal ) 
       
   366 {
       
   367     CMenuItem* node = NULL;
       
   368     node = findNodeByText( iMenuRoot, aTextVal );
       
   369 
       
   370     if ( node )
       
   371         return node->obj();
       
   372     
       
   373     return NULL;
       
   374 }
       
   375 
       
   376 // -----------------------------------------------------------------------------
       
   377 // CMenuClient::getFromMenuItemCollection
       
   378 //
       
   379 //
       
   380 //
       
   381 // -----------------------------------------------------------------------------
       
   382 //
       
   383 void* CMenuClient::getFromMenuItemCollection( TInt aCmdId ) 
       
   384 {
       
   385     CMenuItem* node = NULL;
       
   386     node = findNodeByCmdId( iMenuRoot, aCmdId );
       
   387 
       
   388     if ( node )
       
   389         return node->obj();
       
   390     
       
   391     return NULL;
       
   392 }
       
   393 
       
   394 // -----------------------------------------------------------------------------
       
   395 // CMenuClient::hideSoftkeys
       
   396 //
       
   397 //
       
   398 //
       
   399 // -----------------------------------------------------------------------------
       
   400 //
       
   401 void CMenuClient::hideSoftkeys()
       
   402 {    
       
   403     iWidgetCallback->SetSoftkeysVisible(EFalse);
       
   404 }
       
   405 
       
   406 // -----------------------------------------------------------------------------
       
   407 // CMenuClient::showSoftkeys
       
   408 //
       
   409 //
       
   410 //
       
   411 // -----------------------------------------------------------------------------
       
   412 //
       
   413 void CMenuClient::showSoftkeys()        
       
   414 {   
       
   415     iWidgetCallback->SetSoftkeysVisible(ETrue);
       
   416 }
       
   417 
       
   418 ////////////////////////////////////////////////////////////////////////////////
       
   419 //From MJSMenuItemCallbacks
       
   420 
       
   421 // -----------------------------------------------------------------------------
       
   422 // CMenuClient::createOptionsMenuItem
       
   423 //
       
   424 //
       
   425 //
       
   426 // -----------------------------------------------------------------------------
       
   427 //
       
   428 TInt CMenuClient::createOptionsMenuItem( const TDesC& aText, TInt aCmdId, TInt aInternalId, void* aObj )
       
   429 {    
       
   430     if ( !iMenuRoot ) {
       
   431         iMenuRoot = CMenuItem::NewL( _L(""), -1, -1 );
       
   432     }
       
   433 
       
   434     CMenuItem* item = CMenuItem::NewL(aText, aCmdId, aInternalId, EFalse, iMenuRoot, aObj, EFalse);
       
   435         
       
   436     return append( iMenuRoot, item );            
       
   437 }
       
   438 
       
   439 // -----------------------------------------------------------------------------
       
   440 // CMenuClient::addOptionsMenuItem
       
   441 //
       
   442 //
       
   443 //
       
   444 // -----------------------------------------------------------------------------
       
   445 //
       
   446 TInt CMenuClient::addOptionsMenuItem( TInt aInternalId, TInt aParentInternalId, TBool aShow )
       
   447 {    
       
   448     if ( !iMenuRoot ) {
       
   449         iMenuRoot = CMenuItem::NewL( _L(""), -1, -1 );
       
   450     }    
       
   451 
       
   452     // Find item in actual or real tree by the internal id
       
   453     CMenuItem* item = findNodeById( iMenuRoot, aInternalId, ERealOrVirtual );
       
   454 
       
   455     if ( !item )
       
   456         return KErrGeneral;
       
   457 
       
   458     if ( aShow ) {
       
   459         
       
   460         // if there is a clash by cmdid or text of this item or any of its descendents 
       
   461         // with any real tree item return KErrAlreadyExists
       
   462         if ( findNodeByCmdId( iMenuRoot, item->cmdId() ) || 
       
   463             findNodeByText( iMenuRoot, item->text() ) || 
       
   464             isDuplicate( item->firstChild() ) ) {
       
   465             return KErrAlreadyExists;
       
   466         }
       
   467             
       
   468     }
       
   469   
       
   470     // Find parent in real or virtual tree
       
   471     CMenuItem* parent = findNodeById( iMenuRoot, aParentInternalId, ERealOrVirtual );
       
   472     // if this is a new parent, rearrange the tree
       
   473     CMenuItem* currParent = item->parent();
       
   474 
       
   475     if ( ( aParentInternalId == -1 && aShow ) || 
       
   476         ( currParent && currParent->internalId() != aParentInternalId ) ) {
       
   477     
       
   478         rearrangeTree( parent, item, aShow );// item is deleted in RearrangeTree
       
   479         return KErrNone;
       
   480     }
       
   481     
       
   482     return KErrGeneral;
       
   483 }
       
   484 
       
   485 // -----------------------------------------------------------------------------
       
   486 // CMenuClient::deleteMenuItem
       
   487 //
       
   488 //
       
   489 //
       
   490 // -----------------------------------------------------------------------------
       
   491 //
       
   492 void CMenuClient::deleteMenuItem( TInt aInternalId )
       
   493 {    
       
   494     CMenuItem* item = NULL;
       
   495     CMenuItem* node = findNodeById( iMenuRoot, aInternalId, EReal );
       
   496 
       
   497     if ( !node )
       
   498         return;
       
   499 
       
   500     CMenuItem* parent = node->parent();
       
   501 
       
   502     if ( !parent || !parent->firstChild() )
       
   503         return;
       
   504 
       
   505     //it could be first child
       
   506     if ( parent->firstChild()->internalId() == aInternalId ) {
       
   507         item = parent->firstChild();
       
   508         //the sibling of firstchild will be the new firstchild
       
   509         parent->setFirstChild( item->nextSibling() );
       
   510     }    
       
   511     //or one of the sibling of firstchild
       
   512     else {
       
   513         CMenuItem* prev = parent->firstChild();
       
   514         if ( prev ) {
       
   515             item = prev->nextSibling();
       
   516         }
       
   517 
       
   518         while( item ) {
       
   519             if ( item->internalId() == aInternalId ) {
       
   520                 prev->setNextSibling( item->nextSibling() );
       
   521                 break;
       
   522             }
       
   523             prev = item;
       
   524             item = item->nextSibling();
       
   525         }
       
   526     }
       
   527 
       
   528     if ( item && item->internalId() == aInternalId ) {
       
   529         // rearrange the tree and insert the item and its children in the virtual tree
       
   530         rearrangeTree( iMenuRoot, item, EFalse );      
       
   531         return;          
       
   532     }  
       
   533 }
       
   534 
       
   535 // -----------------------------------------------------------------------------
       
   536 // CMenuClient::setDimmed
       
   537 //
       
   538 //
       
   539 //
       
   540 // -----------------------------------------------------------------------------
       
   541 //
       
   542 void CMenuClient::setDimmed( TInt aInternalId, TBool aValue )
       
   543 {
       
   544     CMenuItem* node = NULL;
       
   545     node = findNodeById( iMenuRoot, aInternalId, EReal );
       
   546 
       
   547     if ( node ) {
       
   548         node->setDimmed( aValue );
       
   549     }
       
   550 
       
   551 }
       
   552 
       
   553 // -----------------------------------------------------------------------------
       
   554 // CMenuClient::menuItemObserver
       
   555 //
       
   556 //
       
   557 //
       
   558 // -----------------------------------------------------------------------------
       
   559 //
       
   560 KJS::WidgetEventHandler* CMenuClient::menuItemObserver( TInt aInternalId, TInt& aCmdId )
       
   561 {
       
   562     CMenuItem* node = NULL;
       
   563     node = findNodeById( iMenuRoot, aInternalId, EReal );
       
   564 
       
   565     if ( node ) {
       
   566         aCmdId = node->cmdId();
       
   567         return node->callback();
       
   568     }
       
   569     
       
   570     return NULL;    
       
   571 
       
   572 }
       
   573 
       
   574 // -----------------------------------------------------------------------------
       
   575 // CMenuClient::setMenuItemObserver
       
   576 //
       
   577 //
       
   578 //
       
   579 // -----------------------------------------------------------------------------
       
   580 //
       
   581 void CMenuClient::setMenuItemObserver( TInt aInternalId, KJS::WidgetEventHandler* aOnSelectCallback )
       
   582 {    
       
   583     CMenuItem* node = NULL;
       
   584     node = findNodeById( iMenuRoot, aInternalId, ERealOrVirtual );
       
   585 
       
   586     if ( node ) {
       
   587         node->setCallback( aOnSelectCallback );
       
   588     }
       
   589     
       
   590 }
       
   591 
       
   592 
       
   593 ////////////////////////////////////////////////////////////////////////////////
       
   594 //private
       
   595 // ----------------------------------------------------------------------------
       
   596 // CMenuClient::deleteTree
       
   597 // Delete node and all its children.
       
   598 //
       
   599 //
       
   600 // ----------------------------------------------------------------------------
       
   601 //
       
   602 void CMenuClient::deleteTree( CMenuItem* aNode )
       
   603 {
       
   604 
       
   605     if ( aNode != NULL ) {
       
   606         deleteTree( aNode->firstChild() );
       
   607         deleteTree( aNode->nextSibling() );         
       
   608         delete aNode;
       
   609         aNode = NULL;
       
   610     }
       
   611 
       
   612 }
       
   613 
       
   614 // ----------------------------------------------------------------------------
       
   615 // CMenuClient::insertTree
       
   616 // this function inserts all items in a menupane with all its desendents 
       
   617 //    (i.e) all its cascade menupanes
       
   618 //
       
   619 //
       
   620 // ----------------------------------------------------------------------------
       
   621 //
       
   622 void CMenuClient::insertTree( CMenuItem* aParent, CMenuItem* aItem )
       
   623 {
       
   624 
       
   625     if ( !aParent || !aItem )
       
   626         return;
       
   627     
       
   628     CMenuItem* newItem = CMenuItem::NewL( aItem->text(), aItem->cmdId(), 
       
   629                                          aItem->internalId(), aItem->dimmed(), 
       
   630                                          aParent, aItem->obj(), aParent->show() );
       
   631     append( aParent, newItem );        
       
   632     // Insert all children
       
   633     insertTree( newItem, aItem->firstChild() );
       
   634     // Insert all siblings
       
   635     insertTree( aParent, aItem->nextSibling() );    
       
   636 
       
   637     return;
       
   638 }
       
   639 
       
   640 // ----------------------------------------------------------------------------
       
   641 // CMenuClient::rearrangeTree
       
   642 // this function rearranges the tree when the parent of a node changes
       
   643 //
       
   644 //
       
   645 // ----------------------------------------------------------------------------
       
   646 //
       
   647 void CMenuClient::rearrangeTree( CMenuItem* aParent, CMenuItem* aItem, TBool aShow )
       
   648 {
       
   649 
       
   650     CMenuItem* newItem = CMenuItem::NewL( aItem->text(), aItem->cmdId(), 
       
   651                                         aItem->internalId(), aItem->dimmed(), 
       
   652                                         aParent, aItem->obj(), aShow );
       
   653     append( aParent, newItem );
       
   654     insertTree( newItem, aItem->firstChild() );
       
   655     deleteTree( aItem->firstChild() );                    
       
   656     deleteItem( aItem ); 
       
   657 
       
   658 }
       
   659 
       
   660 // ----------------------------------------------------------------------------
       
   661 // CMenuClient::showTree
       
   662 // Set show flag for node, its siblings, and all their children.
       
   663 //
       
   664 //
       
   665 // ----------------------------------------------------------------------------
       
   666 //
       
   667 void CMenuClient::showTree( CMenuItem* aItem, TBool aShow )
       
   668 {
       
   669     if ( !aItem )
       
   670         return;
       
   671 
       
   672     aItem->setShow( aShow );
       
   673     showTree( aItem->firstChild(), aShow );
       
   674     showTree( aItem->nextSibling(), aShow );  
       
   675 
       
   676 }
       
   677     
       
   678 // -----------------------------------------------------------------------------
       
   679 // CMenuClient::DeleteItem
       
   680 //
       
   681 //
       
   682 //
       
   683 // -----------------------------------------------------------------------------
       
   684 //
       
   685 void CMenuClient::deleteItem( CMenuItem* aItem )
       
   686 {
       
   687 
       
   688     if ( !aItem )
       
   689         return;
       
   690 
       
   691     CMenuItem* parent = aItem->parent();
       
   692 
       
   693     if ( !parent )
       
   694         return;
       
   695 
       
   696     if ( parent->firstChild() == aItem ) { //first child
       
   697             
       
   698         parent->setFirstChild( aItem->nextSibling() );
       
   699         delete aItem;
       
   700         aItem = NULL;
       
   701     }
       
   702     else { //sibling of first child        
       
   703         deleteSibling( parent->firstChild(), aItem );       
       
   704     }
       
   705 
       
   706     return;
       
   707 }
       
   708 
       
   709 // -----------------------------------------------------------------------------
       
   710 // CMenuClient::deleteSibling
       
   711 //
       
   712 //
       
   713 //
       
   714 // -----------------------------------------------------------------------------
       
   715 //
       
   716 void CMenuClient::deleteSibling( CMenuItem* aNode, CMenuItem* aItem )
       
   717 {
       
   718     if ( !aNode || !aItem )
       
   719         return;
       
   720 
       
   721     if ( aNode->nextSibling() == aItem  ) { //first sibling        
       
   722         aNode->setNextSibling( aItem->nextSibling() );
       
   723         delete aItem;
       
   724         aItem = NULL;
       
   725     }
       
   726     else {    
       
   727         deleteSibling( aNode->nextSibling(), aItem );
       
   728     }
       
   729 
       
   730     return;
       
   731 }
       
   732     
       
   733 // ----------------------------------------------------------------------------
       
   734 // CMenuClient::addMenuItem
       
   735 //
       
   736 //
       
   737 //
       
   738 // ----------------------------------------------------------------------------
       
   739 //
       
   740 void CMenuClient::addMenuItem( CEikMenuPane& aMenuPane, CMenuItem* aNode, TBool aIsRootMenuPane)
       
   741 {
       
   742     if ( !aNode->show() )
       
   743         return;
       
   744 
       
   745     CEikMenuPaneItem::SData menuData;
       
   746     menuData.iCommandId = aNode->internalId() + KMenuItemCommandIdBase;
       
   747 
       
   748     if ( aNode->firstChild() ) {
       
   749         if ( iResourceId > R_CASCADE_MENU_1 + KMaxOptionsMenu ) {
       
   750             return; //Dont add any menu item any more
       
   751         }
       
   752         else {
       
   753             menuData.iCascadeId = iResourceId;
       
   754         }
       
   755     }
       
   756     else {
       
   757         menuData.iCascadeId = 0;
       
   758     }
       
   759 
       
   760     menuData.iFlags = 0;
       
   761     menuData.iText = aNode->text();
       
   762 
       
   763     TCascadeIDMap entry;
       
   764     entry.iResourceId = iResourceId++;
       
   765     entry.parentInternalId = aNode->internalId();
       
   766     iCascadeArr.Append( entry );
       
   767 
       
   768     //Since root menu pane has "Exit" at the botton, menu items must be added at last - 1
       
   769     //else items will get appended below "Exit"
       
   770     TInt index = aIsRootMenuPane ? aMenuPane.NumberOfItemsInPane() - 1 : aMenuPane.NumberOfItemsInPane();
       
   771     aMenuPane.InsertMenuItemL( menuData, index );
       
   772     aMenuPane.SetItemDimmed( aNode->internalId()+KMenuItemCommandIdBase, aNode->dimmed() );
       
   773 
       
   774 }
       
   775 
       
   776 
       
   777 // -----------------------------------------------------------------------------
       
   778 // CMenuClient::append
       
   779 //
       
   780 //
       
   781 //
       
   782 // -----------------------------------------------------------------------------
       
   783 //
       
   784 TInt CMenuClient::append( CMenuItem* aParent, CMenuItem* aItem )
       
   785 {
       
   786 
       
   787     if ( !aParent || !aItem )
       
   788         return KErrGeneral;
       
   789 
       
   790     if ( aParent->firstChild() == NULL ) {//first child        
       
   791         aParent->setFirstChild( aItem );
       
   792     }
       
   793     else { //insert as sibling of first child        
       
   794         appendSibling( aParent->firstChild(), aItem );
       
   795     }
       
   796 
       
   797     return KErrNone;
       
   798 }
       
   799 
       
   800 
       
   801 // -----------------------------------------------------------------------------
       
   802 // CMenuClient::appendSibling
       
   803 //
       
   804 //
       
   805 //
       
   806 // -----------------------------------------------------------------------------
       
   807 //
       
   808 void CMenuClient::appendSibling( CMenuItem* aNode, CMenuItem* aItem )
       
   809 {
       
   810 
       
   811     if ( !aNode || !aItem )
       
   812         return;
       
   813 
       
   814     if ( aNode->nextSibling() == NULL ) { //first sibling        
       
   815         aNode->setNextSibling( aItem );
       
   816     }
       
   817     else {
       
   818         appendSibling( aNode->nextSibling(), aItem );
       
   819     }
       
   820 
       
   821     return;
       
   822 }
       
   823 
       
   824 
       
   825 // ----------------------------------------------------------------------------
       
   826 // CMenuClient::findNodeById
       
   827 //
       
   828 //
       
   829 //
       
   830 // ----------------------------------------------------------------------------
       
   831 //
       
   832 CMenuItem* CMenuClient::findNodeById( CMenuItem* node, TInt aInternalId, TMenuItemState aState )
       
   833 {
       
   834     
       
   835     CMenuItem* item = NULL;
       
   836     
       
   837     if ( !node )
       
   838         return NULL;
       
   839 
       
   840     if ( node->internalId() == aInternalId ) {
       
   841         if ( aState == EReal && node->show() )
       
   842             return node;
       
   843         else if ( aState == EVirtual && !node->show() )
       
   844             return node;
       
   845         else if ( aState == ERealOrVirtual )
       
   846             return node;
       
   847     }
       
   848     else {
       
   849         
       
   850         if ( node->firstChild() ) {
       
   851             item = findNodeById( node->firstChild(), aInternalId, aState );
       
   852             if ( item )
       
   853                 return item;
       
   854         }
       
   855     
       
   856         if ( node->nextSibling() ) {
       
   857             item = findNodeById( node->nextSibling(), aInternalId, aState );
       
   858         }
       
   859     }
       
   860     
       
   861     return item;
       
   862 }
       
   863 
       
   864 
       
   865 // ----------------------------------------------------------------------------
       
   866 // CMenuClient::isDuplicate
       
   867 //
       
   868 //
       
   869 //
       
   870 // ----------------------------------------------------------------------------
       
   871 //
       
   872 TBool CMenuClient::isDuplicate( CMenuItem* node )
       
   873 {
       
   874     
       
   875     if ( !node )
       
   876         return EFalse;
       
   877 
       
   878     if ( findNodeByCmdId( iMenuRoot, node->cmdId() ) || 
       
   879          findNodeByText( iMenuRoot, node->text() ) )
       
   880         return ETrue;
       
   881 
       
   882     if ( isDuplicate( node->firstChild() ) )
       
   883         return ETrue;
       
   884     else
       
   885         return isDuplicate( node->nextSibling() );    
       
   886     
       
   887 }
       
   888 
       
   889 // ----------------------------------------------------------------------------
       
   890 // CMenuClient::findNodeByCmdId
       
   891 //
       
   892 //
       
   893 //
       
   894 // ----------------------------------------------------------------------------
       
   895 //
       
   896 CMenuItem* CMenuClient::findNodeByCmdId( CMenuItem* node, TInt aCmdId )
       
   897 {
       
   898     
       
   899     CMenuItem* item = NULL;
       
   900     
       
   901     if ( !node )
       
   902         return NULL;
       
   903 
       
   904     if ( node->cmdId() == aCmdId && node->show() ) {        
       
   905         return node;      
       
   906     }
       
   907     else {
       
   908         if ( node->firstChild() ) {
       
   909             item = findNodeByCmdId( node->firstChild(), aCmdId );
       
   910             if ( item )
       
   911                 return item;
       
   912         }
       
   913         
       
   914         if ( node->nextSibling() ) {
       
   915             item = findNodeByCmdId( node->nextSibling(), aCmdId );
       
   916         }
       
   917     }
       
   918     
       
   919     return item;
       
   920 }
       
   921 
       
   922 // ----------------------------------------------------------------------------
       
   923 // CMenuClient::findNodeByText
       
   924 //
       
   925 //
       
   926 //
       
   927 // ----------------------------------------------------------------------------
       
   928 //
       
   929 CMenuItem* CMenuClient::findNodeByText( CMenuItem* node, const TDesC& aText )
       
   930 {
       
   931     CMenuItem* item = NULL;
       
   932 
       
   933     if ( !node )
       
   934         return NULL;
       
   935 
       
   936     if ( node->text().CompareC( aText ) == 0 && node->show() )
       
   937         return node;
       
   938 
       
   939     item = findNodeByText( node->firstChild(), aText );
       
   940 
       
   941     if ( item )
       
   942         return item;
       
   943         
       
   944     item = findNodeByText( node->nextSibling(), aText );    
       
   945 
       
   946     return item;
       
   947 }
       
   948 
       
   949 
       
   950 
       
   951 
       
   952 
       
   953 //END OF FILE
       
   954 
       
   955 
       
   956 
       
   957 
       
   958