radioapp/radiowidgets/src/radiofrequencystripbase.cpp
branchRCL_3
changeset 45 cce62ebc198e
equal deleted inserted replaced
43:1a6714c53019 45: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 <HbDocumentLoader>
       
    20 #include <HbEffect>
       
    21 #include <QPainter>
       
    22 #include <QStringListModel>
       
    23 #include <QGraphicsSceneResizeEvent>
       
    24 #include <QPen>
       
    25 #include <HbPushButton>
       
    26 #include <QTimer>
       
    27 #include <HbColorScheme>
       
    28 #include <HbEvent>
       
    29 #include <HbSwipeGesture>
       
    30 #include <HbDeviceProfile>
       
    31 #include <QDebug>
       
    32 
       
    33 // User includes
       
    34 #include "radiofrequencystripbase.h"
       
    35 #include "radiofrequencystripdef.h"
       
    36 #include "radiofrequencyitem.h"
       
    37 
       
    38 /*!
       
    39  * Convenience function to check signal-slot connections
       
    40  */
       
    41 //#define CHECK_SIGNAL_CONNECTIONS
       
    42 static bool connectAndCheck( const QObject* sender, const char* signal,
       
    43                              const QObject* receiver, const char* member,
       
    44                              Qt::ConnectionType type = Qt::AutoConnection )
       
    45 {
       
    46     bool connected = QObject::connect( sender, signal, receiver, member, type );
       
    47 
       
    48     #ifdef CHECK_SIGNAL_CONNECTIONS
       
    49 
       
    50     if ( !connected ) {
       
    51         qDebug() << "Failed to make a signal-slot connection!";
       
    52         qDebug() << "sender: " << sender->metaObject()->className();
       
    53         qDebug() << "signal: " << signal;
       
    54         qDebug() << "receiver: " << receiver->metaObject()->className();
       
    55         qDebug() << "slot/signal: " << signal;
       
    56 
       
    57         Q_ASSERT( false );
       
    58 
       
    59         // ----------------------------------------------------------------
       
    60         // SIGNAL-SLOT CONNECT FAILED!
       
    61         // ----------------------------------------------------------------
       
    62     }
       
    63 
       
    64     #endif // CHECK_SIGNAL_CONNECTIONS
       
    65 
       
    66     return connected;
       
    67 }
       
    68 
       
    69 /*!
       
    70  *
       
    71  */
       
    72 RadioFrequencyStripBase::RadioFrequencyStripBase( QGraphicsItem* parent ) :
       
    73     RadioStripBase( parent ),
       
    74     mItemHeight( 8 ),
       
    75     mMinFrequency( 87500000 ),
       
    76     mMaxFrequency( 108000000 ),
       
    77     mFrequencyStepSize( 100000 ),
       
    78     mFrequency( 87500000 ),
       
    79     mSelectorImage( new QGraphicsPixmapItem( this ) ),
       
    80     mSeparatorPos( 0.0 ),
       
    81     mMaxWidth( 0 ),
       
    82     mSelectorPos( 0.0 ),
       
    83     mLeftButton( 0 ),
       
    84     mRightButton( 0 ),
       
    85     mManualSeekTimer( NULL ),
       
    86     mManualSeekMode( false ),
       
    87     mLastReportedFrequency( 0 ),
       
    88     mManualSeekTimerId( 0 ),
       
    89     mForegroundColor( Qt::white )//HbColorScheme::color( FrequencyStrip::TEXT_COLOR_ATTRIBUTE ) )
       
    90 {
       
    91     setScrollingStyle( HbScrollArea::PanWithFollowOn );
       
    92     setItemSize( QSizeF( FrequencyStrip::ITEM_WIDTH + FrequencyStrip::PIXMAP_OVERLAP / 2, mItemHeight ) );
       
    93     setOverlap( FrequencyStrip::PIXMAP_OVERLAP / 2 );
       
    94 }
       
    95 
       
    96 /*!
       
    97  * Property
       
    98  */
       
    99 void RadioFrequencyStripBase::setItemHeight( int itemHeight )
       
   100 {
       
   101     mItemHeight = itemHeight;
       
   102 }
       
   103 
       
   104 /*!
       
   105  * Property
       
   106  */
       
   107 int RadioFrequencyStripBase::itemHeight() const
       
   108 {
       
   109     return mItemHeight;
       
   110 }
       
   111 
       
   112 /*!
       
   113  *
       
   114  */
       
   115 void RadioFrequencyStripBase::initbase( uint minFrequency, uint maxFrequency, uint stepSize, uint frequency )
       
   116 {
       
   117     mMinFrequency       = minFrequency;
       
   118     mMaxFrequency       = maxFrequency;
       
   119     mFrequencyStepSize  = stepSize;
       
   120     mFrequency          = frequency;
       
   121 
       
   122     initModel();
       
   123     initEmptyItems();
       
   124     initPositions();
       
   125 
       
   126     HbDeviceProfile deviceProfile;
       
   127     mItemHeight = static_cast<int>( mItemHeight * deviceProfile.unitValue() );
       
   128 
       
   129     mManualSeekTimer = new QTimer( this );
       
   130     mManualSeekTimer->setInterval( FrequencyStrip::MANUALSEEK_START_TIMEOUT );
       
   131     mManualSeekTimer->setSingleShot( true );
       
   132     connectAndCheck( mManualSeekTimer,   SIGNAL(timeout()),
       
   133                      this,               SLOT(toggleManualSeek()) );
       
   134 
       
   135     connectAndCheck( this,           SIGNAL(scrollingEnded()),
       
   136                      this,           SLOT(handleScrollingEnd()) );
       
   137 
       
   138     grabGesture( Qt::SwipeGesture );
       
   139 
       
   140     //TODO: Remove. Stepsize temporarily hardcoded to 100 Khz in europe region
       
   141     if ( mFrequencyStepSize < FrequencyStrip::ONE_HUNDRED_KHZ ) {
       
   142         mFrequencyStepSize = FrequencyStrip::ONE_HUNDRED_KHZ;
       
   143     }
       
   144 
       
   145     updateAllItems();
       
   146 
       
   147     showButtons();
       
   148 }
       
   149 
       
   150 /*!
       
   151  *
       
   152  */
       
   153 void RadioFrequencyStripBase::createButtonsFromDocml( HbDocumentLoader& uiLoader, const QString& leftButtonName, const QString& rightButtonName )
       
   154 {
       
   155     Q_ASSERT( !mLeftButton && !mRightButton );
       
   156     mLeftButton = qobject_cast<HbPushButton*>( uiLoader.findWidget( leftButtonName ) );
       
   157     mRightButton = qobject_cast<HbPushButton*>( uiLoader.findWidget( rightButtonName ) );
       
   158 
       
   159     initButtons();
       
   160 }
       
   161 
       
   162 /*!
       
   163  *
       
   164  */
       
   165 void RadioFrequencyStripBase::createButtons()
       
   166 {
       
   167     Q_ASSERT( !mLeftButton && !mRightButton );
       
   168     mLeftButton = new HbPushButton( this );
       
   169     mRightButton = new HbPushButton( this );
       
   170 
       
   171     mLeftButton->setIcon( HbIcon( "qtg_mono_previous" ) );
       
   172     mRightButton->setIcon( HbIcon( "qtg_mono_next" ) );
       
   173 
       
   174     initButtons();
       
   175 }
       
   176 
       
   177 /*!
       
   178  *
       
   179  */
       
   180 void RadioFrequencyStripBase::setFrequency( const uint frequency, int reason, Scroll::Direction direction )
       
   181 {
       
   182     if ( mFrequencies.contains( frequency ) ) {
       
   183         scrollToFrequency( frequency, direction, mAutoScrollTime );
       
   184     }
       
   185 }
       
   186 
       
   187 /*!
       
   188  *
       
   189  */
       
   190 uint RadioFrequencyStripBase::frequency() const
       
   191 {
       
   192     return mFrequency;
       
   193 }
       
   194 
       
   195 /*!
       
   196  *
       
   197  */
       
   198 bool RadioFrequencyStripBase::isInManualSeekMode() const
       
   199 {
       
   200     return mManualSeekMode;
       
   201 }
       
   202 
       
   203 /*!
       
   204  *
       
   205  */
       
   206 void RadioFrequencyStripBase::cancelManualSeek()
       
   207 {
       
   208     mManualSeekTimer->stop();
       
   209     if ( mManualSeekMode ) {
       
   210         toggleManualSeek();
       
   211     }
       
   212 }
       
   213 
       
   214 /*!
       
   215  *
       
   216  */
       
   217 void RadioFrequencyStripBase::addScannedStation( uint frequency )
       
   218 {
       
   219     FrequencyPos pos = mFrequencies.value( frequency );
       
   220     updateItem( pos.mItem, frequency );
       
   221 }
       
   222 
       
   223 /*!
       
   224  *
       
   225  */
       
   226 void RadioFrequencyStripBase::updateFavorite( uint frequency )
       
   227 {
       
   228     FrequencyPos pos = mFrequencies.value( frequency );
       
   229     updateItem( pos.mItem );
       
   230 }
       
   231 
       
   232 /*!
       
   233  * Public slot
       
   234  *
       
   235  */
       
   236 void RadioFrequencyStripBase::setScanningMode( bool isScanning )
       
   237 {
       
   238     mManualSeekTimer->stop();
       
   239     if ( isScanning ) {
       
   240         initEmptyItems();
       
   241         hideButtons();
       
   242         scrollToFrequency( mMinFrequency, Scroll::Shortest, mAutoScrollTime );
       
   243     } else {
       
   244         showButtons();
       
   245     }
       
   246     setEnabled( !isScanning );
       
   247 }
       
   248 
       
   249 /*!
       
   250  * Private slot
       
   251  *
       
   252  */
       
   253 void RadioFrequencyStripBase::initEmptyItems()
       
   254 {
       
   255     //TODO: Remove the weird hack of checking the sender
       
   256     if ( !sender() || !isScanning() ) {
       
   257         QList<FrequencyStrip::StationMarker> emptyList;
       
   258         foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
       
   259             QPixmap pixmap = drawPixmap( item->frequency(), emptyList, item );
       
   260             item->setPixmap( pixmap );
       
   261         }
       
   262     }
       
   263 }
       
   264 
       
   265 /*!
       
   266  * Private slot
       
   267  *
       
   268  */
       
   269 void RadioFrequencyStripBase::removeStation( const QModelIndex& parent, int first, int last )
       
   270 {
       
   271     Q_UNUSED( parent );
       
   272     updateStationsInRange( first, last, true );
       
   273 }
       
   274 
       
   275 /*!
       
   276  * Private slot
       
   277  *
       
   278  */
       
   279 void RadioFrequencyStripBase::updateStation( const QModelIndex& parent, int first, int last )
       
   280 {
       
   281     Q_UNUSED( parent );
       
   282     updateStationsInRange( first, last );
       
   283 }
       
   284 
       
   285 /*!
       
   286  * Private slot
       
   287  */
       
   288 void RadioFrequencyStripBase::handleLeftButton()
       
   289 {
       
   290     skipToPrevious();
       
   291 }
       
   292 
       
   293 /*!
       
   294  * Private slot
       
   295  */
       
   296 void RadioFrequencyStripBase::handleRightButton()
       
   297 {
       
   298     skipToNext();
       
   299 }
       
   300 
       
   301 /*!
       
   302  * Private slot
       
   303  */
       
   304 void RadioFrequencyStripBase::handleLongLeftButton()
       
   305 {
       
   306     seekDown();
       
   307 }
       
   308 
       
   309 /*!
       
   310  * Private slot
       
   311  */
       
   312 void RadioFrequencyStripBase::handleLongRightButton()
       
   313 {
       
   314     seekUp();
       
   315 }
       
   316 
       
   317 /*!
       
   318  * Private slot
       
   319  *
       
   320  */
       
   321 void RadioFrequencyStripBase::toggleManualSeek()
       
   322 {
       
   323     mManualSeekMode = !mManualSeekMode;
       
   324     emit manualSeekChanged( mManualSeekMode );
       
   325 
       
   326     if ( mManualSeekMode ) {
       
   327         grabMouse();
       
   328         hideButtons();
       
   329         mManualSeekTimerId = startTimer( FrequencyStrip::MANUALSEEK_SIGNAL_DELAY );
       
   330     } else {
       
   331         ungrabMouse();
       
   332         showButtons();
       
   333         killTimer( mManualSeekTimerId );
       
   334         mManualSeekTimerId = 0;
       
   335     }
       
   336 }
       
   337 
       
   338 /*!
       
   339  * Private slot
       
   340  */
       
   341 void RadioFrequencyStripBase::handleScrollingEnd()
       
   342 {
       
   343     // Check if the selector is in the invalid area where the strip loops around
       
   344     const int selectorPosition = selectorPos();
       
   345     if ( mManualSeekMode ) {
       
   346         if ( !mPositions.contains( selectorPosition ) ) {
       
   347             if ( selectorPosition < mMaxWidth - FrequencyStrip::ITEM_WIDTH + mSeparatorPos ) {
       
   348                 scrollToFrequency( mMaxFrequency, Scroll::Shortest, 500 );
       
   349                 emitFrequencyChanged( mMaxFrequency, FrequencyStrip::ManualSeekUpdate, Scroll::Shortest );
       
   350             } else {
       
   351                 scrollToFrequency( mMinFrequency, Scroll::Shortest, 500 );
       
   352                 emitFrequencyChanged( mMinFrequency, FrequencyStrip::ManualSeekUpdate, Scroll::Shortest );
       
   353             }
       
   354         }
       
   355 
       
   356         mManualSeekTimer->start( FrequencyStrip::MANUALSEEK_END_TIMEOUT );
       
   357     }
       
   358 }
       
   359 
       
   360 /*!
       
   361  * \reimp
       
   362  */
       
   363 void RadioFrequencyStripBase::updateItemPrimitive( QGraphicsItem* itemToUpdate, int itemIndex )
       
   364 {
       
   365     QGraphicsPixmapItem* item = static_cast<QGraphicsPixmapItem*>( itemToUpdate );
       
   366     if ( itemIndex < mFrequencyItems.count() ) {
       
   367         item->setPixmap( mFrequencyItems.at( itemIndex )->updatePrimitive( item ) );
       
   368     }
       
   369 }
       
   370 
       
   371 /*!
       
   372  * \reimp
       
   373  */
       
   374 QGraphicsItem* RadioFrequencyStripBase::createItemPrimitive( QGraphicsItem* parent )
       
   375 {
       
   376     return new QGraphicsPixmapItem( parent );
       
   377 }
       
   378 
       
   379 /*!
       
   380  * \reimp
       
   381  */
       
   382 void RadioFrequencyStripBase::scrollPosChanged()
       
   383 {
       
   384     if ( mManualSeekMode ) {
       
   385         const int pos = selectorPos();
       
   386         const uint frequency = mPositions.value( pos );
       
   387         if ( frequency > 0 ) {
       
   388             mFrequency = mPositions.value( pos );
       
   389             emitFrequencyChanged( mFrequency, FrequencyStrip::ManualSeekUpdate, Scroll::Shortest );
       
   390         }
       
   391     }
       
   392 }
       
   393 
       
   394 /*!
       
   395  * \reimp
       
   396  */
       
   397 void RadioFrequencyStripBase::resizeEvent ( QGraphicsSceneResizeEvent* event )
       
   398 {
       
   399     RadioStripBase::resizeEvent( event );
       
   400 
       
   401     initSelector();
       
   402 
       
   403     const qreal height = event->newSize().height();
       
   404     const qreal width = event->newSize().width();
       
   405 
       
   406     mSelectorPos = width / 2;
       
   407     mSelectorImage->setOffset( mSelectorPos - ( FrequencyStrip::INDICATOR_WIDTH / 2 ), 0.0 );
       
   408 
       
   409     if ( mLeftButton && mRightButton ) {
       
   410         mLeftButton->resize( height, height );
       
   411         mRightButton->resize( height, height );
       
   412         mRightButton->setPos( QPointF( width - height, 0 ) );
       
   413     }
       
   414 
       
   415     scrollToFrequency( mFrequency );
       
   416 }
       
   417 
       
   418 /*!
       
   419  * \reimp
       
   420  */
       
   421 void RadioFrequencyStripBase::changeEvent( QEvent* event )
       
   422 {
       
   423     if ( event->type() == HbEvent::ThemeChanged ) {
       
   424         // Update the foreground color and redraw each item
       
   425         mForegroundColor = Qt::white;// HbColorScheme::color( FrequencyStrip::TEXT_COLOR_ATTRIBUTE );
       
   426         updateAllItems();
       
   427     }
       
   428 
       
   429     return RadioStripBase::changeEvent(event);
       
   430 }
       
   431 
       
   432 /*!
       
   433  * \reimp
       
   434  */
       
   435 void RadioFrequencyStripBase::mousePressEvent( QGraphicsSceneMouseEvent* event )
       
   436 {
       
   437     RadioStripBase::mousePressEvent( event );
       
   438 
       
   439     mManualSeekTimer->stop();
       
   440     if ( mManualSeekMode ) {
       
   441         const bool insideStrip = rect().contains( event->pos() );
       
   442         if ( !insideStrip ) {
       
   443             toggleManualSeek();
       
   444         }
       
   445     } else {
       
   446         mManualSeekTimer->start( FrequencyStrip::MANUALSEEK_START_TIMEOUT );
       
   447     }
       
   448 }
       
   449 
       
   450 /*!
       
   451  * \reimp
       
   452  */
       
   453 void RadioFrequencyStripBase::mouseReleaseEvent( QGraphicsSceneMouseEvent* event )
       
   454 {
       
   455     RadioStripBase::mouseReleaseEvent( event );
       
   456 
       
   457     mManualSeekTimer->stop();
       
   458     if ( mManualSeekMode ) {
       
   459         mManualSeekTimer->start( FrequencyStrip::MANUALSEEK_END_TIMEOUT );
       
   460     }
       
   461 }
       
   462 
       
   463 /*!
       
   464  * \reimp
       
   465  */
       
   466 void RadioFrequencyStripBase::gestureEvent( QGestureEvent* event )
       
   467 {
       
   468     HbSwipeGesture* swipeGesture = static_cast<HbSwipeGesture*>( event->gesture( Qt::SwipeGesture ) );
       
   469     if ( swipeGesture && !mManualSeekMode ) {
       
   470         if ( swipeGesture->state() == Qt::GestureFinished ) {
       
   471             if ( swipeGesture->horizontalDirection() == QSwipeGesture::Left ) {
       
   472                 skipToNext();
       
   473             } else if ( swipeGesture->horizontalDirection() == QSwipeGesture::Right ) {
       
   474                 skipToPrevious();
       
   475             }
       
   476         }
       
   477     } else if ( mManualSeekMode ) {
       
   478         RadioStripBase::gestureEvent( event );
       
   479     }
       
   480 }
       
   481 
       
   482 /*!
       
   483  * \reimp
       
   484  */
       
   485 void RadioFrequencyStripBase::timerEvent( QTimerEvent* event )
       
   486 {
       
   487     Q_UNUSED( event );
       
   488     if ( mLastReportedFrequency != mFrequency ) {
       
   489         mLastReportedFrequency = mFrequency;
       
   490         emitFrequencyChanged( mFrequency, FrequencyStrip::ManualSeekTune, Scroll::Shortest );
       
   491     }
       
   492 }
       
   493 
       
   494 /*!
       
   495  *
       
   496  */
       
   497 void RadioFrequencyStripBase::initModel()
       
   498 {
       
   499     const uint minFreq = uint( qreal(mMinFrequency) / FrequencyStrip::ONE_HERTZ + FrequencyStrip::ROUNDER );
       
   500     const uint maxFreq = uint( qreal(mMaxFrequency) / FrequencyStrip::ONE_HERTZ + 0.9 ); // always round up
       
   501 
       
   502     QStringList list;
       
   503     QString freqText;
       
   504     for ( uint i = minFreq; i <= maxFreq; ++i ) {
       
   505         freqText = QString::number( i );
       
   506         list.append( freqText );
       
   507         mFrequencyItems.append( new RadioFrequencyItem( freqText ) );
       
   508     }
       
   509     mFrequencyItems.append( new RadioFrequencyItem( "" ) );
       
   510     list.append( "" );
       
   511 
       
   512     mMaxWidth = list.count() * FrequencyStrip::ITEM_WIDTH;
       
   513 
       
   514     mSeparatorPos = qreal(FrequencyStrip::ITEM_WIDTH) / 2;
       
   515     const uint minDrawableFreq = minFreq * FrequencyStrip::ONE_HERTZ - FrequencyStrip::HALF_HERTZ;;
       
   516     const uint maxDrawableFreq = maxFreq * FrequencyStrip::ONE_HERTZ + FrequencyStrip::HALF_HERTZ;
       
   517     mSeparatorPos += qreal( ( mMinFrequency  - minDrawableFreq ) / 2 ) / FrequencyStrip::PIXEL_IN_HZ;
       
   518     mSeparatorPos -= qreal( ( maxDrawableFreq - mMaxFrequency ) / 2 ) / FrequencyStrip::PIXEL_IN_HZ;
       
   519 
       
   520     setModel( new QStringListModel( list, this ) );
       
   521 }
       
   522 
       
   523 /*!
       
   524  *
       
   525  */
       
   526 void RadioFrequencyStripBase::initSelector()
       
   527 {
       
   528     QPixmap selectorPixmap = QPixmap( QSize( FrequencyStrip::SELECTOR_WIDTH, (int)size().height() ) );
       
   529     selectorPixmap.fill( Qt::red );
       
   530     mSelectorImage->setPixmap( selectorPixmap );
       
   531     mSelectorImage->setZValue( FrequencyStrip::SELECTOR_Z_POS );
       
   532 }
       
   533 
       
   534 /*!
       
   535  *
       
   536  */
       
   537 void RadioFrequencyStripBase::initPositions()
       
   538 {
       
   539     int prevPos = 0;
       
   540     int nextPos = 0;
       
   541     const int lastPos = mFrequencies.value( mMaxFrequency ).mPosition;
       
   542     for ( int i = mFrequencies.value( mMinFrequency ).mPosition; i < lastPos; ++i ) {
       
   543         if ( mPositions.contains( i ) ) {
       
   544             prevPos = i;
       
   545             const uint freq = mPositions.value( prevPos ) + mFrequencyStepSize;
       
   546             if ( mFrequencies.contains( freq ) ) {
       
   547                 nextPos = mFrequencies.value( freq ).mPosition;
       
   548             } else {
       
   549                 nextPos = prevPos;
       
   550             }
       
   551         } else {
       
   552             const int nearestHit = ( i - prevPos ) < ( nextPos - i ) ? prevPos : nextPos;
       
   553             mPositions.insert( i, mPositions.value( nearestHit ) );
       
   554         }
       
   555     }
       
   556 }
       
   557 
       
   558 /*!
       
   559  *
       
   560  */
       
   561 void RadioFrequencyStripBase::initButtons()
       
   562 {
       
   563     Q_ASSERT( mLeftButton && mRightButton );
       
   564     connectAndCheck( mLeftButton,    SIGNAL(clicked()),
       
   565                      this,           SLOT(handleLeftButton()) );
       
   566     connectAndCheck( mRightButton,   SIGNAL(clicked()),
       
   567                      this,           SLOT(handleRightButton()) );
       
   568     connectAndCheck( mLeftButton,    SIGNAL(longPress(QPointF)),
       
   569                      this,           SLOT(handleLongLeftButton()) );
       
   570     connectAndCheck( mRightButton,   SIGNAL(longPress(QPointF)),
       
   571                      this,           SLOT(handleLongRightButton()) );
       
   572 
       
   573     mLeftButton->setZValue( FrequencyStrip::SELECTOR_Z_POS );
       
   574     mLeftButton->setObjectName( FrequencyStrip::LEFT_BUTTON );
       
   575     mRightButton->setZValue( FrequencyStrip::SELECTOR_Z_POS );
       
   576     mRightButton->setObjectName( FrequencyStrip::RIGHT_BUTTON );
       
   577 
       
   578     const qreal height = size().height();
       
   579     const qreal width = size().width();
       
   580     mLeftButton->resize( height, height );
       
   581     mRightButton->resize( height, height );
       
   582     mRightButton->setPos( QPointF( width - height, 0 ) );
       
   583 
       
   584     // Add left button effects
       
   585     QStringList pathList;
       
   586     pathList << ":/effects/slide_to_left.fxml" << ":/effects/slide_from_left.fxml";
       
   587     QStringList eventList;
       
   588     eventList << FrequencyStrip::SLIDE_TO_LEFT << FrequencyStrip::SLIDE_FROM_LEFT;
       
   589     HbEffect::add( mLeftButton, pathList, eventList );
       
   590 
       
   591     // Add right button effects
       
   592     pathList.clear();
       
   593     pathList << ":/effects/slide_to_right.fxml" << ":/effects/slide_from_right.fxml";
       
   594     eventList.clear();
       
   595     eventList << FrequencyStrip::SLIDE_TO_RIGHT << FrequencyStrip::SLIDE_FROM_RIGHT;
       
   596     HbEffect::add( mRightButton, pathList, eventList );
       
   597 }
       
   598 
       
   599 /*!
       
   600  *
       
   601  */
       
   602 void RadioFrequencyStripBase::addFrequencyPos( int pos, uint frequency, RadioFrequencyItem* item )
       
   603 {
       
   604     mFrequencies.insert( frequency, FrequencyPos( pos, item ) );
       
   605     mPositions.insert( pos, frequency );
       
   606 }
       
   607 
       
   608 /*!
       
   609  *
       
   610  */
       
   611 void RadioFrequencyStripBase::updateStationsInRange( int first, int last, bool stationRemoved )
       
   612 {
       
   613     if ( !isScanning() ) {
       
   614         uint frequency = 0;
       
   615         for ( int i = first; i <= last; ++i ) {
       
   616             frequency = frequencyAtIndex( i );
       
   617             if ( mFrequencies.contains( frequency ) ) {
       
   618                 FrequencyPos pos = mFrequencies.value( frequency );
       
   619                 updateItem( pos.mItem, 0, stationRemoved ? frequency : 0 );
       
   620             }
       
   621         }
       
   622     }
       
   623 }
       
   624 
       
   625 /*!
       
   626  *
       
   627  */
       
   628 void RadioFrequencyStripBase::updateItem( RadioFrequencyItem* item, uint upperRange, uint ignoredFrequency )
       
   629 {
       
   630     if ( item ) {
       
   631         uint frequency = item->frequency();
       
   632         QList<FrequencyStrip::StationMarker> markers;
       
   633 
       
   634         if ( upperRange == 0 ) {
       
   635             upperRange = frequency + FrequencyStrip::HALF_HERTZ;
       
   636         }
       
   637 
       
   638         if ( isInitialized() ) {
       
   639             markers = stationsInRange( frequency - FrequencyStrip::HALF_HERTZ, upperRange );
       
   640             for ( int i = markers.count() - 1; ignoredFrequency > 0 && i >= 0; --i ) {
       
   641                 if ( markers[i].mFrequency == ignoredFrequency ) {
       
   642                     markers.removeAt( i );
       
   643                     break;
       
   644                 }
       
   645             }
       
   646         }
       
   647 
       
   648         QPixmap pixmap = drawPixmap( frequency, markers, item );
       
   649         item->setPixmap( pixmap );
       
   650 
       
   651         foreach ( const FrequencyStrip::StationMarker& marker, markers ) {
       
   652             FrequencyPos pos = mFrequencies.value( marker.mFrequency );
       
   653             mFrequencies.insert( marker.mFrequency, pos );
       
   654         }
       
   655     }
       
   656 }
       
   657 
       
   658 /*!
       
   659  *
       
   660  */
       
   661 void RadioFrequencyStripBase::updateAllItems()
       
   662 {
       
   663     foreach ( RadioFrequencyItem* item, mFrequencyItems ) {
       
   664         updateItem( item );
       
   665     }
       
   666 }
       
   667 
       
   668 /*!
       
   669  *
       
   670  */
       
   671 QPixmap RadioFrequencyStripBase::drawPixmap( uint frequency, QList<FrequencyStrip::StationMarker> stations, RadioFrequencyItem* item )
       
   672 {
       
   673     QPixmap pixmap( FrequencyStrip::PIXMAP_WIDTH, mItemHeight );
       
   674     pixmap.fill( Qt::transparent );
       
   675     QPainter painter( &pixmap );
       
   676     QPen normalPen = painter.pen();
       
   677     QPen favoritePen = normalPen;
       
   678     normalPen.setColor( mForegroundColor );
       
   679     painter.setPen( normalPen );
       
   680 
       
   681     if ( frequency == 0 ) {
       
   682         painter.drawLine( makeTab( mSeparatorPos - 1 + FrequencyStrip::ROUNDER, mItemHeight ) );
       
   683         painter.drawLine( makeTab( mSeparatorPos + FrequencyStrip::ROUNDER, mItemHeight ) );
       
   684         return pixmap;
       
   685     }
       
   686 
       
   687     const QString itemText = QString::number( frequency / FrequencyStrip::ONE_HERTZ );
       
   688     const uint startFrequency = frequency - FrequencyStrip::HALF_HERTZ;
       
   689     const uint endFrequency = startFrequency + FrequencyStrip::ONE_HERTZ;
       
   690     const uint  roundedMin = int( qreal(mMinFrequency) / FrequencyStrip::ONE_HERTZ + FrequencyStrip::ROUNDER );
       
   691     const uint freq = frequency / FrequencyStrip::ONE_HERTZ;
       
   692     const int diff = freq - roundedMin;
       
   693     const qreal startPixel = diff * FrequencyStrip::ITEM_WIDTH;
       
   694     qreal pixels = 0.0;
       
   695     const qreal leftOverlap = FrequencyStrip::PIXMAP_OVERLAP / 2;
       
   696 
       
   697     for ( uint frequency = startFrequency; frequency <= endFrequency; frequency += mFrequencyStepSize ) {
       
   698 
       
   699         if ( frequency < mMinFrequency || frequency > mMaxFrequency ) {
       
   700             continue;
       
   701         }
       
   702 
       
   703         pixels = qreal( frequency - startFrequency ) / FrequencyStrip::PIXEL_IN_HZ;
       
   704         if ( frequency % FrequencyStrip::ONE_HERTZ == 0 ) {
       
   705 
       
   706             // Draw the high frequency tab and the frequency text for the even number
       
   707             normalPen.setWidth( 3 );
       
   708             painter.setPen( normalPen );
       
   709             painter.drawLine( makeTab( pixels + leftOverlap - 1, FrequencyStrip::TAB_HEIGHT_BIG ) );
       
   710             normalPen.setWidth( 1 );
       
   711             painter.setPen( normalPen );
       
   712 
       
   713             // Draw the frequency text and its 00 decimals
       
   714             painter.setFont( FrequencyStrip::DECIMAL_FONT );
       
   715             const int decimalWidth = painter.fontMetrics().width( FrequencyStrip::DECIMAL_TEXT );
       
   716             const int decimalSpace = painter.fontMetrics().leftBearing( '.' );
       
   717             painter.setFont( FrequencyStrip::FREQUENCY_FONT );
       
   718             const int frequencyWidth = painter.fontMetrics().width( itemText );
       
   719             const int textPosX = int( pixels + leftOverlap - ( frequencyWidth + decimalSpace + decimalWidth ) / 2 );
       
   720             painter.drawText( QPoint( textPosX, FrequencyStrip::FREQUENCY_TEXT_Y_POS ), itemText );
       
   721             painter.setFont( FrequencyStrip::DECIMAL_FONT );
       
   722             painter.drawText( QPoint( textPosX + frequencyWidth + decimalSpace, FrequencyStrip::FREQUENCY_TEXT_Y_POS ), FrequencyStrip::DECIMAL_TEXT );
       
   723 
       
   724         } else if ( frequency % FrequencyStrip::ONE_TAB_IN_HZ == 0 ) {
       
   725 
       
   726             // Draw the low frequency tab for the uneven number
       
   727             painter.drawLine( makeTab( pixels + leftOverlap, FrequencyStrip::TAB_HEIGHT_SMALL ) );
       
   728 
       
   729         }
       
   730 
       
   731         addFrequencyPos( int( startPixel + pixels + FrequencyStrip::ROUNDER ), frequency, item );
       
   732     }
       
   733 
       
   734     // Draw favorites and local stations
       
   735     favoritePen.setColor( Qt::yellow );
       
   736 
       
   737     foreach ( const FrequencyStrip::StationMarker& station, stations ) {
       
   738         const uint frequency = station.mFrequency;
       
   739         pixels = qreal( frequency - startFrequency ) / FrequencyStrip::PIXEL_IN_HZ;
       
   740 
       
   741         if ( station.mIsFavorite ) {
       
   742             favoritePen.setWidth( FrequencyStrip::PEN_WIDTH_FAVORITE );
       
   743             painter.setPen( favoritePen );
       
   744             painter.drawEllipse( int( pixels + leftOverlap - 3 ), FrequencyStrip::STATION_MARKER_Y_POS - 3, 6, 6 );
       
   745         } else {
       
   746             favoritePen.setWidth( 1 );
       
   747             painter.setPen( favoritePen );
       
   748             painter.drawEllipse( int( pixels + leftOverlap - 4 ), FrequencyStrip::STATION_MARKER_Y_POS - 4, 8, 8 );
       
   749         }
       
   750     }
       
   751 
       
   752     return pixmap;
       
   753 }
       
   754 
       
   755 /*!
       
   756  *
       
   757  */
       
   758 QLineF RadioFrequencyStripBase::makeTab( qreal pos, int height )
       
   759 {
       
   760     return QLineF( pos, mItemHeight - height, pos, mItemHeight );
       
   761 }
       
   762 
       
   763 /*!
       
   764  *
       
   765  */
       
   766 int RadioFrequencyStripBase::selectorPos() const
       
   767 {
       
   768     const int pos = int( -contentWidget()->x() + mSelectorPos + FrequencyStrip::ROUNDER );
       
   769     return pos % mMaxWidth;
       
   770 }
       
   771 
       
   772 /*!
       
   773  *
       
   774  */
       
   775 void RadioFrequencyStripBase::scrollToFrequency( uint frequency, Scroll::Direction direction, int time )
       
   776 {
       
   777     int targetFreqPos = mFrequencies.value( frequency ).mPosition;
       
   778     const int currentFreqPos = mFrequencies.value( mFrequency ).mPosition;
       
   779     const int currentPos = int( -contentWidget()->x() + mSelectorPos + FrequencyStrip::ROUNDER );
       
   780     const bool isInSecondHalf = currentPos >= mMaxWidth - FrequencyStrip::ITEM_WIDTH + mSeparatorPos;
       
   781 
       
   782     // Special case: When there is only one favorite and the user presses skip
       
   783     // the strip must scroll around to the same frequency.
       
   784     if ( mFrequency == frequency && direction != Scroll::Shortest ) {
       
   785         if ( direction == Scroll::Left ) {
       
   786             targetFreqPos += mMaxWidth;
       
   787         } else {
       
   788             targetFreqPos -= mMaxWidth;
       
   789         }
       
   790     }
       
   791 
       
   792     mFrequency = frequency;
       
   793 
       
   794     qreal newPos = targetFreqPos;
       
   795     if ( direction == Scroll::Left ) {
       
   796 
       
   797         if ( currentFreqPos > targetFreqPos ) {
       
   798             newPos += mMaxWidth;
       
   799         }
       
   800 
       
   801     } else if ( direction == Scroll::Right ) {
       
   802 
       
   803         if ( currentFreqPos < targetFreqPos ) {
       
   804             newPos -= mMaxWidth;
       
   805         }
       
   806 
       
   807     }
       
   808 
       
   809     if ( isInSecondHalf ) {
       
   810         newPos += mMaxWidth;
       
   811     }
       
   812 
       
   813     newPos -= mSelectorPos - FrequencyStrip::ROUNDER;
       
   814 
       
   815 //    scrollContentsTo( QPointF( newPos, 0 ), time );
       
   816 // TODO: Remove this and uncomment the above line. This is a temporary workaround to get the strip to move
       
   817     scrollContentsTo( QPointF( newPos, 0 ), 0 );
       
   818 }
       
   819 
       
   820 /*!
       
   821  *
       
   822  */
       
   823 void RadioFrequencyStripBase::hideButtons()
       
   824 {
       
   825     HbEffect::start( mLeftButton, FrequencyStrip::SLIDE_TO_LEFT );
       
   826     HbEffect::start( mRightButton, FrequencyStrip::SLIDE_TO_RIGHT );
       
   827 }
       
   828 
       
   829 /*!
       
   830  *
       
   831  */
       
   832 void RadioFrequencyStripBase::showButtons()
       
   833 {
       
   834     HbEffect::start( mLeftButton, FrequencyStrip::SLIDE_FROM_LEFT );
       
   835     HbEffect::start( mRightButton, FrequencyStrip::SLIDE_FROM_RIGHT );
       
   836 }