radioapp/radiouiengine/src/radiostationmodel_p.cpp
branchRCL_3
changeset 19 cce62ebc198e
equal deleted inserted replaced
18:1a6714c53019 19:cce62ebc198e
       
     1 /*
       
     2 * Copyright (c) 2009 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:
       
    15 *
       
    16 */
       
    17 
       
    18 // System includes
       
    19 #include <QTimer>
       
    20 
       
    21 // User includes
       
    22 #include "radiostationmodel.h"
       
    23 #include "radiostationmodel_p.h"
       
    24 #include "radiologger.h"
       
    25 #include "radiopresetstorage.h"
       
    26 #include "radioenginewrapper.h"
       
    27 #include "radiouiengine.h"
       
    28 #include "radiouiengine_p.h"
       
    29 #include "radiostation.h"
       
    30 #include "radiostation_p.h"
       
    31 #include "radiohistorymodel.h"
       
    32 
       
    33 // Constants
       
    34 /**
       
    35  * Timeout period for checking if station is sending dynamic PS in milliseconds
       
    36  */
       
    37 const int DYNAMIC_PS_CHECK_TIMEOUT = 10 * 1000;
       
    38 
       
    39 /*!
       
    40  *
       
    41  */
       
    42 RadioStationModelPrivate::RadioStationModelPrivate( RadioStationModel* model,
       
    43                                                     RadioUiEnginePrivate& uiEngine ) :
       
    44     q_ptr( model ),
       
    45     mUiEngine( uiEngine ),
       
    46     mCurrentStation( &mManualStation ),
       
    47     mDynamicPsTimer( new QTimer() )
       
    48 {
       
    49     mManualStation.setType( RadioStation::ManualStation );
       
    50     Radio::connect( mDynamicPsTimer.data(), SIGNAL(timeout()),
       
    51                     q_ptr,                  SLOT(dynamicPsCheckEnded()) );
       
    52     mDynamicPsTimer->setInterval( DYNAMIC_PS_CHECK_TIMEOUT );
       
    53     mDynamicPsTimer->setSingleShot( true );
       
    54 }
       
    55 
       
    56 /*!
       
    57  *
       
    58  */
       
    59 RadioStationModelPrivate::~RadioStationModelPrivate()
       
    60 {
       
    61     // Destructor needs to be defined. See explanation from RadioEngineWrapperPrivate destructor.
       
    62 }
       
    63 
       
    64 /*!
       
    65  * \reimp
       
    66  */
       
    67 uint RadioStationModelPrivate::currentFrequency() const
       
    68 {
       
    69     return mCurrentStation->frequency();
       
    70 }
       
    71 
       
    72 /*!
       
    73  * \reimp
       
    74  */
       
    75 int RadioStationModelPrivate::currentPresetIndex() const
       
    76 {
       
    77     return mCurrentStation->presetIndex();
       
    78 }
       
    79 
       
    80 /*!
       
    81  * Sets the currently tuned frequency. Meant to be set by the engine wrapper
       
    82  */
       
    83 void RadioStationModelPrivate::setCurrentStation( uint frequency )
       
    84 {
       
    85     LOG_METHOD;
       
    86     RadioStation* oldStation = mCurrentStation;
       
    87     if ( mStations.contains( frequency ) ) {
       
    88         // We have to be careful to check that key exists before using operator[]
       
    89         // with QMap since it will insert a default-constructed value if it doesn't exist yet.
       
    90         mCurrentStation = &mStations[ frequency ];
       
    91     } else {
       
    92         mManualStation.reset();
       
    93         mManualStation.setType( RadioStation::ManualStation );
       
    94         mManualStation.setFrequency( frequency );
       
    95         mCurrentStation = &mManualStation;
       
    96     }
       
    97 
       
    98     Q_Q( RadioStationModel );
       
    99     if ( oldStation && oldStation->isValid() ) {
       
   100         q->emitDataChanged( *oldStation );
       
   101         q->emitDataChanged( *mCurrentStation );
       
   102     }
       
   103 }
       
   104 
       
   105 /*!
       
   106  * \reimp
       
   107  * Sets the genre to the currently tuned station
       
   108  */
       
   109 void RadioStationModelPrivate::setCurrentGenre( uint frequency, int genre )
       
   110 {
       
   111     Q_Q( RadioStationModel );
       
   112     RadioStation station = q->findStation( frequency, FindCriteria::IncludeManualStation );
       
   113     if ( !station.isValid() ) {
       
   114         LOG( "Unable to find current station. Ignoring RDS" );
       
   115         return;
       
   116     }
       
   117     station.setGenre( genre );
       
   118     q->saveStation( station );
       
   119 }
       
   120 
       
   121 /*!
       
   122  * \reimp
       
   123  *
       
   124  */
       
   125 void RadioStationModelPrivate::tunedToFrequency( uint frequency, int reason )
       
   126 {
       
   127     if ( reason == TuneReason::Seek ) {
       
   128         addScannedFrequency( frequency );
       
   129     }
       
   130 
       
   131     setCurrentStation( frequency );
       
   132     startDynamicPsCheck();
       
   133 }
       
   134 
       
   135 /*!
       
   136  * \reimp
       
   137  * Checks if the given frequency exists in the list
       
   138  */
       
   139 bool RadioStationModelPrivate::containsFrequency( uint frequency )
       
   140 {
       
   141     return mStations.contains( frequency );
       
   142 }
       
   143 
       
   144 /*!
       
   145  * \reimp
       
   146  * Checks if the given preset index exists in the list
       
   147  */
       
   148 bool RadioStationModelPrivate::containsPresetIndex( int presetIndex )
       
   149 {
       
   150     Q_Q( RadioStationModel );
       
   151     return q->findPresetIndex( presetIndex ) != RadioStation::NotFound;
       
   152 }
       
   153 
       
   154 /*!
       
   155  * \reimp
       
   156  * Starts the dynamic PS check
       
   157  */
       
   158 void RadioStationModelPrivate::startDynamicPsCheck()
       
   159 {
       
   160     // Start the Dynamic PS check if the station has no name and ps type is not known
       
   161     // During the dynamic PS check the RadioStation's dynamicPs variable is used to store the
       
   162     // received PS name even though at this point it isn't known if it is dynamic or not.
       
   163     mDynamicPsTimer->stop();
       
   164     if ( mCurrentStation->psType() == RadioStation::Unknown ) {
       
   165         mCurrentStation->setDynamicPsText( "" );
       
   166         mDynamicPsTimer->start();
       
   167     }
       
   168 }
       
   169 
       
   170 /*!
       
   171  * \reimp
       
   172  *
       
   173  */
       
   174 void RadioStationModelPrivate::addScannedFrequency( uint frequency )
       
   175 {
       
   176     Q_Q( RadioStationModel );
       
   177     RadioStation station;
       
   178     if ( q->findFrequency( frequency, station ) ) {
       
   179         station.setType( RadioStation::LocalStation );
       
   180         q->saveStation( station );
       
   181     } else {
       
   182         station.setType( RadioStation::LocalStation );
       
   183         station.setFrequency( frequency );
       
   184         q->addStation( station );
       
   185     }
       
   186 }
       
   187 
       
   188 /*!
       
   189  * \reimp
       
   190  * Sets the PS name to the currently tuned station
       
   191  */
       
   192 void RadioStationModelPrivate::setCurrentPsName( uint frequency, const QString& name )
       
   193 {
       
   194     Q_Q( RadioStationModel );
       
   195     LOG_FORMAT( "void RadioStationModelPrivate::setCurrentPsName: %s", GETSTRING( name ) );
       
   196     RadioStation station = q->findStation( frequency, FindCriteria::IncludeManualStation );
       
   197     if ( !station.isValid() ) {
       
   198         LOG( "Unable to find current station. Ignoring RDS" );
       
   199         return;
       
   200     }
       
   201 
       
   202     if ( station.psType() == RadioStation::Static ) {
       
   203 
       
   204         if ( name.compare( station.name() ) != 0 && !station.isRenamed() ) {
       
   205             station.setName( name );
       
   206             q->saveStation( station );
       
   207         }
       
   208 
       
   209     } else {
       
   210 
       
   211         if ( mDynamicPsTimer->isActive() ) {    // Dynamic PS check is ongoing
       
   212             LOG( "Dynamic Ps check ongoing" );
       
   213 
       
   214             if ( !station.dynamicPsText().isEmpty() &&
       
   215                     name.compare( station.dynamicPsText(), Qt::CaseInsensitive ) != 0  ) {
       
   216                 LOG( "Dynamic Ps check - Second PS name arrived and is different. PS is dynamic" );
       
   217                 station.setPsType( RadioStation::Dynamic ); // Station is sending Dynamic PS
       
   218                 mDynamicPsTimer->stop();
       
   219 
       
   220                 // Cleanup the station name if region is not America
       
   221                 if ( !station.name().isEmpty()
       
   222                      && !station.isRenamed()
       
   223                      && mWrapper->region() != RadioRegion::America )
       
   224                 {
       
   225                     LOG( "Station name cleanup" );
       
   226                     station.setName( "" );
       
   227                 }
       
   228             }
       
   229 
       
   230             // Received PS name is published to the UI as dynamic PS while the check is ongoing
       
   231             // even though at this stage we don't know if it is dynamic or not.
       
   232 
       
   233             station.setDynamicPsText( name );
       
   234             q->saveStation( station );
       
   235 
       
   236         } else {
       
   237 
       
   238             if ( station.psType() == RadioStation::Dynamic ) {
       
   239                 LOG( "Station uses Dynamic Ps" );
       
   240             } else {
       
   241                 LOG( "Station PS type unknown" );
       
   242             }
       
   243 
       
   244             station.setDynamicPsText( name );
       
   245             q->saveStation( station );
       
   246         }
       
   247     }
       
   248 }
       
   249 
       
   250 /*!
       
   251  * \reimp
       
   252  * Sets the radio text to the currently tuned station
       
   253  */
       
   254 void RadioStationModelPrivate::setCurrentRadioText( uint frequency, const QString& radioText )
       
   255 {
       
   256     Q_Q( RadioStationModel );
       
   257     RadioStation station = q->findStation( frequency, FindCriteria::IncludeManualStation );
       
   258     if ( !station.isValid() ) {
       
   259         LOG( "Unable to find current station. Ignoring RDS" );
       
   260         return;
       
   261     }
       
   262     station.setRadioText( radioText );
       
   263     q->saveStation( station );
       
   264     mUiEngine.api().historyModel().clearRadioTextPlus();
       
   265 }
       
   266 
       
   267 /*!
       
   268  * \reimp
       
   269  * Sets the radio text plus to the currently tuned station
       
   270  */
       
   271 void RadioStationModelPrivate::setCurrentRadioTextPlus( uint frequency, int rtClass, const QString& rtItem )
       
   272 {
       
   273     Q_Q( RadioStationModel );
       
   274     RadioStation station = q->findStation( frequency, FindCriteria::IncludeManualStation );
       
   275     if ( !station.isValid() ) {
       
   276         LOG( "Unable to find current station. Ignoring RDS" );
       
   277         return;
       
   278     }
       
   279     station.setRadioTextPlus( rtClass, rtItem );
       
   280     q->saveStation( station );
       
   281     mUiEngine.api().historyModel().addRadioTextPlus( rtClass, rtItem, station );
       
   282 }
       
   283 
       
   284 /*!
       
   285  * \reimp
       
   286  * Sets the PI code to the currently tuned station
       
   287  */
       
   288 void RadioStationModelPrivate::setCurrentPiCode( uint frequency, int piCode )
       
   289 {
       
   290     Q_Q( RadioStationModel );
       
   291     RadioStation station = q->findStation( frequency, FindCriteria::IncludeManualStation );
       
   292     if ( !station.isValid() ) {
       
   293         LOG( "Unable to find current station. Ignoring RDS" );
       
   294         return;
       
   295     }
       
   296 #ifdef SHOW_CALLSIGN_IN_ANY_REGION
       
   297     RadioRegion::Region region = RadioRegion::America;
       
   298 #else
       
   299     RadioRegion::Region region =  mWrapper->region();
       
   300 #endif
       
   301 
       
   302     station.setPiCode( piCode, region );
       
   303     q->saveStation( station );
       
   304 }
       
   305 
       
   306 /*!
       
   307  *
       
   308  */
       
   309 void RadioStationModelPrivate::doSaveStation( RadioStation& station, bool persistentSave )
       
   310 {
       
   311     mStations.insert( station.frequency(), station );
       
   312 
       
   313     if ( persistentSave ) {
       
   314         const bool success = mPresetStorage->savePreset( *station.data_ptr() );
       
   315         RADIO_ASSERT( success, "RadioStationModelPrivate::saveStation", "Failed to add station" );
       
   316         Q_UNUSED( success );
       
   317     }
       
   318 }
       
   319 
       
   320 /*!
       
   321  *
       
   322  */
       
   323 QList<RadioStation> RadioStationModelPrivate::favorites() const
       
   324 {
       
   325     QList<RadioStation> favoriteList;
       
   326     foreach( const RadioStation& tempStation, mStations ) {
       
   327         if ( tempStation.isFavorite() ) {
       
   328             favoriteList.append( tempStation );
       
   329         }
       
   330     }
       
   331     return favoriteList;
       
   332 }