qtinternetradio/ui/src/irstationsview.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Mon, 19 Apr 2010 14:01:53 +0300
changeset 0 09774dfdd46b
child 2 2e1adbfc62af
permissions -rw-r--r--
Revision: 201011 Kit: 201015

/*
* Copyright (c) 2009 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:
*
*/
#include <QPixmap>
#include <hblistview.h>
#include <hbaction.h>
#include <QTimer>

#include "irabstractviewmanager.h"
#include "irstationsview.h"
#include "irapplication.h"
#include "irplaycontroller.h"
#include "irqisdsclient.h"
#include "irqenums.h"
#include "irqutility.h"
#include "irchannelmodel.h"
#include "irqisdsdatastructure.h"
#include "irqnetworkcontroller.h"

const int KBitmapSize = 59; 
const uint KConnectTimeOut = 15000; //if the connecting take more than 15 seconds, we will show a pop up

//                                      public functions

/*
 * Description : constructor
 */
IRStationsView::IRStationsView(IRApplication* aApplication, TIRViewId aViewId) 
                               : IrAbstractListViewBase(aApplication, aViewId),
                               iLogoPreset(NULL),  iPreset(NULL), 
                               iWaitDialog(NULL),
                               iViewParameter(EIRViewPara_InvalidId),iLastSelectitem(0),
                               iLastPopularItem(0)                          
{       
    iIconIndexArray.clear();
    iChannelModel = new IrChannelModel(this);
    iListView->setModel(iChannelModel);
    
    
    iConnectTimer = new QTimer(this);
    iConnectTimer->setInterval(KConnectTimeOut);     
    
    iConvertTimer = new QTimer(this);
    iConvertTimer->setInterval(10);    
    
    connect(iChannelModel, SIGNAL(dataAvailable()), this, SLOT(dataChanged()));    
    connect(iNetworkController, SIGNAL(networkRequestNotified(IRQNetworkEvent)),
            this, SLOT(networkRequestNotified(IRQNetworkEvent)));    
    connect(iConnectTimer, SIGNAL(timeout()), this, SLOT(connectTimeOut()));
    connect(iConvertTimer, SIGNAL(timeout()), this, SLOT(convertAnother()));
}

/*
 * Description : destructor
 */
IRStationsView::~IRStationsView()
{
    delete iPreset;
    iPreset = NULL;

    delete iLogoPreset;
    iLogoPreset = NULL;

    delete iWaitDialog;
    iWaitDialog = NULL;
    
 
 
}

void IRStationsView::setViewParameter(TIRViewParameter aParameter)
{
    iViewParameter = aParameter;
}

TIRViewParameter IRStationsView::getViewParameter() const
{
    return iViewParameter;
}

void IRStationsView::loadCategoryStations(int aIndex, const QString &aHeadingText)
{
    connectToIsdsClient();
    setHeadingText(aHeadingText);
    setViewParameter(EIRViewPara_CategoryStations);
    
    bool cache = false;
    iIsdsClient->isdsChannelRequest(aIndex, cache);
    
    if (!cache)
    {
        createWaitDialog(hbTrId("txt_common_info_loading"));
    }
}

void IRStationsView::loadPopularStations(bool aShowWaitDialog)
{
    connectToIsdsClient();
    setViewParameter(EIRViewPara_PopularStations);
    setHeadingText(tr("Popular stations"));
    bool cache = false;
    iIsdsClient->isdsCategoryRequest(IRQIsdsClient::Ehotpicks, cache);
     
    if (!cache && aShowWaitDialog)
    {
        createWaitDialog(hbTrId("txt_common_info_loading"));
    }
}

void IRStationsView::loadSearchResult(const QString &aStr)
{
    connectToIsdsClient();
    setViewParameter(EIRViewPara_SearchResults);
    setHeadingText(hbTrId("txt_irad_subtitle_search_result"));
    iIsdsClient->isdsSearchRequest(aStr);    
    if( iConnectTimer->isActive() )
    {
        iConnectTimer->stop();
    }
    
    iConnectTimer->start();
    createWaitDialog(hbTrId("txt_common_info_searching"));
}

