javauis/eswt_akn/org.eclipse.ercp.swt.s60/native/src/swtcommandmenu.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Wed, 13 Oct 2010 14:23:59 +0300
branchRCL_3
changeset 83 26b2b12093af
parent 66 2455ef1f5bbc
permissions -rw-r--r--
Revision: v2.2.17 Kit: 201041

/*******************************************************************************
 * Copyright (c) 2005, 2010 Nokia Corporation and/or its subsidiary(-ies).
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Nokia Corporation - S60 implementation
 *******************************************************************************/


#include <eikhkeyt.h>
#include <eikon.hrh>
#include <eswtcore.rsg>
#ifdef RD_SCALABLE_UI_V2
#include <aknstyluspopupmenu.h>
#endif //RD_SCALABLE_UI_V2
#include "swtcommandmenu.h"


const TUint KCknEnvClipEndChar=0x2026;


// ======== MEMBER FUNCTIONS ========


inline CSwtCommandMenu::CSwtCommandMenu(MSwtDisplay& aDisplay)
        : iDisplay(aDisplay)
{
}

CSwtCommandMenu::~CSwtCommandMenu()
{
    ASSERT(iItems.Count() == 0);
    iItems.Close();
    ASSERT(iCascadeMenus.Count() == 0);
    iCascadeMenus.Close();
    ASSERT(iSeparators.Count() == 0);
    iSeparators.Close();
}

void CSwtCommandMenu::ConstructL()
{
} //lint !e1762

CSwtCommandMenu* CSwtCommandMenu::NewL(MSwtDisplay& aDisplay)
{
    CSwtCommandMenu* self = new(ELeave) CSwtCommandMenu(aDisplay);
    CleanupStack::PushL(self);
    self->ConstructL();
    CleanupStack::Pop(self);
    return self;
}

void CSwtCommandMenu::Reset()
{
    iItems.Reset();
    iCascadeMenus.Reset();
    iSeparators.Reset();
}

void CSwtCommandMenu::AppendCommand(const MSwtCommand& aCommand,
                                    const MSwtMenu* aCascadeMenu)
{
    // If append fails then item won't appear in menu (and separators might
    // appear at wrong places if later appends succeed). It's a shame but
    // it's like that (nothing specific to do if this happens).
    if (iItems.Append(&aCommand) == KErrNone)
    {
        if (iCascadeMenus.Append(aCascadeMenu) != KErrNone)
        {
            // If append in cascademenus array fails then remove item to avoid
            // arrays not being synchronized
            iItems.Remove(iItems.Count() - 1);
        }
    }
}

void CSwtCommandMenu::InsertCommand(const MSwtCommand& aCommand,
                                    const MSwtMenu* aCascadeMenu, TInt aPos)
{
    // If insert fails then item won't appear in menu (and separators might
    // appear at wrong places if later appends succeed). It's a shame but
    // it's like that (nothing specific to do if this happens).
    if (iItems.Insert(&aCommand, aPos) == KErrNone)
    {
        if (iCascadeMenus.Insert(aCascadeMenu, aPos) != KErrNone)
        {
            // If insert in cascademenus array fails then remove item to avoid
            // arrays not being synchronized
            iItems.Remove(aPos);
        }
    }
}

void CSwtCommandMenu::AppendSeparator()
{
    // If append fails then separator won't appear in menu. It's a shame but
    // it's like that (nothing specific to do if this happens).
    iSeparators.Append(iItems.Count() - 1);
}

const RPointerArray<MSwtCommand>& CSwtCommandMenu::Commands() const
{
    return iItems;
}

TSwtPeer CSwtCommandMenu::Dispose()
{
    // Actual dispose
    delete this;
    return NULL;
}

TSwtPeer CSwtCommandMenu::JavaPeer() const
{
    return NULL;
}

void CSwtCommandMenu::RegisterChildL(MSwtMenuItem& /*aChild*/, TInt /*aIndex*/)
{
    // CommandMenu contains commands instead of menuitems, so this method is not used
}

void CSwtCommandMenu::UnregisterChild(MSwtMenuItem& /*aChild*/)
{
    // CommandMenu contains commands instead of menuitems, so this method is not used
}

void CSwtCommandMenu::SetEnabled(TBool)
{
}

void CSwtCommandMenu::SetVisible(TBool)
{
}

TBool CSwtCommandMenu::IsEnabled() const
{
    return ETrue;
}

TBool CSwtCommandMenu::IsVisible() const
{
    return ETrue;
}

void CSwtCommandMenu::SetDefaultItem(MSwtMenuItem*)
{
}

MSwtMenuItem* CSwtCommandMenu::DefaultItem() const
{
    return NULL;
}

