radioapp/radiouiengine/src/radiohistorymodel_p.cpp
changeset 19 afea38384506
parent 16 f54ebcfc1b80
child 37 451b2e1545b2
equal deleted inserted replaced
16:f54ebcfc1b80 19:afea38384506
    13 *
    13 *
    14 * Description:
    14 * Description:
    15 *
    15 *
    16 */
    16 */
    17 
    17 
       
    18 // System includes
       
    19 #include <QSqlDatabase>
       
    20 #include <QFile>
       
    21 #include <QDateTime>
       
    22 #include <QVariant>
       
    23 #include <QStringList>
       
    24 #include <QSqlError>
       
    25 #include <QSqlQueryModel>
       
    26 #include <QSqlRecord>
       
    27 
       
    28 // User includes
    18 #include "radiohistorymodel_p.h"
    29 #include "radiohistorymodel_p.h"
       
    30 #include "radiohistorymodel.h"
    19 #include "radiohistoryitem.h"
    31 #include "radiohistoryitem.h"
       
    32 #include "radiohistoryitem_p.h"
       
    33 #include "radiostation.h"
       
    34 #include "radiologger.h"
       
    35 
       
    36 const char* DATABASE_NAME       = "radioplayhistory.db";
       
    37 const char* DATABASE_DRIVER     = "QSQLITE";
       
    38 const char* HISTORY_TABLE       = "history";
       
    39 const char* SQL_CREATE_TABLE    = "CREATE TABLE history ("
       
    40                                   "id INTEGER PRIMARY KEY AUTOINCREMENT, "
       
    41                                   "artist TEXT NOT NULL, "
       
    42                                   "title TEXT NOT NULL, "
       
    43                                   "station TEXT NOT NULL, "
       
    44                                   "frequency INTEGER NOT NULL, "
       
    45                                   "tagged INTEGER NOT NULL DEFAULT 0, "
       
    46                                   "fromRds INTEGER NOT NULL DEFAULT 1, "
       
    47                                   "time TIMESTAMP NOT NULL)";
       
    48 
       
    49 const char* SQL_ADD_ITEM         = "INSERT INTO history (artist,title,station,frequency,fromRds,time) "
       
    50                                             "VALUES ( ?,?,?,?,?,? )";
       
    51 
       
    52 const char* SQL_SELECT_ALL       = "SELECT * FROM history ORDER BY id DESC";
       
    53 const char* SQL_SELECT_TAGGED    = "SELECT * FROM history WHERE tagged=1";// ORDER BY id DESC";
       
    54 
       
    55 const char* SQL_DELETE_ALL       = "DELETE FROM history";
       
    56 
       
    57 //static const char* SQL_FIND_ITEM_BY_ID = "SELECT * FROM history WHERE id = ?";
       
    58 const char* SQL_TOGGLE_TAG       = "UPDATE history SET tagged = ? WHERE id = ?";
       
    59 
       
    60 
       
    61 #ifdef LOGGING_ENABLED
       
    62 #   define GET_ERR( param ) GETSTRING( param.lastError().text() )
       
    63 #   define GET_ERR_PTR( param ) GETSTRING( param->lastError().text() )
       
    64 #endif // LOGGING_ENABLED
       
    65 
       
    66 /*!
       
    67  * Static utility function to parse a frequency
       
    68  */
       
    69 static  QString parseFrequency( const uint frequency )
       
    70 {
       
    71     QString loc = qtTrId( "txt_rad_dblist_val_l1_mhz" );
       
    72     return loc.arg( RadioStation::parseFrequency( frequency ) );
       
    73 }
    20 
    74 
    21 /*!
    75 /*!
    22  *
    76  *
    23  */
    77  */
    24 RadioHistoryModelPrivate::RadioHistoryModelPrivate( RadioHistoryModel* model,
    78 RadioHistoryModelPrivate::RadioHistoryModelPrivate( RadioHistoryModel* model,
    25                                                     RadioUiEngine& uiEngine ) :
    79                                                     RadioUiEngine& uiEngine ) :
    26     q_ptr( model ),
    80     q_ptr( model ),
    27     mUiEngine( uiEngine ),
    81     mUiEngine( uiEngine ),
    28     mTopItemIsPlaying( false ),
    82     mTopItemIsPlaying( false ),
    29     mShowDetails( false )
    83     mShowDetails( true ),
    30 {
    84     mViewMode( ShowAll ),
    31 
    85     mRtItemClass( -1 )
       
    86 {
    32 }
    87 }
    33 
    88 
    34 /*!
    89 /*!
    35  *
    90  *
    36  */
    91  */
    37 RadioHistoryModelPrivate::~RadioHistoryModelPrivate()
    92 RadioHistoryModelPrivate::~RadioHistoryModelPrivate()
    38 {
    93 {
    39 
    94     if ( mDatabase && mDatabase->isOpen() ) {
    40 }
    95         mDatabase->close();
       
    96     }
       
    97 }
       
    98 
       
    99 /*!
       
   100  *
       
   101  */
       
   102 bool RadioHistoryModelPrivate::connectToDatabase()
       
   103 {
       
   104     LOG_METHOD;
       
   105     QSqlDatabase db = QSqlDatabase::addDatabase( DATABASE_DRIVER );
       
   106     if ( db.isValid() ) {
       
   107         mDatabase.reset( new QSqlDatabase( db ) );
       
   108         mDatabase->setDatabaseName( DATABASE_NAME );
       
   109 
       
   110         if ( !mDatabase->open() ) {
       
   111             LOG_FORMAT( "Failed to open database! error = %s", GET_ERR_PTR( mDatabase ) );
       
   112             mDatabase.reset();
       
   113             return false;
       
   114         }
       
   115 
       
   116         // Create the table if it does not exist
       
   117         if ( !mDatabase->tables().contains( HISTORY_TABLE ) ) {
       
   118             LOG( "RadioHistoryModelPrivate::connectToDatabase: Creating database tables." );
       
   119             QSqlQuery query;
       
   120             if ( !query.exec( SQL_CREATE_TABLE ) ) {
       
   121                 LOG_FORMAT( "Database creation failed! error = %s", GET_ERR( query ) );
       
   122                 mDatabase->close();
       
   123                 mDatabase.reset();
       
   124                 return false;
       
   125             }
       
   126         }
       
   127     } else {
       
   128         LOG_FORMAT( "Invalid database! error = %s", GET_ERR( db ) );
       
   129         return false;
       
   130     }
       
   131 
       
   132     mQueryModel.reset( new QSqlQueryModel() );
       
   133     setViewMode( ShowAll );
       
   134 
       
   135     return mQueryModel->lastError().type() == QSqlError::NoError;
       
   136 }
       
   137 
       
   138 /*!
       
   139  *
       
   140  */
       
   141 void RadioHistoryModelPrivate::addItem( const QString& artist,
       
   142                                         const QString& title,
       
   143                                         const RadioStation& station,
       
   144                                         bool fromRds )
       
   145 {
       
   146     LOG_FORMAT( "RadioHistoryModelPrivate::addItem. Artist: %s, Title: %s", GETSTRING( artist ), GETSTRING( title ) );
       
   147 
       
   148     if ( !mQueryModel ) {
       
   149         return;
       
   150     }
       
   151 
       
   152     mTopItemIsPlaying = true;
       
   153 
       
   154     QSqlQuery query = beginTransaction();
       
   155 
       
   156     query.prepare( SQL_ADD_ITEM );
       
   157     query.addBindValue( artist );
       
   158     query.addBindValue( title );
       
   159     query.addBindValue( station.name() );
       
   160     query.addBindValue( static_cast<int>( station.frequency() / 1000 ) );
       
   161     query.addBindValue( fromRds );
       
   162     query.addBindValue( QDateTime::currentDateTime().toTime_t() );
       
   163 
       
   164     commitTransaction( query, InsertRows, 0 );
       
   165 }
       
   166 
       
   167 /*!
       
   168  *
       
   169  */
       
   170 int RadioHistoryModelPrivate::rowCount() const
       
   171 {
       
   172     if ( !mQueryModel ) {
       
   173         return 0;
       
   174     }
       
   175     return mQueryModel->rowCount();
       
   176 }
       
   177 
       
   178 /*!
       
   179  *
       
   180  */
       
   181 QVariant RadioHistoryModelPrivate::data( const int row, const int role ) const
       
   182 {
       
   183     if ( mQueryModel->lastError().type() == QSqlError::NoError ) {
       
   184 
       
   185         QSqlRecord record = mQueryModel->record( row );
       
   186         if ( role == Qt::DisplayRole ) {
       
   187 
       
   188             const QString artist = record.value( RadioHistoryValue::Artist ).toString();
       
   189             const QString title = record.value( RadioHistoryValue::Title ).toString();
       
   190             const QString station = record.value( RadioHistoryValue::Station ).toString();
       
   191             const uint frequency = record.value( RadioHistoryValue::Frequency ).toUInt() * 1000;
       
   192 
       
   193             QStringList list;
       
   194             if ( mShowDetails ) {
       
   195                 list.append( qtTrId( "txt_rad_dblist_1_2" ).arg( artist ).arg( title ) );
       
   196                 QDateTime dateTime = record.value( RadioHistoryValue::Time ).toDateTime();
       
   197                 const QString time = dateTime.toLocalTime().toString();
       
   198 
       
   199                 QString name = !station.isEmpty() ? station : parseFrequency( frequency );
       
   200                 list.append( qtTrId( "txt_rad_dblist_1_2" ).arg( time ).arg( name ) );
       
   201             } else {
       
   202                 list.append( artist );
       
   203                 list.append( title );
       
   204             }
       
   205 
       
   206             return list;
       
   207         } else if ( role == Qt::DecorationRole ) {
       
   208             QVariantList list;
       
   209             const bool tagged = record.value( RadioHistoryValue::Tagged ).toBool();
       
   210             if ( tagged ) {
       
   211                 list.append( mTaggedIcon );
       
   212             } else {
       
   213                 list.append( mNonTaggedIcon );
       
   214             }
       
   215             return list;
       
   216         }
       
   217     }
       
   218 
       
   219     return QVariant();
       
   220 }
       
   221 
       
   222 /*!
       
   223  *
       
   224  */
       
   225 void RadioHistoryModelPrivate::removeAll()
       
   226 {
       
   227     if ( !mQueryModel ) {
       
   228         return;
       
   229     }
       
   230 
       
   231     QSqlQuery query = beginTransaction();
       
   232 
       
   233     query.prepare( SQL_DELETE_ALL );
       
   234 
       
   235     // Commented out because rowsRemoved() seems to crash HbListView
       
   236 //    commitTransaction( query, RemoveRows, 0, rowCount() - 1 );
       
   237 
       
   238     commitTransaction( query, NoOp, 0 );
       
   239     q_ptr->reset();
       
   240 }
       
   241 
       
   242 /*!
       
   243  *
       
   244  */
       
   245 void RadioHistoryModelPrivate::setViewMode( ViewMode mode )
       
   246 {
       
   247     if ( !mQueryModel ) {
       
   248         return;
       
   249     }
       
   250 
       
   251     mViewMode = mode;
       
   252     mQueryModel->setQuery( mode == ShowTagged ? SQL_SELECT_TAGGED : SQL_SELECT_ALL, *mDatabase );
       
   253     q_ptr->reset();
       
   254 }
       
   255 
       
   256 /*!
       
   257  *
       
   258  */
       
   259 void RadioHistoryModelPrivate::toggleTagging( const RadioHistoryItem& item, const int row )
       
   260 {
       
   261     QSqlQuery updateQuery = beginTransaction();
       
   262 
       
   263     updateQuery.prepare( SQL_TOGGLE_TAG );
       
   264     updateQuery.addBindValue( item.isTagged() ? 0 : 1 );
       
   265     updateQuery.addBindValue( item.id() );
       
   266 
       
   267     commitTransaction( updateQuery, ChangeData, row );
       
   268 }
       
   269 
       
   270 /*!
       
   271  *
       
   272  */
       
   273 RadioHistoryItem RadioHistoryModelPrivate::itemAtIndex( const QModelIndex& index ) const
       
   274 {
       
   275     LOG_METHOD;
       
   276     RadioHistoryItem item;
       
   277     QSqlRecord record = mQueryModel->record( index.row() );
       
   278     item.data_ptr()->initFromRecord( record );
       
   279     return item;
       
   280 }
       
   281 
       
   282 /*!
       
   283  *
       
   284  */
       
   285 void RadioHistoryModelPrivate::refreshModel()
       
   286 {
       
   287     setViewMode( mViewMode );
       
   288 }
       
   289 
       
   290 /*!
       
   291  *
       
   292  */
       
   293 QSqlQuery RadioHistoryModelPrivate::beginTransaction()
       
   294 {
       
   295     LOG_METHOD;
       
   296     QSqlQuery newQuery( *mDatabase );
       
   297     mDatabase->transaction();
       
   298     return newQuery;
       
   299 }
       
   300 
       
   301 /*!
       
   302  *
       
   303  */
       
   304 void RadioHistoryModelPrivate::commitTransaction( QSqlQuery& query, Operation operation, int start, int end )
       
   305 {
       
   306     LOG_METHOD;
       
   307     if ( end == -1 ) {
       
   308         end = start;
       
   309     }
       
   310 
       
   311     bool success = false;
       
   312     Q_UNUSED( success );
       
   313     if ( query.exec() ) {
       
   314         if ( operation == InsertRows ) {
       
   315             q_ptr->beginInsertRows( QModelIndex(), start, end );
       
   316         } else if ( operation == RemoveRows ) {
       
   317             q_ptr->beginRemoveRows( QModelIndex(), start, end );
       
   318         }
       
   319 
       
   320         success = mDatabase->commit();
       
   321         LOG_ASSERT( success, LOG_FORMAT( "Commit failed! err: %s", GET_ERR_PTR( mDatabase ) ) );
       
   322 
       
   323         refreshModel();
       
   324 
       
   325         if ( operation == InsertRows ) {
       
   326             q_ptr->endInsertRows();
       
   327             q_ptr->emitItemAdded();
       
   328         } else if ( operation == RemoveRows ) {
       
   329             q_ptr->endRemoveRows();
       
   330         } else if ( operation == ChangeData ) {
       
   331             q_ptr->reportChangedData( start );
       
   332         }
       
   333     } else {
       
   334         LOG_FORMAT( "RadioHistoryModelPrivate::commitTransaction FAILED, rolling back: error = %s", GET_ERR( query ) );
       
   335         success = mDatabase->rollback();
       
   336         LOG_ASSERT( success, LOG_FORMAT( "Rollback failed! err: %s", GET_ERR_PTR( mDatabase ) ) );
       
   337     }
       
   338 }