void IRStationsView::storeCurrentItem()
{
    switch (getViewParameter())
    {
    case EIRViewPara_PopularStations:
        iLastPopularItem = iListView->currentIndex().row();
        break;
    case EIRViewPara_CategoryStations:
        iLastSelectitem = iListView->currentIndex().row();
        break;
    default:
        break;
    }
}

void IRStationsView::resetCurrentItem()
{
    iLastSelectitem = 0;
}

/*
 * Description : from base class IRBaseView.
 *               handle view commands.
 * Parameters  : aCommand : see the definition of TIRViewCommand
 * Return      : EIR_DoDefault : caller does default handling
 *               EIR_NoDefault : caller doesn't do default handling
 */
TIRHandleResult IRStationsView::handleCommand(TIRViewCommand aCommand, TIRViewCommandReason aReason)
{
    TIRHandleResult ret = IrAbstractListViewBase::handleCommand(aCommand, aReason);
    int leftCount = 0;
    
    switch (aCommand)
    {   
    case EIR_ViewCommand_ACTIVATED:
        connect(iIsdsClient, SIGNAL(presetResponse(IRQPreset *)),
                this, SLOT(presetResponse(IRQPreset *)));
        connect(iIsdsClient, SIGNAL(presetLogoDownloaded(IRQPreset* )),
                this, SLOT(presetLogoDownload(IRQPreset* )));
        connect(iIsdsClient, SIGNAL(presetLogoDownloadError()),
                this, SLOT(presetLogoDownloadError()));
        
        ret = EIR_NoDefault;
        break;
        
    case EIR_ViewCommand_DEACTIVATE:
        if (aReason == EIR_ViewCommandReason_Back)
        {
            cleanupResource();
        }
        
        iConnectTimer->stop();
        iConvertTimer->stop();
        iIsdsClient->isdsLogoDownCancelTransaction();         
        
        disconnect(iIsdsClient, SIGNAL(presetResponse(IRQPreset *)),
                   this, SLOT(presetResponse(IRQPreset *)));
        disconnect(iIsdsClient, SIGNAL(presetLogoDownloaded(IRQPreset*)),
                   this, SLOT(presetLogoDownload(IRQPreset* )));
        disconnect(iIsdsClient, SIGNAL(presetLogoDownloadError()),
                   this, SLOT(presetLogoDownloadError()));        
        ret = EIR_NoDefault;
        break;
        
    case EIR_ViewCommand_EffectFinished:
        /* when the effect is finished, we start showing the logos  */
        leftCount = iIconIndexArray.count();
        if( leftCount > 0 )
        {
            iConvertTimer->start();
        }
        break;
 
    default:
        break;
    }
    
    return ret;
}

void IRStationsView::launchAction()
{
    setUseNetworkReason(EIR_UseNetwork_StartingView);
    iApplication->verifyNetworkConnectivity();
}

//                                      slots functions

/*
 * Description : slot function when an item in a list is clicked.
 *               issue a listen request to isds client
 * Parameters  : aItem : pointer to the clicked item.
 */
void IRStationsView::handleItemSelected()
{
    if (iListView)
    {
        int index = iListView->currentIndex().row();
        if (index != -1)  
        {
            if (iIsdsClient)
            {
                connect(iIsdsClient, SIGNAL(operationException(IRQError)),
                        this, SLOT(operationException(IRQError)));
                
                //once an item is selected, we show a dialog to prevent user from clicking the
                //item again
                iPlayController->createBufferingDialog(this, SLOT(cancelRequest()));
                
                if (iIsdsClient->isdsIsChannelBanner())
                {
                    iIsdsClient->isdsListenRequest(index + 1);
                }
                else
                {
                    iIsdsClient->isdsListenRequest(index);
                }
            }
        }
    }
}

/*
 * Description : data is received from isds client. Load the data to the list widget and display
 *               the stations view
 */
void IRStationsView::dataChanged()
{
	
	int currentItem = 0;
    iApplication->closeConnectingDialog();
    iConnectTimer->stop();
    if (iWaitDialog)
    {
        iWaitDialog->close();
    }
    
    disconnectIsdsClient();
    cleanupResource();
 
    
    switch (getViewParameter())
    {
    case EIRViewPara_SearchResults:
        currentItem = 0;
        break;
    case EIRViewPara_PopularStations:
        currentItem = iLastPopularItem;
        break;
    case EIRViewPara_CategoryStations:
        currentItem = iLastSelectitem;
        break;
	  default:
        break;
    }
    iListView->reset();
    iListView->setCurrentIndex(iChannelModel->index(currentItem));
    iListView->scrollTo(iChannelModel->index(currentItem));

    //initialize the iconindices
    for (int i = 0; i < iChannelModel->rowCount(); ++i)
    {
        if (iChannelModel->imageUrl(i) != "")
        {
            iIconIndexArray.append(i);
        }
    }

    getViewManager()->activateView(this);   
}