void CSwtCommandMenu::FillPaneL(CEikMenuPane& aMenuPaneControl) const
{
    TInt separatorIndex = 0;
    TInt count = iItems.Count();
    for (TInt itemIndex = 0; itemIndex < count; ++itemIndex)
    {
        CEikMenuPaneItem::SData itemData;
        TInt maxLength = itemData.iText.MaxLength();
        if (iItems[itemIndex]->LongLabel().Length() > 0
                && iItems[itemIndex]->LongLabel().Length() <= maxLength)
        {
            itemData.iText = iItems[itemIndex]->LongLabel();
        }
        else if (iItems[itemIndex]->Text().Length() <= maxLength)
        {
            itemData.iText = iItems[itemIndex]->Text();
        }
        else
        {
            itemData.iText = iItems[itemIndex]->Text().Left(maxLength - 1);
            itemData.iText.Append(KCknEnvClipEndChar);
        }
        itemData.iExtraText = KNullDesC;
        itemData.iFlags = iItems[itemIndex]->IsEnabled() ? 0 : EEikMenuItemDimmed;
        if ((separatorIndex < iSeparators.Count()) && (iSeparators[separatorIndex] == itemIndex))
        {
            itemData.iFlags |= EEikMenuItemSeparatorAfter;
            ++separatorIndex;
        }
        itemData.iCommandId = reinterpret_cast<TInt>(iItems[itemIndex]);
        itemData.iCascadeId = (iCascadeMenus[itemIndex] != NULL) ? R_SWT_SUBMENUPANE : 0;

        aMenuPaneControl.AddMenuItemL(itemData);
    }

    // Register the pane host. See Host().
    iHost = &aMenuPaneControl;
}

void CSwtCommandMenu::ProcessCommandL(TInt aCommandId, TInt aItemIndex,
                                      TBool /*aOfferToSubMenus = EFalse*/) const
{
//  if (reinterpret_cast<TInt>(iItems[aItemIndex]) == aCommandId)
    const MSwtCommand* command = reinterpret_cast<MSwtCommand*>(aCommandId);
    aItemIndex = iItems.Count();
    for (TInt itemIndex = 0; itemIndex < iItems.Count(); ++itemIndex)
    {
        if (command == iItems[itemIndex])
        {
            aItemIndex = itemIndex;
            break;
        }
    }
    if (aItemIndex < iItems.Count())
    {
        iDisplay.PostSelectionEventL(iItems[aItemIndex]->JavaPeer());
    }
}

TInt CSwtCommandMenu::CountDisplayableItems(TBool /*aStylusPopupMenu = EFalse*/) const
{
    // The displayable items are the enabled items
    // since, in S60, the disabled items are not added in the menu panes
    TInt nbDisplayableItems(0);
    for (TInt itemIndex = 0; itemIndex < iItems.Count(); ++itemIndex)
    {
        if (iItems[itemIndex]->IsEnabled())
        {
            nbDisplayableItems++;
        }
    }

    return nbDisplayableItems;
}

const MSwtMenu* CSwtCommandMenu::GetCascadeMenu(const CEikMenuPaneItem::SData& aItemData) const
{
    for (TInt itemIndex = 0; itemIndex < iItems.Count(); ++itemIndex)
    {
        if (iItems[itemIndex]->IsEnabled())
        {
            TInt commandId(REINTERPRET_CAST(TInt, iItems[itemIndex]));
            if (commandId == aItemData.iCommandId)
            {
                return iCascadeMenus[itemIndex];
            }
        }
    }

    return NULL;
}

TBool CSwtCommandMenu::HasRadioGroup() const
{
    return EFalse;
}

CEikMenuPane* CSwtCommandMenu::Host() const
{
    return iHost;
}

void CSwtCommandMenu::SetHost(CEikMenuPane* aPane)
{
    iHost = aPane;
}

void CSwtCommandMenu::SetLocation(TInt /*aX*/, TInt /*aY*/)
{
    // Command menu is not able to change its location
    // This part of code should never be used!
}

TPoint CSwtCommandMenu::GetLocation() const
{
    // Command menu is not able to change its location
    // This part of code should never be used!
    ASSERT(EFalse);
    return TPoint();
}

TBool CSwtCommandMenu::LocationEnabled() const
{
    return EFalse;
}

const RPointerArray<MSwtMenuItem>* CSwtCommandMenu::Items() const
{
    return NULL;
}

#ifdef RD_SCALABLE_UI_V2
void CSwtCommandMenu::FillPopupL(CAknStylusPopUpMenu& aPopupMenu) const
{
    for (TInt i = 0; i < iItems.Count(); ++i)
    {
        if (iItems[i]->IsEnabled())
        {
            if (iItems[i]->LongLabel().Length() > 0)
            {
                aPopupMenu.AddMenuItemL(iItems[i]->LongLabel(),
                                        reinterpret_cast<TInt>(iItems[i]));
            }
            else
            {
                aPopupMenu.AddMenuItemL(iItems[i]->Text(), reinterpret_cast<TInt>(iItems[i]));
            }
        }
    }
}
#endif //RD_SCALABLE_UI_V2