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