radioapp/radiouiengine/src/radiostationmodel.cpp
branchRCL_3
changeset 20 93c594350b9a
parent 19 cce62ebc198e
--- a/radioapp/radiouiengine/src/radiostationmodel.cpp	Tue Aug 31 15:15:02 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,753 +0,0 @@
-/*
-* 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:
-*
-*/
-
-// System includes
-#include <QStringList>
-
-// User includes
-#include "radiostationmodel.h"
-#include "radiostationmodel_p.h"
-#include "radiopresetstorage.h"
-#include "radioenginewrapper.h"
-#include "radiouiengine.h"
-#include "radiouiengine_p.h"
-#include "radiostation.h"
-#include "radiostation_p.h"
-#include "radiologger.h"
-
-/*!
- *
- */
-static QString parseLine( const RadioStation& station )
-{
-    QString line = "";
-    const QString parsedFrequency = qtTrId( "txt_rad_dblist_l1_mhz" ).arg( RadioStation::parseFrequency( station.frequency() ) );
-    line.append( parsedFrequency );
-
-    QString name = station.name();
-    if ( !name.isEmpty() )
-    {
-        line.append( " - " );
-        line.append( name.trimmed() );
-    }
-
-    LOG_FORMAT( "RadioStationModel: Returning line %s", GETSTRING(line) );
-    return line;
-}
-
-/*!
- *
- */
-RadioStationModel::RadioStationModel( RadioUiEnginePrivate& uiEngine ) :
-    QAbstractListModel( &uiEngine.api() ),
-    d_ptr( new RadioStationModelPrivate( this, uiEngine ) )
-{
-}
-
-/*!
- *
- */
-RadioStationModel::~RadioStationModel()
-{
-}
-
-/*!
- *
- */
-Qt::ItemFlags RadioStationModel::flags ( const QModelIndex& index ) const
-{
-    Qt::ItemFlags flags = QAbstractListModel::flags( index );
-    flags |= Qt::ItemIsEditable;
-    return flags;
-}
-
-/*!
- *
- */
-int RadioStationModel::rowCount( const QModelIndex& parent ) const
-{
-    Q_UNUSED( parent );
-    Q_D( const RadioStationModel );
-    const int count = d->mStations.keys().count();
-    return count;
-}
-
-/*!
- * Checks the given station and emits signals based on what member variables had been changed
- */
-QVariant RadioStationModel::data( const QModelIndex& index, int role ) const
-{
-    if ( !index.isValid() ) {
-        return QVariant();
-    }
-
-    Q_D( const RadioStationModel );
-    if ( role == Qt::DisplayRole ) {
-        RadioStation station = stationAt( index.row() );
-        QString firstLine = parseLine( station );
-        if ( d->mDetailLevel.testFlag( RadioStationModel::ShowGenre ) ) {
-            QStringList list;
-            list.append( firstLine );
-            QString genre = " "; // Empty space so that the listbox generates the second row
-            if ( station.genre() != -1 ) {
-                genre = d->mUiEngine.api().genreToString( station.genre(), GenreTarget::StationsList );
-            }
-            list.append( genre );
-
-            return list;
-        }
-
-        return firstLine;
-    } else if ( role == RadioRole::RadioStationRole ) {
-        QVariant variant;
-        variant.setValue( stationAt( index.row() ) );
-        return variant;
-    } else if ( role == Qt::DecorationRole &&
-                d->mDetailLevel.testFlag( RadioStationModel::ShowIcons ) ) {
-        RadioStation station = stationAt( index.row() );
-        QVariantList list;
-        if ( station.isFavorite() && !d->mFavoriteIcon.isNull() ) {
-            list.append( d->mFavoriteIcon );
-        } else {
-            list.append( QIcon() );
-        }
-        if ( currentStation().frequency() == station.frequency() && !d->mNowPlayingIcon.isNull() ) {
-            list.append( d->mNowPlayingIcon );
-        }
-        return list;
-    } else if ( role == RadioRole::IsFavoriteRole ) {
-        QVariant variant;
-        variant.setValue( stationAt( index.row() ).isFavorite() );
-        return variant;
-    }
-
-    return QVariant();
-}
-
-/*!
- * Checks the given station and emits signals based on what member variables had been changed
- */
-bool RadioStationModel::setData( const QModelIndex& index, const QVariant& value, int role )
-{
-    Q_UNUSED( index );
-
-    if ( role == RadioRole::ToggleFavoriteRole ) {
-        const uint frequency = value.toUInt();
-        RadioStation station;
-        if ( findFrequency( frequency, station ) ) {
-            setFavoriteByPreset( station.presetIndex(), !station.isFavorite() );
-        } else {
-            setFavoriteByFrequency( frequency, true );
-        }
-
-        return true;
-    }
-
-    return false;
-}
-
-/*!
- * Called by the engine to initialize the list with given amount of presets
- */
-void RadioStationModel::initialize( RadioPresetStorage* storage, RadioEngineWrapper* wrapper )
-{
-    Q_D( RadioStationModel );
-    d->mPresetStorage = storage;
-    d->mWrapper = wrapper;
-
-    int index = d->mPresetStorage->firstPreset();
-    LOG_FORMAT( "RadioStationModel::initialize: presetCount: %d, firstIndex: %d",
-                                            d->mPresetStorage->presetCount(), index );
-
-    while ( index >= 0 ) {
-        RadioStation station;
-
-        RadioStationIf* stationInterface = static_cast<RadioStationIf*>( station.data_ptr() );
-        if ( d->mPresetStorage->readPreset( index, *stationInterface ) ) {
-            if ( station.isValid() && d->mWrapper->isFrequencyValid( station.frequency() ) ) {
-
-#ifdef INIT_STATIONS_WITH_DUMMY_RT
-                station.setGenre( GenreEurope::RdsChildrensProgrammes );
-                if ( index % 3 == 0 ) {
-                    station.setName( "Radio Rock" );
-                    station.setRadioText( "Now playing: <font color='cyan'>The Presidents of the United States of America</font> - <font color='cyan'>Dune Buggy and diipa daapa jhkjhui erjlkej rewjtl</font>" );
-                } else if ( index % 2 == 0 ) {
-                    station.setName( "Radio Rock" );
-                } else {
-                    station.setDynamicPsText( "DYN PS" );
-                }
-#endif // INIT_STATIONS_WITH_DUMMY_RT
-
-                // Check if the station seems to send RDS or not.
-                // Note that radiotext is not checked because it is not saved to cenrep
-                // TODO: Consider saving this state flag to cenrep
-                if ( ( station.hasName() && !station.isRenamed() ) || station.hasUrl() ) {
-                    static_cast<RadioStationIf*>( station.data_ptr() )->setStationHasSentRds( true );
-                }
-
-                d->mStations.insert( station.frequency(), station );
-            } else {
-                LOG( "RadioStationModel::initialize: Invalid station!" );
-                LOG_FORMAT( "Invalid station freq: %d", station.frequency() );
-            }
-        }
-
-        index = d->mPresetStorage->nextPreset( index );
-    }
-
-    d->setCurrentStation( d->mWrapper->currentFrequency() );
-
-    wrapper->addObserver( d );
-}
-
-/*!
- * Sets the icons to be used in the lists
- */
-void RadioStationModel::setIcons( const QIcon& favoriteIcon, const QIcon& nowPlayingIcon )
-{
-    Q_D( RadioStationModel );
-    d->mFavoriteIcon = favoriteIcon;
-    d->mNowPlayingIcon = nowPlayingIcon;
-}
-
-/*!
- * Returns a reference to the station handler interface
- */
-RadioStationHandlerIf& RadioStationModel::stationHandlerIf()
-{
-    Q_D( RadioStationModel );
-    return *d;
-}
-
-/*!
- * Returns a reference to the underlying QList so that it can be easily looped
- */
-const Stations& RadioStationModel::list() const
-{
-    Q_D( const RadioStationModel );
-    return d->mStations;
-}
-
-/*!
- * Returns the station at the given index.
- */
-RadioStation RadioStationModel::stationAt( int index ) const
-{
-    // Get the value from the keys list instead of directly accessing the values list
-    // because QMap may have added a default-constructed value to the values list
-    Q_D( const RadioStationModel );
-    if ( index >= 0 && index < d->mStations.keys().count() ) {
-        uint frequency = d->mStations.keys().at( index );
-        return d->mStations.value( frequency );
-    }
-    return RadioStation();
-}
-
-/*!
- * Finds a station by frequency
- */
-bool RadioStationModel::findFrequency( uint frequency, RadioStation& station, FindCriteria::Criteria criteria ) const
-{
-    Q_D( const RadioStationModel );
-
-    if ( criteria == FindCriteria::IncludeManualStation && d->mCurrentStation->frequency() == frequency ) {
-        station = *d->mCurrentStation;
-        return true;
-    }
-
-    if ( d->mStations.contains( frequency ) ) {
-        station = d->mStations.value( frequency );
-        return true;
-    }
-    return false;
-}
-
-/*!
- * Convenience function to find a radio station.
- */
-RadioStation RadioStationModel::findStation( uint frequency, FindCriteria::Criteria criteria ) const
-{
-    RadioStation station;
-    findFrequency( frequency, station, criteria ); // Return value ignored
-    return station;
-}
-
-/*!
- * Finds a station by preset index
- */
-int RadioStationModel::findPresetIndex( int presetIndex )
-{
-    Q_D( RadioStationModel );
-    int index = 0;
-    foreach( const RadioStation& tempStation, d->mStations ) {
-        if ( tempStation.presetIndex() == presetIndex ) {
-            return index;
-        }
-        ++index;
-    }
-
-    return RadioStation::NotFound;
-}
-
-/*!
- * Finds a station by preset index
- */
-int RadioStationModel::findPresetIndex( int presetIndex, RadioStation& station )
-{
-    Q_D( RadioStationModel );
-    const int index = findPresetIndex( presetIndex );
-    if ( index != RadioStation::NotFound ) {
-        station = d->mStations.values().at( index );
-    }
-    return index;
-}
-
-/*!
- * Finds the closest station from the given frequency
- */
-RadioStation RadioStationModel::findClosest( const uint frequency, StationSkip::Mode mode )
-{
-    Q_D( RadioStationModel );
-    const bool findFavorite = mode == StationSkip::PreviousFavorite || mode == StationSkip::NextFavorite;
-    const bool findNext = mode == StationSkip::Next || mode == StationSkip::NextFavorite;
-    QList<RadioStation> list = findFavorite ? d->favorites() : d->mStations.values();
-
-    if ( list.isEmpty() ) {
-        return RadioStation();
-    }
-
-    // Find the previous and next station from current frequency
-    RadioStation previous;
-    RadioStation next;
-    foreach( const RadioStation& station, list ) {
-        const uint testFreq = station.frequency();
-        if ( testFreq == frequency ) {
-            continue;
-        }
-
-        if ( testFreq > frequency ) {
-            next = station;
-            break;
-        }
-        previous = station;
-    }
-
-    // Check if we need to loop around
-    if ( findNext && !next.isValid() ) {
-        next = list.first();
-    } else if ( !findNext && !previous.isValid() ) {
-        previous = list.last();
-    }
-
-    return findNext ? next : previous;
-}
-
-/*!
- * Checks if the model contains the given frequency
- */
-bool RadioStationModel::contains( const uint frequency ) const
-{
-    RadioStation unused;
-    return findFrequency( frequency, unused );
-}
-
-/*!
- * Removes a station by frequency
- */
-void RadioStationModel::removeByFrequency( uint frequency )
-{
-    RadioStation station;
-    if ( findFrequency( frequency, station ) ) {
-        removeStation( station );
-    }
-}
-
-/*!
- * Removes a station by preset index
- */
-void RadioStationModel::removeByPresetIndex( int presetIndex )
-{
-    RadioStation station;
-    const int index = findPresetIndex( presetIndex, station );
-    if ( index >= 0 ) {
-        removeStation( station );
-    }
-}
-
-/*!
- * Removes the given station
- */
-void RadioStationModel::removeStation( const RadioStation& station )
-{
-    Q_D( RadioStationModel );
-    const uint frequency = station.frequency();
-    if ( d->mStations.contains( frequency ) ) {
-
-        // If we are removing the current station, copy its data to the current station pointer
-        // to keep all of the received RDS data still available. They will be discarded when
-        // the user tunes to another frequency, but they are available if the user decides to add it back.
-        if ( d->mCurrentStation->frequency() == frequency ) {
-            *d->mCurrentStation = station;
-        }
-
-        // Copy the station to a temporary variable that can be used as signal parameter
-        RadioStation tempStation = station;
-
-        const int row = indexFromFrequency( tempStation.frequency() );
-        beginRemoveRows( QModelIndex(), row, row );
-
-        d->mPresetStorage->deletePreset( tempStation.presetIndex() );
-        d->mStations.remove( frequency );
-
-        d->mCurrentStation = NULL;
-        d->setCurrentStation( d->mWrapper->currentFrequency() );
-
-        endRemoveRows();
-    }
-}
-
-/*!
- * Public slot
- * Removes all stations
- */
-void RadioStationModel::removeAll( RemoveMode mode )
-{
-    Q_D( RadioStationModel );
-    if ( d->mStations.count() == 0 ) {
-        return;
-    }
-
-    if ( mode == RemoveAll ) {
-        beginRemoveRows( QModelIndex(), 0, rowCount() - 1 );
-
-        // Preset utility deletes all presets with index -1
-        bool success = d->mPresetStorage->deletePreset( -1 );
-        Q_UNUSED( success );
-        RADIO_ASSERT( success, "FMRadio", "Failed to remove station" );
-
-        d->mStations.clear();
-        d->mCurrentStation = NULL;
-        d->setCurrentStation( d->mWrapper->currentFrequency() );
-
-        endRemoveRows();
-    } else {
-        foreach( const RadioStation& station, d->mStations ) {
-
-            if ( mode == RemoveLocalStations ) {
-                if ( station.isType( RadioStation::LocalStation ) && !station.isFavorite() ) {
-                    removeStation( station );
-                }
-            } else {
-                if ( station.isFavorite() ) {
-                    RadioStation newStation( station );
-                    newStation.setFavorite( false );
-                    saveStation( newStation );
-                }
-            }
-        }
-    }
-}
-
-/*!
- * Adds a new station to the list
- */
-void RadioStationModel::addStation( const RadioStation& station )
-{
-    Q_D( RadioStationModel );
-    const int newIndex = findUnusedPresetIndex();
-    LOG_FORMAT( "RadioStationModel::addStation: Adding station to index %d", newIndex );
-
-    RadioStation newStation = station;
-    newStation.setPresetIndex( newIndex );
-    newStation.unsetType( RadioStation::ManualStation );
-
-    // We have to call beginInsertRows() BEFORE the addition is actually done so we must figure out where
-    // the new station will go in the sorted frequency order
-    int row = 0;
-    const int count = rowCount();
-    if ( count > 1 ) {
-        Stations::const_iterator iter = d->mStations.upperBound( newStation.frequency() );
-        if ( d->mStations.contains( iter.key() ) ) {
-            row = d->mStations.keys().indexOf( iter.key() );
-        } else {
-            row = count;
-        }
-    } else if ( count == 1 ) {
-        uint existingFreq = d->mStations.keys().first();
-        if ( station.frequency() > existingFreq ) {
-            row = 1;
-        }
-    }
-
-    beginInsertRows( QModelIndex(), row, row );
-
-    d->doSaveStation( newStation );
-
-    d->setCurrentStation( d->mWrapper->currentFrequency() );
-
-    endInsertRows();
-
-    // Not all UI components listen to rowsInserted() signal so emit the favorite signal
-    if ( newStation.isFavorite() ) {
-        emit favoriteChanged( *d->mCurrentStation );
-    }
-}
-
-/*!
- * Saves the given station. It is expected to already exist in the list
- */
-void RadioStationModel::saveStation( RadioStation& station )
-{
-    Q_D( RadioStationModel );
-    const bool stationHasChanged = station.hasChanged();
-    RadioStation::Change changeFlags = station.changeFlags();
-    station.resetChangeFlags();
-
-    if ( station.isType( RadioStation::ManualStation ) ) {
-
-        d->mManualStation = station;
-        emitChangeSignals( station, changeFlags );
-
-    } else if ( station.isValid() && stationHasChanged && d->mStations.contains( station.frequency() )) {
-
-        d->doSaveStation( station, changeFlags.testFlag( RadioStation::PersistentDataChanged ) );
-        d->setCurrentStation( d->mWrapper->currentFrequency() );
-
-        emitChangeSignals( station, changeFlags );
-    }
-}
-
-/*!
- * Finds number of favorite stations
- */
-int RadioStationModel::favoriteCount()
-{
-    Q_D( const RadioStationModel );
-    return d->favorites().count();
-}
-
-/*!
- * Changes the favorite status of a station by its frequency. If the station does
- * not yet exist, it is added.
- */
-void RadioStationModel::setFavoriteByFrequency( uint frequency, bool favorite )
-{
-    Q_D( RadioStationModel );
-    if ( d->mWrapper->isFrequencyValid( frequency ) ) {
-        LOG_FORMAT( "RadioStationModel::setFavoriteByFrequency, frequency: %d", frequency );
-        RadioStation station;
-        if ( findFrequency( frequency, station ) ) { // Update existing preset
-            if ( station.isFavorite() != favorite ) {
-                station.setFavorite( favorite );
-                saveStation( station );
-            }
-        } else if ( favorite ) {                    // Add new preset if setting as favorite
-            RadioStation newStation;
-            if ( d->mCurrentStation->frequency() == frequency ) {
-                newStation = *d->mCurrentStation;
-            } else {
-                LOG( "CurrentStation frequency mismatch!" );
-                newStation.setFrequency( frequency );
-            }
-
-            newStation.setType( RadioStation::LocalStation | RadioStation::Favorite );
-
-            // Emit the signals only after adding the preset and reinitializing the current station
-            // because the UI will probably query the current station in its slots that get called.
-            addStation( newStation );
-        }
-    }
-}
-
-/*!
- * Changes the favorite status of a station by its preset index
- */
-void RadioStationModel::setFavoriteByPreset( int presetIndex, bool favorite )
-{
-    LOG_FORMAT( "RadioStationModel::setFavoriteByPreset, presetIndex: %d", presetIndex );
-    RadioStation station;
-    if ( findPresetIndex( presetIndex, station ) != RadioStation::NotFound ) {
-        station.setFavorite( favorite );
-        saveStation( station );
-    }
-}
-
-/*!
- * Renames a station by its preset index
- */
-void RadioStationModel::renameStation( int presetIndex, const QString& name )
-{
-    LOG_FORMAT( "RadioStationModel::renameStation, presetIndex: %d, name: %s", presetIndex, GETSTRING(name) );
-    RadioStation station;
-    if ( findPresetIndex( presetIndex, station ) != RadioStation::NotFound ) {
-        station.setUserDefinedName( name );
-        saveStation( station );
-    }
-}
-
-/*!
- *
- */
-void RadioStationModel::setFavorites( const QModelIndexList& favorites )
-{
-    foreach ( const QModelIndex& index, favorites ) {
-        RadioStation station = stationAt( index.row() );
-        RADIO_ASSERT( station.isValid() , "RadioStationModel::setFavorites", "invalid RadioStation");
-        setFavoriteByPreset( station.presetIndex(), true );
-    }
-}
-
-/*!
- * Returns the currently tuned station
- */
-RadioStation& RadioStationModel::currentStation()
-{
-    Q_D( RadioStationModel );
-    return *d->mCurrentStation;
-}
-
-/*!
- * Returns the currently tuned station
- */
-const RadioStation& RadioStationModel::currentStation() const
-{
-    Q_D( const RadioStationModel );
-    return *d->mCurrentStation;
-}
-
-/*!
- * Sets the model detail level
- */
-void RadioStationModel::setDetail( Detail level )
-{
-    Q_D( RadioStationModel );
-    d->mDetailLevel = level;
-}
-
-/*!
- * Returns a list of radio stations in the given frequency range
- */
-QList<RadioStation> RadioStationModel::stationsInRange( uint minFrequency, uint maxFrequency )
-{
-    Q_D( RadioStationModel );
-    QList<RadioStation> stations;
-    foreach( const RadioStation& station, d->mStations ) {
-        if ( station.frequency() >= minFrequency && station.frequency() <= maxFrequency ) {
-            stations.append( station );
-        }
-    }
-
-    return stations;
-}
-
-/*!
- * Returns the model index corresponding to the given frequency
- */
-int RadioStationModel::indexFromFrequency( uint frequency )
-{
-    RadioStation station;
-    if ( findFrequency( frequency, station ) ) {
-        return findPresetIndex( station.presetIndex() );
-    }
-    return -1;
-}
-
-/*!
- * Private slot
- * Timer timeout slot to indicate that the dynamic PS check has ended
- */
-void RadioStationModel::dynamicPsCheckEnded()
-{
-    Q_D( RadioStationModel );
-    LOG_TIMESTAMP( "Finished dynamic PS check." );
-    if ( d->mCurrentStation->psType() != RadioStation::Dynamic && !d->mCurrentStation->dynamicPsText().isEmpty() )
-    {
-        d->mCurrentStation->setPsType( RadioStation::Static );
-        d->mCurrentStation->setName( d->mCurrentStation->dynamicPsText() );
-        d->mCurrentStation->setDynamicPsText( "" );
-        saveStation( *d->mCurrentStation );
-    }
-}
-
-/*!
- * Checks the given station and emits signals based on what member variables had been changed
- */
-void RadioStationModel::emitChangeSignals( const RadioStation& station, RadioStation::Change flags )
-{
-    if ( flags.testFlag( RadioStation::NameChanged ) ||
-         flags.testFlag( RadioStation::GenreChanged ) ||
-         flags.testFlag( RadioStation::UrlChanged ) ||
-         flags.testFlag( RadioStation::TypeChanged ) ||
-         flags.testFlag( RadioStation::PiCodeChanged ) ) {
-
-        // Create a temporary RadioStation for the duration of the signal-slot processing
-        // The receivers can ask the station what data has changed and update accordingly
-        RadioStation tempStation( station );
-        tempStation.setChangeFlags( flags );
-        emit stationDataChanged( tempStation );
-
-        emitDataChanged( tempStation );
-    }
-
-    if ( flags.testFlag( RadioStation::RadioTextChanged ) ) {
-        emit radioTextReceived( station );
-        emitDataChanged( station );
-    }
-
-    if ( flags.testFlag( RadioStation::DynamicPsChanged ) ) {
-        emit dynamicPsChanged( station );
-        emitDataChanged( station );
-    }
-
-    if ( flags.testFlag( RadioStation::FavoriteChanged ) && station.isValid() ) {
-        emit favoriteChanged( station );
-        emitDataChanged( station );
-    }
-}
-
-/*!
- *
- */
-void RadioStationModel::emitDataChanged( const RadioStation& station )
-{
-    const int row = findPresetIndex( station.presetIndex() );
-    QModelIndex top = index( row, 0, QModelIndex() );
-    QModelIndex bottom = index( row, 0, QModelIndex() );
-    emit dataChanged( top, bottom );
-}
-
-/*!
- * Finds an unused preset index
- */
-int RadioStationModel::findUnusedPresetIndex()
-{
-    Q_D( RadioStationModel );
-    QList<int> indexes;
-    foreach( const RadioStation& station, d->mStations ) {
-        if ( station.isValid() ) {
-            indexes.append( station.presetIndex() );
-        }
-    }
-
-    int index = 0;
-    for ( ; indexes.contains( index ); ++index ) {
-        // Nothing to do here
-    }
-
-    LOG_FORMAT( "RadioStationModel::findUnusedPresetIndex, index: %d", index );
-    return index;
-}