/*
 * Description : the preset of the selected station is received from isds client.
 *               application is responsible for deleting old preset.
 *               call player controler to play the station
 * Parameters  : aPreset : the preset of the selected station            
 */
void IRStationsView::presetResponse(IRQPreset *aPreset)
{
    disconnect(iIsdsClient, SIGNAL(operationException(IRQError)),
               this, SLOT(operationException(IRQError)));
    
    delete iPreset;
    iPreset = aPreset;
    
    if (iPreset)
    {
        iPlayController->connectToChannel(iPreset,EIRQIsds);
    }
}


/*
 * Description  : slot function for operation failure. The signal is emitted by isds client
 * Parameters   : aError : see the definition of IRQError
 */
void IRStationsView::operationException(IRQError aError)
{
    iApplication->closeConnectingDialog();
    iPlayController->closeBufferingDialog();
    
    if (iWaitDialog)
    {
        iWaitDialog->close();
    }
    
    disconnectIsdsClient();
    QString errorString = hbTrId("txt_irad_info_failed_to_connect");
    
    switch (aError)
    {   
    case EIRQErrorNotFound:
        errorString = hbTrId("txt_irad_info_no_matching_stations_found");
        if (iConnectTimer->isActive())
        {
            iConnectTimer->stop();
        }
        break;
        default:
            break;
    }
    
    popupNote(errorString, HbMessageBox::MessageTypeWarning);
}

void IRStationsView::cancelRequest()
{
    if( iWaitDialog )
    {
        iWaitDialog->close();
    }
    
    if( iConnectTimer->isActive())
    {
        iConnectTimer->stop();
    }    
    iIsdsClient->isdsCancelRequest();
    disconnectIsdsClient();
}

void IRStationsView::startConvert(int aIndex)
{
    QString url = iChannelModel->imageUrl(aIndex);
 
    IRQPreset tempPreset;
    tempPreset.imgUrl = url;
    tempPreset.type = IRQPreset::EIsds;
    
    bool cached = iIsdsClient->isdsIsLogoCached(&tempPreset, KBitmapSize, KBitmapSize);
    
    if( !cached )
    {
        bool network = iApplication->verifyNetworkConnectivity(hbTrId("txt_irad_info_downloading_logos"));
        if( !network )
        {
            //if user has clicked an item and the connection is being setup, we don't change the reason
            if (EIR_UseNetwork_NoReason == getUseNetworkReason())
            {
                setUseNetworkReason(EIR_UseNetwork_DownloadLogo);
            }
            iConvertTimer->stop();
            return;
        }        
    }
    
    iIsdsClient->isdsLogoDownSendRequest(&tempPreset, 0, KBitmapSize, KBitmapSize); 
}

 
//if the logo is downloaded ok
void IRStationsView::presetLogoDownload(IRQPreset* aPreset)
{
    if( NULL == aPreset )
    {
        presetLogoDownloadError();
        return;
    } 
    
 
    delete iLogoPreset;            
    iLogoPreset = aPreset;    

    if (iLogoPreset->logoData != KNullDesC8)
    {         
        QPixmap tempMap;  
        const unsigned char * logoData = iLogoPreset->logoData.Ptr();     
        bool ret = tempMap.loadFromData(logoData, iLogoPreset->logoData.Length());
        QIcon convertIcon(tempMap);
       
        if( ret )
        {            
            HbIcon *hbIcon = new HbIcon(convertIcon);
            int index = iIconIndexArray[0];
            iChannelModel->setLogo(hbIcon, index);
            iIconIndexArray.removeAt(0);     
            int leftCount = iIconIndexArray.count(); 
            if( leftCount > 0 )
            {
                iConvertTimer->start();  
            }
            return;
        }     
    }    
    
    presetLogoDownloadError(); 
}

