hswidgetplugin/fmradiohswidgetplugin/src/fmradiohswidget.cpp
changeset 32 189d20c34778
parent 28 075425b8d9a4
child 33 11b6825f0862
equal deleted inserted replaced
28:075425b8d9a4 32:189d20c34778
     1 /*
       
     2 * Copyright (c) 2010 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:  FM Radio home screen widget
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <HbPushButton>
       
    20 #include <HbLabel>
       
    21 #include <HbDocumentLoader>
       
    22 #include <HbFrameDrawer>
       
    23 #include <HbFrameItem>
       
    24 #include <HbIcon>
       
    25 #include <HbIconAnimationManager>
       
    26 #include <HbIconAnimationDefinition>
       
    27 #include <HbColorScheme>
       
    28 #include <QGraphicsLinearLayout>
       
    29 #include <QGraphicsItem>
       
    30 #include <QDesktopServices>
       
    31 #include <QTimer>
       
    32 
       
    33 // User includes
       
    34 #include "fmradiohswidget.h"
       
    35 #include "fmradiohswidgetprofilereader.h"
       
    36 #include "fmradiohswidgetradioserviceclient.h"
       
    37 #include "radioservicedef.h"
       
    38 #include "radio_global.h"
       
    39 #include "radiologger.h"
       
    40 
       
    41 /*!
       
    42     \ingroup group_fmradiohs_widget
       
    43     \class FmRadioHsWidget
       
    44     \brief Example implementation for home screen widget.
       
    45 
       
    46     FmRadioHsWidget implements needed functions for the FM Radio home screen
       
    47     widget.
       
    48 */
       
    49 
       
    50 // ======== MEMBER FUNCTIONS ========
       
    51 
       
    52 /*!
       
    53     Constructs a widget which is a child of \a parent, with widget flags set to \a flags.
       
    54     
       
    55     Constructor should be empty and all the actual construction should be
       
    56     done in onInitialize().
       
    57 */
       
    58 FmRadioHsWidget::FmRadioHsWidget(QGraphicsItem* parent, Qt::WindowFlags flags)
       
    59     : HbWidget(parent, flags),
       
    60       mTunerBackgroundPushButton(NULL),
       
    61       mPowerToggleButton(NULL),
       
    62       mPreviousPushButton(NULL),
       
    63       mNextPushButton(NULL),
       
    64       mInformationFirstRowLabel(NULL),
       
    65       mInformationSecondRowLabel(NULL),
       
    66       mFmRadioState(Undefined),
       
    67       mFavoriteStations(false),
       
    68       mRadioInformation(QHash<QString, QString>()),
       
    69       mProfileMonitor(NULL),
       
    70       mRadioServiceClient(NULL),
       
    71       mRadioStartingCancelTimer(NULL)
       
    72 {
       
    73     LOG_METHOD_ENTER;
       
    74 }
       
    75 
       
    76 /*!
       
    77     Destructor
       
    78 */
       
    79 FmRadioHsWidget::~FmRadioHsWidget()
       
    80 {
       
    81     LOG_METHOD;
       
    82 }
       
    83 
       
    84 /*!
       
    85     Getter for /r mRootPath property.
       
    86 */
       
    87 QString FmRadioHsWidget::rootPath()const
       
    88 {
       
    89     LOG_METHOD_ENTER;
       
    90     return mRootPath;
       
    91 }
       
    92 
       
    93 /*!
       
    94     Sets the mRoothPath propertry to /a roothPath.
       
    95 */
       
    96 void FmRadioHsWidget::setRootPath(const QString &rootPath)
       
    97 {
       
    98     LOG_METHOD_ENTER;
       
    99     mRootPath = rootPath;
       
   100 }
       
   101 
       
   102 /*!
       
   103     Called when widget is initialized. Constructs objects and connects them.
       
   104 */
       
   105 void FmRadioHsWidget::onInitialize()
       
   106 {
       
   107     LOG_METHOD_ENTER;
       
   108     mProfileMonitor = new FmRadioHsWidgetProfileReader(this);
       
   109     mRadioServiceClient = new FmRadioHsWidgetRadioServiceClient(this);
       
   110     mRadioStartingCancelTimer = new QTimer(this);
       
   111     
       
   112     connect(mRadioServiceClient, SIGNAL(radioInformationChanged(int, QVariant)), this,
       
   113         SLOT(handleRadioInformationChange(int, QVariant)));
       
   114     connect(mRadioServiceClient, SIGNAL(radioStateChanged(QVariant)), this,
       
   115         SLOT(handleRadioStateChange(QVariant)));
       
   116     connect(mProfileMonitor, SIGNAL(radioRunning(QVariant)), this,
       
   117         SLOT(handleRadioStateChange(QVariant)));
       
   118 
       
   119     load(KDocml);
       
   120     
       
   121     mProfileMonitor->startMonitoringRadioRunningStatus();
       
   122 }
       
   123 
       
   124 /*!
       
   125     Called when widget is shown in the home screen
       
   126 */
       
   127 void FmRadioHsWidget::onShow()
       
   128 {
       
   129     LOG_METHOD_ENTER;
       
   130 }
       
   131 
       
   132 /*!
       
   133     Called when widget is hidden from the home screen
       
   134 */
       
   135 void FmRadioHsWidget::onHide()
       
   136 {
       
   137     LOG_METHOD_ENTER;
       
   138 }
       
   139 
       
   140 /*!
       
   141     Loads docml files.
       
   142 */
       
   143 void FmRadioHsWidget::load(const QString &docml)
       
   144 {
       
   145     LOG_METHOD_ENTER;
       
   146 
       
   147     HbDocumentLoader *documentLoader = new HbDocumentLoader();
       
   148     documentLoader->reset();
       
   149     bool loaded = false;
       
   150     documentLoader->load(docml, &loaded);
       
   151 
       
   152     if (loaded) {
       
   153         // Find mainLayout
       
   154         HbWidget *mainLayout = qobject_cast<HbWidget*> (documentLoader->findWidget(
       
   155             KDocmlObjectNameMainLayout));
       
   156         // For drawing frame backgrounds
       
   157         HbFrameItem *frameItem = NULL;
       
   158 
       
   159         if (mainLayout) {
       
   160             QGraphicsLinearLayout *mWidgetLayout = new QGraphicsLinearLayout(Qt::Vertical, this);
       
   161             
       
   162             // Temporarily use graphics from resources. Change to the system
       
   163             // graphics when they are available.
       
   164             HbFrameDrawer *drawer = new HbFrameDrawer(
       
   165                 ":/ui/resource/qtg_graf_hsradio_bg.png",
       
   166                 HbFrameDrawer::OnePiece);
       
   167             //HbFrameDrawer *drawer = new HbFrameDrawer("qtg_fr_hswidget_normal",
       
   168             //    HbFrameDrawer::NinePieces);
       
   169             frameItem = new HbFrameItem(drawer, mainLayout);
       
   170             frameItem->setPreferredSize(mainLayout->preferredSize());
       
   171 
       
   172             mWidgetLayout->addItem(mainLayout);
       
   173             setLayout(mWidgetLayout);
       
   174         }
       
   175         
       
   176         // Find stacked layout for tuner area.
       
   177         HbWidget *tunerStackedLayout = qobject_cast<HbWidget*> (documentLoader->findWidget(
       
   178             KDocmlObjectNameTunerStackedLayout));
       
   179         if (tunerStackedLayout) {
       
   180 
       
   181             // Find stacked layout for information area.
       
   182             HbWidget *tunerInformationStackedLayout = qobject_cast<HbWidget*> (documentLoader->findWidget(
       
   183                 KDocmlObjectNameTunerInformationStackedLayout));
       
   184             if (tunerInformationStackedLayout) {
       
   185 
       
   186                 // MarqueeItem tests.
       
   187                     /*
       
   188                     QGraphicsLinearLayout *layout = new QGraphicsLinearLayout(Qt::Vertical, mInformationAreaOneRowLayout);
       
   189                     mInformationLonelyRowMarquee = new HbMarqueeItem();
       
   190                     mInformationLonelyRowMarquee->setObjectName("marquee3");
       
   191                     HbStyle::setItemName(mInformationLonelyRowMarquee, "marquee3");
       
   192                     mInformationLonelyRowMarquee->setText(
       
   193                         "Long text");
       
   194                     mInformationLonelyRowMarquee->setLoopCount(-1);
       
   195                     mInformationLonelyRowMarquee->startAnimation();
       
   196                     HbFontSpec fs(HbFontSpec::Secondary);
       
   197                     mInformationLonelyRowMarquee->setFontSpec(fs);
       
   198                     mInformationLonelyRowMarquee->setTextColor(HbColorScheme::color("qtc_hs_list_item_title"));
       
   199                     mInformationLonelyRowMarquee->setPreferredSize(layout->preferredSize());
       
   200                     layout->addItem(mInformationLonelyRowMarquee);
       
   201                     */
       
   202                 /*
       
   203                 }
       
   204                 */
       
   205 
       
   206                 // Find lonely label
       
   207                 mInformationLonelyRowLabel = qobject_cast<HbLabel *> (documentLoader->findWidget(
       
   208                     KDocmlObjectNameLonelyRowLabel));
       
   209                 if (mInformationLonelyRowLabel) {
       
   210                     QColor color = HbColorScheme::color("qtc_radio_tuner_normal");
       
   211                     if (color.isValid()) {
       
   212                         mInformationLonelyRowLabel->setTextColor(color);
       
   213                     }
       
   214                 }
       
   215 
       
   216                 // Find layout for two rows
       
   217                 mInformationAreaTwoRowsLayout = qobject_cast<QGraphicsWidget *> (
       
   218                     documentLoader->findObject(KDocmlObjectNameTwoRowsLayout));
       
   219                 if (mInformationAreaTwoRowsLayout) {
       
   220                     // Find first row
       
   221                     mInformationFirstRowLabel = qobject_cast<HbLabel *> (documentLoader->findWidget(
       
   222                         KDocmlObjectNameFirstRowLabel));
       
   223                     if (mInformationFirstRowLabel) {
       
   224                         QColor color = HbColorScheme::color("qtc_radio_tuner_normal");
       
   225                         if (color.isValid()) {
       
   226                             mInformationFirstRowLabel->setTextColor(color);
       
   227                         }
       
   228                     }
       
   229 
       
   230                     // Find second row
       
   231                     mInformationSecondRowLabel = qobject_cast<HbLabel *> (documentLoader->findWidget(
       
   232                         KDocmlObjectNameSecondRowLabel));
       
   233                     if (mInformationSecondRowLabel) {
       
   234                         QColor color = HbColorScheme::color("qtc_radio_tuner_normal");
       
   235                         if (color.isValid()) {
       
   236                             mInformationSecondRowLabel->setTextColor(color);
       
   237                         }
       
   238                     }
       
   239 
       
   240                 }
       
   241 
       
   242 
       
   243                 mAnimationIcon = qobject_cast<HbLabel *> (documentLoader->findWidget(
       
   244                     KDocmlObjectNameAnimationIcon));
       
   245                 if (mAnimationIcon) {
       
   246                     // Use animation manager to define the frame-by-frame animation.
       
   247                     HbIconAnimationManager *animationManager = HbIconAnimationManager::global();
       
   248 
       
   249                     // Create animation definition.
       
   250                     HbIconAnimationDefinition animationDefinition;
       
   251                     QList<HbIconAnimationDefinition::AnimationFrame> animationFrameList;
       
   252 
       
   253                     // This should be probably done by loading axml instead.
       
   254                     HbIconAnimationDefinition::AnimationFrame animationFrame;
       
   255                     QString animationFrameIconName;
       
   256                     QString animationFrameIconNamePrefix = "qtg_anim_loading_";
       
   257                     for (int i = 1; i < 11; i++) {
       
   258                         animationFrame.duration = 100;
       
   259                         animationFrameIconName.clear();
       
   260                         animationFrameIconName.append(animationFrameIconNamePrefix);
       
   261                         animationFrameIconName.append(animationFrameIconName.number(i));
       
   262                         animationFrame.iconName = animationFrameIconName;
       
   263                         animationFrameList.append(animationFrame);
       
   264                     }
       
   265                     animationDefinition.setPlayMode(HbIconAnimationDefinition::Loop);
       
   266                     animationDefinition.setFrameList(animationFrameList);
       
   267                     animationManager->addDefinition("animation", animationDefinition);
       
   268 
       
   269                     // Construct an icon using the animation definition.
       
   270                     HbIcon icon("animation");
       
   271 
       
   272                     mAnimationIcon->setIcon(icon);
       
   273                 }
       
   274 
       
   275             }
       
   276 
       
   277             // Find push button for tuner area.
       
   278             mTunerBackgroundPushButton = qobject_cast<HbPushButton*> (documentLoader->findWidget(
       
   279                 KDocmlObjectNameTunerBackgroundPushButton));
       
   280             if (mTunerBackgroundPushButton) {
       
   281                 // Test different states.
       
   282                 //bool p = mTunerBackgroundPushButton->setProperty("state", "normal");
       
   283                 // Try css for controlling the appearance.
       
   284                 //bool b = QFile::exists(KCss);
       
   285                 //bool cssLoaded = HbStyleLoader::registerFilePath(KCss);
       
   286                 //HbStyle::setItemName(mTunerBackgroundPushButton, KDocmlObjectNameTunerBackgroundPushButton);
       
   287                 // Use the frame background.
       
   288                 HbFrameDrawer *tunerBackgroundButtonFrameDrawer = new HbFrameDrawer(
       
   289                     "qtg_fr_tuner", HbFrameDrawer::ThreePiecesHorizontal);
       
   290                 tunerBackgroundButtonFrameDrawer->setFillWholeRect(true);
       
   291                 mTunerBackgroundPushButton->setFrameBackground(tunerBackgroundButtonFrameDrawer);
       
   292                 
       
   293                 // Connect the button's clicked signal. 
       
   294                 connect(mTunerBackgroundPushButton, SIGNAL(clicked()), this, SLOT(radioToForeground()));
       
   295             }
       
   296 
       
   297         }
       
   298 
       
   299         // Find layout for control buttons.
       
   300         HbWidget *controlButtonsLayout = qobject_cast<HbWidget*> (documentLoader->findWidget(
       
   301             KDocmlObjectNameContolButtonsLayout));
       
   302         if (controlButtonsLayout) {
       
   303             if (frameItem) {
       
   304                 // Stack widget's background behind it.
       
   305                 frameItem->stackBefore(controlButtonsLayout);
       
   306             }
       
   307             
       
   308             // Find power button.
       
   309             mPowerToggleButton = qobject_cast<HbPushButton *> (documentLoader->findWidget(
       
   310                 KDocmlObjectNameowerToggleButton));
       
   311             if (mPowerToggleButton) {
       
   312                 // If power button is lathced type, use this.
       
   313                 //mPowerToggleButton->setCheckable(true);
       
   314                 changeControlButtonFrameBackground(false, Left, mPowerToggleButton);
       
   315                 
       
   316                 // Use the graphics from resources until release contains proper graphics. 
       
   317                 mPowerToggleButton->setIcon(HbIcon(":/ui/resource/mono_power.png"));
       
   318                 // Connect the button's clicked signal.
       
   319                 connect(mPowerToggleButton, SIGNAL(clicked()), this, SLOT(radioToBackground()));
       
   320             }
       
   321             
       
   322             // Find previous button.
       
   323             mPreviousPushButton = qobject_cast<HbPushButton *> (documentLoader->findWidget(
       
   324                 KDocmlObjectNamePreviousPushButton));
       
   325             if (mPreviousPushButton) {
       
   326                 changeControlButtonFrameBackground(false, Center, mPreviousPushButton);
       
   327                 // Connect the button's clicked signal.
       
   328                 connect(mPreviousPushButton, SIGNAL(clicked()), this, SLOT(previousChannel()));
       
   329             }
       
   330 
       
   331             // Find next button.
       
   332             mNextPushButton = qobject_cast<HbPushButton *> (documentLoader->findWidget(
       
   333                 KDocmlObjectNameNextPushButton));
       
   334             if (mNextPushButton) {
       
   335                 changeControlButtonFrameBackground(false, Right, mNextPushButton);
       
   336                 // Connect the button's clicked signal.
       
   337                 connect(mNextPushButton, SIGNAL(clicked()), this, SLOT(nextChannel()));
       
   338             }
       
   339         }
       
   340 
       
   341     }
       
   342     // Loader is not needed anymore so it is deleted.
       
   343     delete documentLoader;
       
   344 }
       
   345 
       
   346 /*!
       
   347  Slot for closing FM Radio application from power button.
       
   348  */
       
   349 void FmRadioHsWidget::closeRadio()
       
   350 {
       
   351     LOG_SLOT_CALLER;
       
   352     mRadioServiceClient->doCloseFmRadio();
       
   353 }
       
   354 
       
   355 /*!
       
   356  Slot for previous button clicked.
       
   357  */
       
   358 void FmRadioHsWidget::previousChannel()
       
   359 {
       
   360     LOG_SLOT_CALLER;
       
   361     clearRadioInformation();
       
   362     mRadioServiceClient->doChangeFmRadioStation(FmRadioHsWidgetRadioServiceClient::PreviousFavouriteStation);
       
   363 }
       
   364 
       
   365 /*!
       
   366  Slot for next button clicked.
       
   367  */
       
   368 void FmRadioHsWidget::nextChannel()
       
   369 {
       
   370     LOG_SLOT_CALLER;
       
   371     clearRadioInformation();
       
   372     mRadioServiceClient->doChangeFmRadioStation(FmRadioHsWidgetRadioServiceClient::NextFavouriteStation);
       
   373 }
       
   374 
       
   375 /*!
       
   376  Slot for bringing the radio application to foreground.
       
   377  */
       
   378 void FmRadioHsWidget::radioToForeground()
       
   379 {
       
   380     LOG_SLOT_CALLER;
       
   381     // If radio is not running start it to foreground by monitor request.
       
   382     if (mFmRadioState == NotRunning) {
       
   383         handleRadioStateChange(QVariant(Starting));
       
   384         //mRadioServiceClient->doPowerOnFmRadio(FmRadioHsWidgetRadioServiceClient::ToForeground);
       
   385         mRadioServiceClient->startMonitoring(FmRadioHsWidgetRadioServiceClient::ToForeground);
       
   386     }
       
   387     else {
       
   388         if (mFmRadioState == Closing) {
       
   389             // Radio is closing but user wants to power it up again.
       
   390             mRadioServiceClient->doPowerOnFmRadio();
       
   391             mRadioServiceClient->stopMonitoring();
       
   392             mRadioServiceClient->startMonitoring(FmRadioHsWidgetRadioServiceClient::ToBackground);
       
   393             handleRadioStateChange(QVariant(Running));
       
   394         }
       
   395         // If radio is running, bring it to the foreground.
       
   396         mRadioServiceClient->doChangeFmRadioVisibility(
       
   397             FmRadioHsWidgetRadioServiceClient::ToForeground);
       
   398     }
       
   399 }
       
   400 
       
   401 /*!
       
   402  Slot for putting the radio application to the background.
       
   403  */
       
   404 void FmRadioHsWidget::radioToBackground()
       
   405 {
       
   406     LOG_SLOT_CALLER;
       
   407     // If radio is not running start it to background by monitor request.
       
   408     if (mFmRadioState == NotRunning) {
       
   409         handleRadioStateChange(QVariant(Starting));
       
   410         mRadioServiceClient->startMonitoring(FmRadioHsWidgetRadioServiceClient::ToBackground);
       
   411     }
       
   412     else if (mFmRadioState == Starting) {
       
   413         // Do nothing if radio is starting.
       
   414     }
       
   415     else if (mFmRadioState == Closing) {
       
   416         // Radio is closing but user wants to power it up again.
       
   417         mRadioServiceClient->doPowerOnFmRadio();
       
   418         mRadioServiceClient->stopMonitoring();
       
   419         mRadioServiceClient->startMonitoring(FmRadioHsWidgetRadioServiceClient::ToBackground);
       
   420         handleRadioStateChange(QVariant(Running));
       
   421     }
       
   422     else {
       
   423         // If radio is running, put it to the background.
       
   424         // This is little bit useless because the radio is in background if
       
   425         // user is able to click the widget.
       
   426         mRadioServiceClient->doChangeFmRadioVisibility(
       
   427             FmRadioHsWidgetRadioServiceClient::ToBackground);
       
   428     }
       
   429 }
       
   430 
       
   431 /*!
       
   432  Handles changes in FM Radio information.
       
   433 
       
   434  /param type Type of changed information.
       
   435  /param value Information content.
       
   436  */
       
   437 void FmRadioHsWidget::handleRadioInformationChange(const int notificationId,
       
   438     const QVariant &value)
       
   439 {
       
   440     LOG_METHOD;
       
   441     LEVEL2(LOG_SLOT_CALLER);
       
   442     if (!value.isValid()) {
       
   443         // Value is not valid so return.
       
   444         return;
       
   445     }
       
   446     switch ( notificationId ) {
       
   447 
       
   448         case RadioServiceNotification::FavoriteCount:
       
   449             LEVEL2(LOG("FavoriteCount"));
       
   450             if (value.canConvert(QVariant::Int)) {
       
   451                 int favoriteCount = value.toInt();
       
   452                 // If there are favorite stations, enable the next/previous
       
   453                 // buttons.
       
   454                 mFavoriteStations = favoriteCount > 0 ? true : false;
       
   455                 LEVEL2(LOG_FORMAT("favoriteCount: %d, mFavoriteStations: %d",
       
   456                     favoriteCount, mFavoriteStations));
       
   457             changeStationButtonsEnabledState(mFavoriteStations);
       
   458             }
       
   459             break;
       
   460             
       
   461         case RadioServiceNotification::CurrentIsFavorite:
       
   462             LEVEL2(LOG("CurrentIsFavorite"));
       
   463             if (value.canConvert(QVariant::Bool)) {
       
   464                 bool currentIsFavorite = value.toBool();
       
   465                 LEVEL2(LOG_FORMAT("currentIsFavorite: %d", currentIsFavorite));
       
   466                 // If favorite count is 1 and current station is favorite
       
   467                 // disable next/prev buttons.
       
   468                 if (currentIsFavorite) {
       
   469                     changeStationButtonsEnabledState(false);
       
   470                 } else {
       
   471                     // Else eneble them.
       
   472                     changeStationButtonsEnabledState(true);
       
   473                 }
       
   474             }
       
   475             break;
       
   476 
       
   477         case RadioServiceNotification::RadioStatus:
       
   478             LEVEL2(LOG("RadioStatus"));
       
   479             if (value.canConvert(QVariant::Int)) {
       
   480                 int status = value.toInt();
       
   481                 switch (status) {
       
   482                 case RadioStatus::Playing:
       
   483                     LEVEL2(LOG("Playing"));
       
   484                     handleRadioStateChange(QVariant(ControllingAudio));
       
   485                     break;
       
   486                 case RadioStatus::Muted:
       
   487                     LEVEL2(LOG("Muted"));
       
   488                     handleRadioStateChange(QVariant(NotControllingAudio));
       
   489                     break;
       
   490                 case RadioStatus::Seeking:
       
   491                     LEVEL2(LOG("Seeking"));
       
   492                     handleRadioStateChange(QVariant(Seeking));
       
   493                     break;
       
   494                 case RadioStatus::NoAntenna:
       
   495                     LEVEL2(LOG("NoAntenna"));
       
   496                     handleRadioStateChange(QVariant(AntennaNotConnected));
       
   497                     break;                    
       
   498                 case RadioStatus::PoweringOff:
       
   499                     LEVEL2(LOG("PoweringOff"));
       
   500                     handleRadioStateChange(QVariant(Closing));
       
   501                     break;
       
   502                 default:
       
   503                     LEVEL2(LOG("default"));
       
   504                     break;
       
   505                 }
       
   506             }
       
   507             break;
       
   508 
       
   509         case RadioServiceNotification::Frequency:
       
   510             LEVEL2(LOG("Frequency"));
       
   511             if (value.canConvert(QVariant::UInt)) {
       
   512                 const uint frequency = value.toUInt();
       
   513                 QString frequencyString;
       
   514                 // Format the frequency to human readable text.
       
   515                 frequencyString.sprintf("%.1f", qreal(frequency) / FREQUENCY_MULTIPLIER);
       
   516                 LEVEL2(LOG_FORMAT("frequency: %s", GETSTRING(frequencyString)));
       
   517                 // TODO: Remove comment when localisation is working on device.
       
   518                 //frequencyString = hbTrId("txt_rad_list_l1_mhz").arg(freqString);
       
   519                 bool frequencyCleared = false;
       
   520                 // If widget has some frequency information and new frequency
       
   521                 // differs from that
       
   522                 if (mRadioInformation.contains(KRadioInformationFrequency)
       
   523                     && mRadioInformation[KRadioInformationFrequency].compare(frequencyString) != 0) {
       
   524                     // Clear all infromation from widget because station has changed.
       
   525                     clearRadioInformation();
       
   526                     frequencyCleared = true;
       
   527                 }
       
   528                 // If widget do not have any frquency information, update it.
       
   529                 bool frequencyUpdated = updateRadioInformation(KRadioInformationFrequency, frequencyString);
       
   530                 if (frequencyCleared || frequencyUpdated) {
       
   531                     // Information changed, update the UI.
       
   532                     radioInformationChanged();
       
   533                 }
       
   534             }
       
   535         break;
       
   536 
       
   537         case RadioServiceNotification::Name:
       
   538             LEVEL2(LOG("Name"));
       
   539             if (value.canConvert(QVariant::String)) {
       
   540                 if (updateRadioInformation(KRadioInformationStationName, value.toString())) {
       
   541                     LEVEL2(LOG_FORMAT("name: %s", GETSTRING(value.toString())));
       
   542                     radioInformationChanged();
       
   543                 }
       
   544             }
       
   545         break;
       
   546 
       
   547         case RadioServiceNotification::Genre:
       
   548             LEVEL2(LOG("Genre"));
       
   549             if (value.canConvert(QVariant::String)) {
       
   550                 if (updateRadioInformation(KRadioInformationPty, value.toString())) {
       
   551                     LEVEL2(LOG_FORMAT("genre: %s", GETSTRING(value.toString())));
       
   552                     radioInformationChanged();
       
   553                 }
       
   554             }
       
   555         break;
       
   556 
       
   557         case RadioServiceNotification::RadioText:
       
   558             LEVEL2(LOG("RadioText"));
       
   559             if (value.canConvert(QVariant::String)) {
       
   560                 if (updateRadioInformation(KRadioInformationRt, value.toString())) {
       
   561                     LEVEL2(LOG_FORMAT("radio text: %s", GETSTRING(value.toString())));
       
   562                     radioInformationChanged();
       
   563                 }
       
   564             }
       
   565         break;
       
   566         
       
   567         case RadioServiceNotification::DynamicPS:
       
   568             LOG("DynamicPS");
       
   569             if (value.canConvert(QVariant::String)) {
       
   570                 if (updateRadioInformation(KRadioInformationDynamicPsName, value.toString())) {
       
   571                     LEVEL2(LOG_FORMAT("dynamicPS: %s", GETSTRING(value.toString())));
       
   572                     radioInformationChanged();
       
   573                 }
       
   574             }
       
   575         break;
       
   576 
       
   577     default:
       
   578         LOG("default");
       
   579         break;
       
   580     }
       
   581 }
       
   582 
       
   583 /*!
       
   584  Check if the the radio information is changed. If it is changed update it.
       
   585 
       
   586  /param informationType Type of the information.
       
   587  /param information  Information text.
       
   588 
       
   589  /return bool If information is updated, return true. Return false otherwise.
       
   590  */
       
   591 bool FmRadioHsWidget::updateRadioInformation(const QString &informationType,
       
   592     const QString &information)
       
   593 {
       
   594     LOG_METHOD_RET("%d");
       
   595     // If hash contains this type of information.
       
   596     if (mRadioInformation.contains(informationType)) {
       
   597         // If new information is empty.
       
   598         if (information.isEmpty()) {
       
   599             // Remove old information from the hash.
       
   600             LEVEL2(LOG_FORMAT("informationType: %s removed", GETSTRING(informationType)));
       
   601             mRadioInformation.remove(informationType);
       
   602             // Return true to indicate the change.
       
   603             return true;
       
   604         }
       
   605         // If new information differs from the old one.
       
   606         if (mRadioInformation[informationType].compare(information) != 0) {
       
   607             // Update the information.
       
   608             LEVEL2(LOG_FORMAT("informationType: %s = %s", GETSTRING(informationType), GETSTRING(information)));
       
   609             mRadioInformation[informationType] = information;
       
   610             // And return true to indicate the change.
       
   611             return true;
       
   612         }
       
   613     } else { // Hash do not contain this type of information.
       
   614         // If new information is not empty.
       
   615         if (!information.isEmpty()) {
       
   616             // Add it to the hash.
       
   617             LEVEL2(LOG_FORMAT("informationType: %s = %s", GETSTRING(informationType), GETSTRING(information)));
       
   618             mRadioInformation[informationType] = information;
       
   619             // Return true to indicate the change.
       
   620             return true;
       
   621         }
       
   622     }
       
   623     // Return false to indicate that nothing changed.
       
   624     return false;
       
   625 }
       
   626 
       
   627 /*!
       
   628  Formatting radio information texts after a change.
       
   629  */
       
   630 void FmRadioHsWidget::radioInformationChanged()
       
   631 {
       
   632     LOG_METHOD_ENTER;
       
   633     // Clear the rows.
       
   634     mRadioInformationFirstRow.clear();
       
   635     mRadioInformationSecondRow.clear();
       
   636 
       
   637     // First row contains station name.
       
   638     if (mRadioInformation.contains(KRadioInformationStationName)) {
       
   639         mRadioInformationFirstRow.append(mRadioInformation.value(KRadioInformationStationName));
       
   640     } else if (mRadioInformation.contains(KRadioInformationFrequency)) {
       
   641         // Or frequency.
       
   642         mRadioInformationFirstRow.append(mRadioInformation.value(KRadioInformationFrequency));
       
   643     }
       
   644     LEVEL2(LOG_FORMAT("mRadioInformationFirstRow: %s", GETSTRING(mRadioInformationFirstRow)));
       
   645     
       
   646     // Second row of information contains radio text.
       
   647     if (mRadioInformation.contains(KRadioInformationRt)) {
       
   648         mRadioInformationSecondRow.append(mRadioInformation.value(KRadioInformationRt));
       
   649     } else if (mRadioInformation.contains(KRadioInformationDynamicPsName)) {
       
   650         // Or Dynamic PS name.
       
   651         mRadioInformationSecondRow.append(mRadioInformation.value(
       
   652             KRadioInformationDynamicPsName));
       
   653     } else if (mRadioInformation.contains(KRadioInformationPty)) {
       
   654         // Or PTY.
       
   655         mRadioInformationSecondRow.append(mRadioInformation.value(KRadioInformationPty));
       
   656     }
       
   657     LEVEL2(LOG_FORMAT("mRadioInformationSecondRow: %s", GETSTRING(mRadioInformationSecondRow)));
       
   658     
       
   659     // If second row is empty.
       
   660     if (mRadioInformationSecondRow.isEmpty()) {
       
   661         // Show only the lonely row.
       
   662         mInformationLonelyRowLabel->setPlainText(mRadioInformationFirstRow);
       
   663         changeInformationAreaLayout(OneRow);
       
   664     }
       
   665     else {
       
   666         // Else display both rows.
       
   667         mInformationFirstRowLabel->setPlainText(mRadioInformationFirstRow);
       
   668         mInformationSecondRowLabel->setPlainText(mRadioInformationSecondRow);
       
   669         changeInformationAreaLayout(TwoRows);
       
   670     }
       
   671 }
       
   672 
       
   673 /*!
       
   674  Clears the radio station information. For example, when the station is
       
   675  changed, old information should be cleared.
       
   676  */
       
   677 void FmRadioHsWidget::clearRadioInformation()
       
   678 {
       
   679     LOG_METHOD_ENTER;
       
   680     if (!mRadioInformation.isEmpty()) {
       
   681         LEVEL2(LOG("clear radioInformation"));
       
   682         mRadioInformation.clear();
       
   683     }
       
   684 }
       
   685 
       
   686 /*!
       
   687  Handles changes in FM Radio state.
       
   688 
       
   689  /param value New state of the radio application.
       
   690  */
       
   691 void FmRadioHsWidget::handleRadioStateChange(const QVariant &value)
       
   692 {
       
   693     LOG_METHOD;
       
   694     int state;
       
   695     if (value.canConvert(QVariant::Int)) {
       
   696         state = value.toInt();
       
   697     } else {
       
   698         return;
       
   699     }
       
   700 
       
   701     if (state == mFmRadioState) {
       
   702         // State did not change, so return.
       
   703         return;
       
   704     }
       
   705 
       
   706     switch (state) {
       
   707     case Undefined:
       
   708         LEVEL2(LOG("Undefined"));
       
   709         // Something went wrong. Widget should not be in this state after onInitialize().
       
   710         mFmRadioState = Undefined;
       
   711         break;
       
   712     case NotRunning:
       
   713         LEVEL2(LOG("NotRunning"));
       
   714         mFmRadioState = NotRunning;
       
   715         mRadioServiceClient->stopMonitoring();
       
   716         changePowerButtonOn(false);
       
   717         mFavoriteStations = false;
       
   718         changeStationButtonsEnabledState(false);
       
   719         clearRadioInformation();
       
   720         mInformationFirstRowLabel->setPlainText("");
       
   721         mInformationSecondRowLabel->setPlainText("");
       
   722         mInformationLonelyRowLabel->setPlainText(hbTrId("txt_rad_list_fm_radio"));
       
   723         changeInformationAreaLayout(OneRow);
       
   724         break;
       
   725     case Starting:
       
   726         LEVEL2(LOG("Starting"));
       
   727         mFmRadioState = Starting;
       
   728         changePowerButtonOn(true);
       
   729         changeStationButtonsEnabledState(false);
       
   730         changeInformationAreaLayout(Animation);
       
   731         // This timer is workaround to recover from situation where radio is
       
   732         // started from widget but user answers no to the offline start dialog.
       
   733         // Stop timer if it is running.
       
   734         stopRadioStartingCancelTimer();
       
   735         // Set timer as single shot.
       
   736         mRadioStartingCancelTimer->setSingleShot(true);
       
   737         // Connect timeout.
       
   738         connect(mRadioStartingCancelTimer, SIGNAL(timeout()), this,
       
   739             SLOT(cancelRadioStartingState()));
       
   740         // Start to timeout after delay.
       
   741         mRadioStartingCancelTimer->start(KRadioStartingStateCancelDelay);
       
   742         break;
       
   743     case Running:
       
   744         LEVEL2(LOG("Running"));
       
   745         mFmRadioState = Running;
       
   746         // Stop timer if it is running because radio is now running.
       
   747         stopRadioStartingCancelTimer();
       
   748         mRadioServiceClient->startMonitoring(
       
   749             FmRadioHsWidgetRadioServiceClient::DoNotChange);
       
   750         changePowerButtonOn(true);
       
   751         changeStationButtonsEnabledState(mFavoriteStations);
       
   752         changeInformationAreaLayout(OneRow);
       
   753         break;
       
   754     case ControllingAudio:
       
   755         LEVEL2(LOG("ControllingAudio"));
       
   756         mFmRadioState = ControllingAudio;
       
   757         changeStationButtonsEnabledState(mFavoriteStations);
       
   758         radioInformationChanged();
       
   759         break;
       
   760     case NotControllingAudio:
       
   761         LEVEL2(LOG("NotControllingAudio"));
       
   762         mFmRadioState = NotControllingAudio;
       
   763         changeStationButtonsEnabledState(mFavoriteStations);
       
   764         radioInformationChanged();
       
   765         break;
       
   766     case Seeking:
       
   767         LEVEL2(LOG("Seeking"));
       
   768         mFmRadioState = Seeking;
       
   769         changeStationButtonsEnabledState(false);
       
   770         changeInformationAreaLayout(Animation);
       
   771         break;
       
   772     case AntennaNotConnected:
       
   773         LEVEL2(LOG("AntennaNotConnected"));
       
   774         mFmRadioState = AntennaNotConnected;
       
   775         changeStationButtonsEnabledState(false);
       
   776         mInformationFirstRowLabel->setPlainText("");
       
   777         mInformationSecondRowLabel->setPlainText("");
       
   778         mInformationLonelyRowLabel->setPlainText(hbTrId("txt_rad_info_connect_wired_headset"));
       
   779         changeInformationAreaLayout(OneRow);
       
   780         break;
       
   781     case Closing:
       
   782         LEVEL2(LOG("Closing"));
       
   783         mFmRadioState = Closing;
       
   784         changePowerButtonOn(false);
       
   785         changeStationButtonsEnabledState(false);
       
   786         clearRadioInformation();
       
   787         mInformationFirstRowLabel->setPlainText("");
       
   788         mInformationSecondRowLabel->setPlainText("");
       
   789         mInformationLonelyRowLabel->setPlainText(hbTrId("txt_rad_list_fm_radio"));
       
   790         changeInformationAreaLayout(OneRow);
       
   791         break;
       
   792     default:
       
   793         LOG("default");
       
   794         break;
       
   795     }
       
   796 }
       
   797 
       
   798 /*!
       
   799  Changes visible widgets of information area stacked layout.
       
   800 
       
   801  /param InformationAreaLayout The layout to switch visible.
       
   802  */
       
   803 void FmRadioHsWidget::changeInformationAreaLayout(const InformationAreaLayout layout)
       
   804 {
       
   805     LOG_METHOD;
       
   806     switch (layout) {
       
   807     case OneRow:
       
   808         LEVEL2(LOG("OneRow"));
       
   809         mInformationLonelyRowLabel->show();
       
   810         mInformationAreaTwoRowsLayout->hide();
       
   811         mAnimationIcon->hide();
       
   812         break;
       
   813     case TwoRows:
       
   814         LEVEL2(LOG("TwoRows"));
       
   815         mInformationLonelyRowLabel->hide();
       
   816         mInformationAreaTwoRowsLayout->show();
       
   817         mAnimationIcon->hide();
       
   818         break;
       
   819     case Animation:
       
   820         LEVEL2(LOG("Animation"));
       
   821         mInformationLonelyRowLabel->hide();
       
   822         mInformationAreaTwoRowsLayout->hide();
       
   823         mAnimationIcon->show();
       
   824         break;
       
   825     default:
       
   826         LOG("default");
       
   827         break;
       
   828     }
       
   829 }
       
   830 
       
   831 /*!
       
   832  Changes state of power button.
       
   833 
       
   834  */
       
   835 void FmRadioHsWidget::changePowerButtonOn(const bool isPowerOn)
       
   836 {
       
   837     LOG_METHOD;
       
   838     QString iconName;
       
   839     if (isPowerOn) {
       
   840         LEVEL2(LOG("Power on"));
       
   841         // Change icon to reflect power on state.
       
   842         iconName.append("qtg_mono_power");
       
   843         mPowerToggleButton->setIcon(HbIcon(":/ui/resource/mono_power.png"));
       
   844         mPowerToggleButton->setText("Off");
       
   845         // Connect clicked to closeRadio slot.
       
   846         disconnect(mPowerToggleButton, SIGNAL(clicked()), this,
       
   847             SLOT(radioToBackground()));
       
   848         connect(mPowerToggleButton, SIGNAL(clicked()), this,
       
   849             SLOT(closeRadio()));
       
   850     } else {
       
   851         LEVEL2(LOG("Power off"));
       
   852         // Change icon to reflect power off state.
       
   853         iconName.append("qtg_mono_power");
       
   854         mPowerToggleButton->setIcon(HbIcon(":/ui/resource/mono_power.png"));
       
   855         mPowerToggleButton->setText("On");
       
   856         // Connect clicked to radioToBackground slot.
       
   857         disconnect(mPowerToggleButton, SIGNAL(clicked()), this,
       
   858             SLOT(closeRadio()));
       
   859         connect(mPowerToggleButton, SIGNAL(clicked()), this,
       
   860             SLOT(radioToBackground()));
       
   861     }
       
   862     changeControlButtonFrameBackground(true, Left, mPowerToggleButton);
       
   863 }
       
   864 
       
   865 /*!
       
   866  Changes enabled state of station buttons.
       
   867 
       
   868  */
       
   869 void FmRadioHsWidget::changeStationButtonsEnabledState(const bool enabled)
       
   870 {
       
   871     LOG_METHOD_ENTER;
       
   872     changeControlButtonFrameBackground(enabled, Center, mPreviousPushButton);
       
   873     changeControlButtonFrameBackground(enabled, Right, mNextPushButton);
       
   874 }
       
   875 
       
   876 /*!
       
   877  Changes background of control button.
       
   878 
       
   879  /param enabled Is button enabled or disabled.
       
   880  /param position Position of the control button in button group.
       
   881  /param button The button to change the background.
       
   882  */
       
   883 void FmRadioHsWidget::changeControlButtonFrameBackground(const bool enabled,
       
   884     const ControlButtonPosition position, HbPushButton *button)
       
   885 {
       
   886     LOG_METHOD_ENTER;
       
   887     QString frameGraphicsName("qtg_fr_hsbutton_");
       
   888     if (enabled) {
       
   889         frameGraphicsName.append("normal");
       
   890     } else {
       
   891         frameGraphicsName.append("disabled");
       
   892     }
       
   893     LEVEL2(LOG_FORMAT("frameGraphicsName: %s", GETSTRING(frameGraphicsName)));
       
   894     HbFrameDrawer *frameDrawer = new HbFrameDrawer(frameGraphicsName,
       
   895         HbFrameDrawer::ThreePiecesHorizontal);
       
   896     switch (position) {
       
   897     case Left:
       
   898         LEVEL2(LOG("Left"));
       
   899         frameDrawer->setFileNameSuffixList(QStringList() << "_l" << "_c" << "_cr");
       
   900         break;
       
   901     case Center:
       
   902         LEVEL2(LOG("Center"));
       
   903         frameDrawer->setFileNameSuffixList(QStringList() << "_cl" << "_c" << "_cr");
       
   904         break;
       
   905     case Right:
       
   906         LEVEL2(LOG("Right"));
       
   907         frameDrawer->setFileNameSuffixList(QStringList() << "_cl" << "_c" << "_r");
       
   908         break;
       
   909     default:
       
   910         LOG("default");
       
   911         break;
       
   912     }
       
   913     button->setFrameBackground(frameDrawer);
       
   914     button->setEnabled(enabled);
       
   915 }
       
   916 
       
   917 /*!
       
   918  Radio did not start on time. Let's reset the widget's state.
       
   919 
       
   920  */
       
   921 void FmRadioHsWidget::cancelRadioStartingState()
       
   922 {
       
   923     LOG_SLOT_CALLER;
       
   924     handleRadioStateChange(QVariant(NotRunning));
       
   925 }
       
   926 
       
   927 /*!
       
   928  Stop the timer canceling radio starting state.
       
   929 
       
   930  */
       
   931 void FmRadioHsWidget::stopRadioStartingCancelTimer()
       
   932 {
       
   933     LOG_METHOD_ENTER;
       
   934     if (mRadioStartingCancelTimer->isActive()) {
       
   935          mRadioStartingCancelTimer->stop();
       
   936      }
       
   937 }