//if the logo download fails
void IRStationsView::presetLogoDownloadError()
{
    // if the logo download fails, try to download the next
    iIconIndexArray.removeAt(0);
    int leftCount = iIconIndexArray.count();
    if( leftCount > 0 )
    {
        iConvertTimer->start();
    }    
}

void IRStationsView::cleanupResource()
{
    iIconIndexArray.clear();

    //destroy icons in time to save memory
    iChannelModel->clearAndDestroyLogos();
}

void IRStationsView::networkRequestNotified(IRQNetworkEvent aEvent)
{
    if (getViewManager()->currentView() != this)
    {
        return;
    }
    
    switch (aEvent)
    {
    case EIRQNetworkConnectionEstablished:
        if (EIR_UseNetwork_StartingView == getUseNetworkReason())
        {
            //when stations view is starting view(used to show popular stations), don't show wait dialog 
            loadPopularStations(false);
        }
        else if(EIR_UseNetwork_DownloadLogo == getUseNetworkReason())
        {
            iApplication->closeConnectingDialog();
            int leftCount = iIconIndexArray.count();
            if(0 != leftCount)
            {
            	  iConvertTimer->start();
            }            
        }
        else if (EIR_UseNetwork_SelectItem == getUseNetworkReason())
        {
            iApplication->closeConnectingDialog();
            handleItemSelected();
            int leftCount = iIconIndexArray.count();
            if(0 != leftCount)
            {
                iConvertTimer->start();
            }
        }
        setUseNetworkReason(EIR_UseNetwork_NoReason);
        
        break;
        
    case EIRQConnectingCancelled:
    case EIRQDisplayNetworkMessageNoConnectivity:
        if (iListView->model()->rowCount() == 0)
        {
            getViewManager()->activateView(EIRView_MainView);
        }
        else
        {
            setCheckedAction();
        }
        setUseNetworkReason(EIR_UseNetwork_NoReason);
        break;
        
    default:
        setCheckedAction();
        setUseNetworkReason(EIR_UseNetwork_NoReason);
        break;
    }
}

void IRStationsView::connectToIsdsClient()
{
    connect(iIsdsClient, SIGNAL(channelItemsChanged(QList<IRQChannelItem *> *)),
            iChannelModel, SLOT(updateData(QList<IRQChannelItem *> *)));
    
    connect(iIsdsClient, SIGNAL(operationException(IRQError)),
            this, SLOT(operationException(IRQError)));
}

void IRStationsView::disconnectIsdsClient()
{
    disconnect(iIsdsClient, SIGNAL(channelItemsChanged(QList<IRQChannelItem *> *)),
               iChannelModel, SLOT(updateData(QList<IRQChannelItem *> *)));
    
    disconnect(iIsdsClient, SIGNAL(operationException(IRQError)),
               this, SLOT(operationException(IRQError)));
}

void IRStationsView::createWaitDialog(QString aStr)
{
    if (!iWaitDialog)
    {
        iWaitDialog = new HbMessageBox(aStr, HbMessageBox::MessageTypeInformation);
        //iWaitDialog->setTimeout(HbPopupBase::NoTimeout); 
        iWaitDialog->setTimeout(HbPopup::NoTimeout); // JM: changed in w47 Orbit
        iWaitDialog->setModal(true);
        //iWaitDialog->setDismissPolicy(HbPopupBase::NoDismiss); 
        iWaitDialog->setDismissPolicy(HbPopup::NoDismiss); // JM: changed in w47 Orbit
        HbAction *cancelAction = new HbAction(hbTrId("txt_common_button_cancel"), iWaitDialog);
        iWaitDialog->setPrimaryAction(cancelAction);
        connect(cancelAction, SIGNAL(triggered()), this, SLOT(cancelRequest()));
    }

    iWaitDialog->exec();
}

void IRStationsView::convertAnother()
{
    iConvertTimer->stop();
    int leftCount = iIconIndexArray.count();
    
    if(0 != leftCount)
    {
        startConvert(iIconIndexArray[0]);   
    }
}

void IRStationsView::connectTimeOut()
{    
    iConnectTimer->stop();
    cancelRequest();   
    popupNote(hbTrId("txt_irad_info_connecting_timout"), HbMessageBox::MessageTypeWarning);
}