demos/qmediaplayer/mediaplayer.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (qt-info@nokia.com)
       
     6 **
       
     7 ** This file is part of the demonstration applications of the Qt Toolkit.
       
     8 **
       
     9 ** $QT_BEGIN_LICENSE:LGPL$
       
    10 ** No Commercial Usage
       
    11 ** This file contains pre-release code and may not be distributed.
       
    12 ** You may use this file in accordance with the terms and conditions
       
    13 ** contained in the Technology Preview License Agreement accompanying
       
    14 ** this package.
       
    15 **
       
    16 ** GNU Lesser General Public License Usage
       
    17 ** Alternatively, this file may be used under the terms of the GNU Lesser
       
    18 ** General Public License version 2.1 as published by the Free Software
       
    19 ** Foundation and appearing in the file LICENSE.LGPL included in the
       
    20 ** packaging of this file.  Please review the following information to
       
    21 ** ensure the GNU Lesser General Public License version 2.1 requirements
       
    22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    23 **
       
    24 ** In addition, as a special exception, Nokia gives you certain additional
       
    25 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    27 **
       
    28 ** If you have questions regarding the use of this file, please contact
       
    29 ** Nokia at qt-info@nokia.com.
       
    30 **
       
    31 **
       
    32 **
       
    33 **
       
    34 **
       
    35 **
       
    36 **
       
    37 **
       
    38 ** $QT_END_LICENSE$
       
    39 **
       
    40 ***************************************************************************/
       
    41 
       
    42 #include <QtGui>
       
    43 
       
    44 #define SLIDER_RANGE 8
       
    45 
       
    46 #include "mediaplayer.h"
       
    47 #include "ui_settings.h"
       
    48 
       
    49 
       
    50 class MediaVideoWidget : public Phonon::VideoWidget
       
    51 {
       
    52 public:
       
    53     MediaVideoWidget(MediaPlayer *player, QWidget *parent = 0) : 
       
    54         Phonon::VideoWidget(parent), m_player(player), m_action(this)
       
    55     {
       
    56         m_action.setCheckable(true);
       
    57         m_action.setChecked(false);
       
    58         m_action.setShortcut(QKeySequence( Qt::AltModifier + Qt::Key_Return));
       
    59         m_action.setShortcutContext(Qt::WindowShortcut);
       
    60         connect(&m_action, SIGNAL(toggled(bool)), SLOT(setFullScreen(bool)));
       
    61         addAction(&m_action);
       
    62         setAcceptDrops(true);
       
    63     }
       
    64 
       
    65 protected:
       
    66     void mouseDoubleClickEvent(QMouseEvent *e)
       
    67     {
       
    68         Phonon::VideoWidget::mouseDoubleClickEvent(e);
       
    69         setFullScreen(!isFullScreen());
       
    70     }
       
    71 
       
    72     void keyPressEvent(QKeyEvent *e)
       
    73     {
       
    74         if (e->key() == Qt::Key_Space && !e->modifiers()) {
       
    75             m_player->playPause();
       
    76             e->accept();
       
    77             return;
       
    78         } else if (e->key() == Qt::Key_Escape && !e->modifiers()) {
       
    79             setFullScreen(false);
       
    80             e->accept();
       
    81             return;
       
    82         }
       
    83         Phonon::VideoWidget::keyPressEvent(e);        
       
    84     }
       
    85 
       
    86     bool event(QEvent *e)
       
    87     {
       
    88         switch(e->type())
       
    89         {
       
    90         case QEvent::Close:
       
    91             //we just ignore the cose events on the video widget
       
    92             //this prevents ALT+F4 from having an effect in fullscreen mode
       
    93             e->ignore(); 
       
    94             return true;
       
    95         case QEvent::MouseMove:
       
    96 #ifndef QT_NO_CURSOR
       
    97             unsetCursor();
       
    98 #endif
       
    99             //fall through
       
   100         case QEvent::WindowStateChange:
       
   101             {
       
   102                 //we just update the state of the checkbox, in case it wasn't already
       
   103                 m_action.setChecked(windowState() & Qt::WindowFullScreen);
       
   104                 const Qt::WindowFlags flags = m_player->windowFlags();
       
   105                 if (windowState() & Qt::WindowFullScreen) {
       
   106                     m_timer.start(1000, this);
       
   107                 } else {
       
   108                     m_timer.stop();
       
   109 #ifndef QT_NO_CURSOR
       
   110                     unsetCursor();
       
   111 #endif
       
   112                 }
       
   113             }
       
   114             break;
       
   115         default:
       
   116             break;
       
   117         }
       
   118 
       
   119         return Phonon::VideoWidget::event(e);
       
   120     }
       
   121 
       
   122     void timerEvent(QTimerEvent *e)
       
   123     {
       
   124         if (e->timerId() == m_timer.timerId()) {
       
   125             //let's store the cursor shape
       
   126 #ifndef QT_NO_CURSOR
       
   127             setCursor(Qt::BlankCursor);
       
   128 #endif
       
   129         }
       
   130         Phonon::VideoWidget::timerEvent(e);
       
   131     }
       
   132 
       
   133     void dropEvent(QDropEvent *e)
       
   134     {
       
   135         m_player->handleDrop(e);
       
   136     }
       
   137 
       
   138     void dragEnterEvent(QDragEnterEvent *e) {
       
   139         if (e->mimeData()->hasUrls())
       
   140             e->acceptProposedAction();
       
   141     }
       
   142 
       
   143 private:
       
   144     MediaPlayer *m_player;
       
   145     QBasicTimer m_timer;
       
   146     QAction m_action;
       
   147 };
       
   148 
       
   149 
       
   150 MediaPlayer::MediaPlayer(const QString &filePath,
       
   151                          const bool hasSmallScreen) :
       
   152         playButton(0), nextEffect(0), settingsDialog(0), ui(0), 
       
   153             m_AudioOutput(Phonon::VideoCategory),
       
   154             m_videoWidget(new MediaVideoWidget(this)),
       
   155             m_hasSmallScreen(hasSmallScreen)
       
   156 {
       
   157     setWindowTitle(tr("Media Player"));
       
   158     setContextMenuPolicy(Qt::CustomContextMenu);
       
   159     m_videoWidget->setContextMenuPolicy(Qt::CustomContextMenu);
       
   160  
       
   161     QSize buttonSize(34, 28);
       
   162 
       
   163     QPushButton *openButton = new QPushButton(this);
       
   164 
       
   165     openButton->setIcon(style()->standardIcon(QStyle::SP_DialogOpenButton));
       
   166     QPalette bpal;
       
   167     QColor arrowcolor = bpal.buttonText().color();
       
   168     if (arrowcolor == Qt::black)
       
   169         arrowcolor = QColor(80, 80, 80);
       
   170     bpal.setBrush(QPalette::ButtonText, arrowcolor);
       
   171     openButton->setPalette(bpal);
       
   172 
       
   173     rewindButton = new QPushButton(this);
       
   174     rewindButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
       
   175 
       
   176     forwardButton = new QPushButton(this);
       
   177     forwardButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward));
       
   178     forwardButton->setEnabled(false);
       
   179 
       
   180     playButton = new QPushButton(this);
       
   181     playIcon = style()->standardIcon(QStyle::SP_MediaPlay);
       
   182     pauseIcon = style()->standardIcon(QStyle::SP_MediaPause);
       
   183     playButton->setIcon(playIcon);
       
   184 
       
   185     slider = new Phonon::SeekSlider(this);
       
   186     slider->setMediaObject(&m_MediaObject);
       
   187     volume = new Phonon::VolumeSlider(&m_AudioOutput);
       
   188  
       
   189     QVBoxLayout *vLayout = new QVBoxLayout(this);
       
   190     vLayout->setContentsMargins(8, 8, 8, 8);    
       
   191 
       
   192     QHBoxLayout *layout = new QHBoxLayout();
       
   193 
       
   194     info = new QLabel(this);
       
   195     info->setMinimumHeight(70);
       
   196     info->setAcceptDrops(false);
       
   197     info->setMargin(2);
       
   198     info->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
       
   199     info->setLineWidth(2);
       
   200     info->setAutoFillBackground(true);
       
   201 
       
   202     QPalette palette;
       
   203     palette.setBrush(QPalette::WindowText, Qt::white);
       
   204 #ifndef Q_WS_MAC
       
   205     openButton->setMinimumSize(54, buttonSize.height());
       
   206     rewindButton->setMinimumSize(buttonSize);
       
   207     forwardButton->setMinimumSize(buttonSize);
       
   208     playButton->setMinimumSize(buttonSize);
       
   209 #endif
       
   210     info->setStyleSheet("border-image:url(:/images/screen.png) ; border-width:3px");
       
   211     info->setPalette(palette);
       
   212     info->setText(tr("<center>No media</center>"));
       
   213 
       
   214     volume->setFixedWidth(120);
       
   215 
       
   216     layout->addWidget(openButton);
       
   217     layout->addWidget(rewindButton);
       
   218     layout->addWidget(playButton);
       
   219     layout->addWidget(forwardButton);
       
   220 
       
   221     layout->addStretch();
       
   222     layout->addWidget(volume);
       
   223 
       
   224     vLayout->addWidget(info);
       
   225     initVideoWindow();
       
   226     vLayout->addWidget(&m_videoWindow);
       
   227     QVBoxLayout *buttonPanelLayout = new QVBoxLayout();
       
   228     m_videoWindow.hide();
       
   229     buttonPanelLayout->addLayout(layout);
       
   230     
       
   231     timeLabel = new QLabel(this);
       
   232     progressLabel = new QLabel(this);
       
   233     QWidget *sliderPanel = new QWidget(this);
       
   234     QHBoxLayout *sliderLayout = new QHBoxLayout();
       
   235     sliderLayout->addWidget(slider);
       
   236     sliderLayout->addWidget(timeLabel);    
       
   237     sliderLayout->addWidget(progressLabel);    
       
   238     sliderLayout->setContentsMargins(0, 0, 0, 0);
       
   239     sliderPanel->setLayout(sliderLayout);
       
   240 
       
   241     buttonPanelLayout->addWidget(sliderPanel);
       
   242     buttonPanelLayout->setContentsMargins(0, 0, 0, 0);
       
   243 #ifdef Q_OS_MAC
       
   244     layout->setSpacing(4);
       
   245     buttonPanelLayout->setSpacing(0);
       
   246     info->setMinimumHeight(100);
       
   247     info->setFont(QFont("verdana", 15));
       
   248     // QStyle *flatButtonStyle = new QWindowsStyle;
       
   249     openButton->setFocusPolicy(Qt::NoFocus);
       
   250     // openButton->setStyle(flatButtonStyle);
       
   251     // playButton->setStyle(flatButtonStyle);
       
   252     // rewindButton->setStyle(flatButtonStyle);
       
   253     // forwardButton->setStyle(flatButtonStyle);
       
   254  #endif
       
   255     QWidget *buttonPanelWidget = new QWidget(this);
       
   256     buttonPanelWidget->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed); 
       
   257     buttonPanelWidget->setLayout(buttonPanelLayout);    
       
   258     vLayout->addWidget(buttonPanelWidget);
       
   259  
       
   260     QHBoxLayout *labelLayout = new QHBoxLayout();
       
   261 
       
   262     vLayout->addLayout(labelLayout);
       
   263     setLayout(vLayout);
       
   264 
       
   265     // Create menu bar:
       
   266     fileMenu = new QMenu(this);
       
   267     QAction *openFileAction = fileMenu->addAction(tr("Open &File..."));
       
   268     QAction *openUrlAction = fileMenu->addAction(tr("Open &Location..."));
       
   269 
       
   270     fileMenu->addSeparator();  
       
   271     QMenu *aspectMenu = fileMenu->addMenu(tr("&Aspect ratio"));
       
   272     QActionGroup *aspectGroup = new QActionGroup(aspectMenu);
       
   273     connect(aspectGroup, SIGNAL(triggered(QAction *)), this, SLOT(aspectChanged(QAction *)));
       
   274     aspectGroup->setExclusive(true);
       
   275     QAction *aspectActionAuto = aspectMenu->addAction(tr("Auto"));
       
   276     aspectActionAuto->setCheckable(true);
       
   277     aspectActionAuto->setChecked(true);
       
   278     aspectGroup->addAction(aspectActionAuto);
       
   279     QAction *aspectActionScale = aspectMenu->addAction(tr("Scale"));
       
   280     aspectActionScale->setCheckable(true);
       
   281     aspectGroup->addAction(aspectActionScale);
       
   282     QAction *aspectAction16_9 = aspectMenu->addAction(tr("16/9"));
       
   283     aspectAction16_9->setCheckable(true);
       
   284     aspectGroup->addAction(aspectAction16_9);
       
   285     QAction *aspectAction4_3 = aspectMenu->addAction(tr("4/3"));
       
   286     aspectAction4_3->setCheckable(true);
       
   287     aspectGroup->addAction(aspectAction4_3);
       
   288 
       
   289     QMenu *scaleMenu = fileMenu->addMenu(tr("&Scale mode"));
       
   290     QActionGroup *scaleGroup = new QActionGroup(scaleMenu);
       
   291     connect(scaleGroup, SIGNAL(triggered(QAction *)), this, SLOT(scaleChanged(QAction *)));
       
   292     scaleGroup->setExclusive(true);
       
   293     QAction *scaleActionFit = scaleMenu->addAction(tr("Fit in view"));
       
   294     scaleActionFit->setCheckable(true);
       
   295     scaleActionFit->setChecked(true);
       
   296     scaleGroup->addAction(scaleActionFit);
       
   297     QAction *scaleActionCrop = scaleMenu->addAction(tr("Scale and crop"));
       
   298     scaleActionCrop->setCheckable(true);
       
   299     scaleGroup->addAction(scaleActionCrop);
       
   300     
       
   301     fileMenu->addSeparator();    
       
   302     QAction *settingsAction = fileMenu->addAction(tr("&Settings..."));
       
   303     
       
   304     // Setup signal connections:
       
   305     connect(rewindButton, SIGNAL(clicked()), this, SLOT(rewind()));
       
   306     //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));
       
   307     openButton->setMenu(fileMenu);
       
   308     
       
   309     connect(playButton, SIGNAL(clicked()), this, SLOT(playPause()));
       
   310     connect(forwardButton, SIGNAL(clicked()), this, SLOT(forward()));
       
   311     //connect(openButton, SIGNAL(clicked()), this, SLOT(openFile()));
       
   312     connect(settingsAction, SIGNAL(triggered(bool)), this, SLOT(showSettingsDialog()));
       
   313     connect(openUrlAction, SIGNAL(triggered(bool)), this, SLOT(openUrl()));
       
   314     connect(openFileAction, SIGNAL(triggered(bool)), this, SLOT(openFile()));
       
   315     
       
   316     connect(m_videoWidget, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
       
   317     connect(this, SIGNAL(customContextMenuRequested(const QPoint &)), SLOT(showContextMenu(const QPoint &)));
       
   318     connect(&m_MediaObject, SIGNAL(metaDataChanged()), this, SLOT(updateInfo()));
       
   319     connect(&m_MediaObject, SIGNAL(totalTimeChanged(qint64)), this, SLOT(updateTime()));
       
   320     connect(&m_MediaObject, SIGNAL(tick(qint64)), this, SLOT(updateTime()));
       
   321     connect(&m_MediaObject, SIGNAL(finished()), this, SLOT(finished()));
       
   322     connect(&m_MediaObject, SIGNAL(stateChanged(Phonon::State, Phonon::State)), this, SLOT(stateChanged(Phonon::State, Phonon::State)));
       
   323     connect(&m_MediaObject, SIGNAL(bufferStatus(int)), this, SLOT(bufferStatus(int)));
       
   324     connect(&m_MediaObject, SIGNAL(hasVideoChanged(bool)), this, SLOT(hasVideoChanged(bool)));
       
   325 
       
   326     rewindButton->setEnabled(false);
       
   327     playButton->setEnabled(false);
       
   328     setAcceptDrops(true);
       
   329 
       
   330     m_audioOutputPath = Phonon::createPath(&m_MediaObject, &m_AudioOutput);
       
   331     Phonon::createPath(&m_MediaObject, m_videoWidget);
       
   332 
       
   333     if (!filePath.isEmpty())
       
   334         setFile(filePath);
       
   335     resize(minimumSizeHint());
       
   336 }
       
   337 
       
   338 void MediaPlayer::stateChanged(Phonon::State newstate, Phonon::State oldstate)
       
   339 {
       
   340     Q_UNUSED(oldstate);
       
   341 
       
   342     if (oldstate == Phonon::LoadingState) {
       
   343         QRect videoHintRect = QRect(QPoint(0, 0), m_videoWindow.sizeHint());
       
   344         QRect newVideoRect = QApplication::desktop()->screenGeometry().intersected(videoHintRect);
       
   345         if (!m_hasSmallScreen) {
       
   346             if (m_MediaObject.hasVideo()) {
       
   347                 // Flush event que so that sizeHint takes the
       
   348                 // recently shown/hidden m_videoWindow into account:
       
   349                 qApp->processEvents();
       
   350                 resize(sizeHint());
       
   351             } else
       
   352                 resize(minimumSize());
       
   353         }
       
   354     }
       
   355 
       
   356     switch (newstate) {
       
   357         case Phonon::ErrorState:
       
   358             QMessageBox::warning(this, "Phonon Mediaplayer", m_MediaObject.errorString(), QMessageBox::Close);
       
   359             if (m_MediaObject.errorType() == Phonon::FatalError) {
       
   360                 playButton->setEnabled(false);
       
   361                 rewindButton->setEnabled(false);
       
   362             } else {
       
   363                 m_MediaObject.pause();
       
   364             }
       
   365             break;
       
   366         case Phonon::PausedState:
       
   367         case Phonon::StoppedState:
       
   368             playButton->setIcon(playIcon);
       
   369 
       
   370             m_videoWidget->setFullScreen(false);
       
   371 
       
   372             if (m_MediaObject.currentSource().type() != Phonon::MediaSource::Invalid){
       
   373                 playButton->setEnabled(true);
       
   374                 rewindButton->setEnabled(true);
       
   375             } else {
       
   376                 playButton->setEnabled(false);
       
   377                 rewindButton->setEnabled(false);
       
   378             }
       
   379             break;
       
   380         case Phonon::PlayingState:
       
   381             playButton->setEnabled(true);
       
   382             playButton->setIcon(pauseIcon);
       
   383             if (m_MediaObject.hasVideo())
       
   384                 m_videoWindow.show();
       
   385             // Fall through
       
   386         case Phonon::BufferingState:
       
   387             rewindButton->setEnabled(true);
       
   388             break;
       
   389         case Phonon::LoadingState:
       
   390             rewindButton->setEnabled(false);
       
   391             break;
       
   392     }
       
   393 
       
   394 }
       
   395 
       
   396 void MediaPlayer::initSettingsDialog()
       
   397 {
       
   398     settingsDialog = new QDialog(this);
       
   399     ui = new Ui_settings();
       
   400     ui->setupUi(settingsDialog);
       
   401 
       
   402     connect(ui->brightnessSlider, SIGNAL(valueChanged(int)), this, SLOT(setBrightness(int)));
       
   403     connect(ui->hueSlider, SIGNAL(valueChanged(int)), this, SLOT(setHue(int)));
       
   404     connect(ui->saturationSlider, SIGNAL(valueChanged(int)), this, SLOT(setSaturation(int)));
       
   405     connect(ui->contrastSlider , SIGNAL(valueChanged(int)), this, SLOT(setContrast(int)));
       
   406     connect(ui->aspectCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setAspect(int)));
       
   407     connect(ui->scalemodeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setScale(int)));
       
   408 
       
   409     ui->brightnessSlider->setValue(int(m_videoWidget->brightness() * SLIDER_RANGE));
       
   410     ui->hueSlider->setValue(int(m_videoWidget->hue() * SLIDER_RANGE));
       
   411     ui->saturationSlider->setValue(int(m_videoWidget->saturation() * SLIDER_RANGE));
       
   412     ui->contrastSlider->setValue(int(m_videoWidget->contrast() * SLIDER_RANGE));
       
   413     ui->aspectCombo->setCurrentIndex(m_videoWidget->aspectRatio());
       
   414     ui->scalemodeCombo->setCurrentIndex(m_videoWidget->scaleMode());
       
   415     connect(ui->effectButton, SIGNAL(clicked()), this, SLOT(configureEffect()));
       
   416 
       
   417 #ifdef Q_WS_X11
       
   418     //Cross fading is not currently implemented in the GStreamer backend
       
   419     ui->crossFadeSlider->setVisible(false);
       
   420     ui->crossFadeLabel->setVisible(false);
       
   421     ui->crossFadeLabel1->setVisible(false);
       
   422     ui->crossFadeLabel2->setVisible(false);
       
   423     ui->crossFadeLabel3->setVisible(false);
       
   424 #endif
       
   425     ui->crossFadeSlider->setValue((int)(2 * m_MediaObject.transitionTime() / 1000.0f));
       
   426     
       
   427     // Insert audio devices:
       
   428     QList<Phonon::AudioOutputDevice> devices = Phonon::BackendCapabilities::availableAudioOutputDevices();
       
   429     for (int i=0; i<devices.size(); i++){
       
   430         QString itemText = devices[i].name();
       
   431         if (!devices[i].description().isEmpty()) {
       
   432             itemText += QString::fromLatin1(" (%1)").arg(devices[i].description());
       
   433         }
       
   434         ui->deviceCombo->addItem(itemText);
       
   435         if (devices[i] == m_AudioOutput.outputDevice())
       
   436             ui->deviceCombo->setCurrentIndex(i);
       
   437     }
       
   438 
       
   439     // Insert audio effects:
       
   440     ui->audioEffectsCombo->addItem(tr("<no effect>"));
       
   441     QList<Phonon::Effect *> currEffects = m_audioOutputPath.effects();
       
   442     Phonon::Effect *currEffect = currEffects.size() ? currEffects[0] : 0;
       
   443     QList<Phonon::EffectDescription> availableEffects = Phonon::BackendCapabilities::availableAudioEffects();
       
   444     for (int i=0; i<availableEffects.size(); i++){
       
   445         ui->audioEffectsCombo->addItem(availableEffects[i].name());
       
   446         if (currEffect && availableEffects[i] == currEffect->description())
       
   447             ui->audioEffectsCombo->setCurrentIndex(i+1);
       
   448     }
       
   449     connect(ui->audioEffectsCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(effectChanged()));
       
   450 
       
   451 }
       
   452 
       
   453 void MediaPlayer::effectChanged()
       
   454 {
       
   455     int currentIndex = ui->audioEffectsCombo->currentIndex();
       
   456     if (currentIndex) {
       
   457         QList<Phonon::EffectDescription> availableEffects = Phonon::BackendCapabilities::availableAudioEffects();
       
   458         Phonon::EffectDescription chosenEffect = availableEffects[currentIndex - 1];
       
   459 
       
   460         QList<Phonon::Effect *> currEffects = m_audioOutputPath.effects();
       
   461         Phonon::Effect *currentEffect = currEffects.size() ? currEffects[0] : 0;
       
   462 
       
   463         // Deleting the running effect will stop playback, it is deleted when removed from path
       
   464         if (nextEffect && !(currentEffect && (currentEffect->description().name() == nextEffect->description().name())))
       
   465             delete nextEffect;
       
   466 
       
   467         nextEffect = new Phonon::Effect(chosenEffect);
       
   468     }
       
   469     ui->effectButton->setEnabled(currentIndex);
       
   470 }
       
   471 
       
   472 void MediaPlayer::showSettingsDialog()
       
   473 {
       
   474     if (!settingsDialog)
       
   475         initSettingsDialog();
       
   476 
       
   477     float oldBrightness = m_videoWidget->brightness();
       
   478     float oldHue = m_videoWidget->hue();
       
   479     float oldSaturation = m_videoWidget->saturation();
       
   480     float oldContrast = m_videoWidget->contrast();
       
   481     Phonon::VideoWidget::AspectRatio oldAspect = m_videoWidget->aspectRatio();
       
   482     Phonon::VideoWidget::ScaleMode oldScale = m_videoWidget->scaleMode();
       
   483     int currentEffect = ui->audioEffectsCombo->currentIndex();
       
   484     settingsDialog->exec();
       
   485     
       
   486     if (settingsDialog->result() == QDialog::Accepted){
       
   487         m_MediaObject.setTransitionTime((int)(1000 * float(ui->crossFadeSlider->value()) / 2.0f));
       
   488         QList<Phonon::AudioOutputDevice> devices = Phonon::BackendCapabilities::availableAudioOutputDevices();
       
   489         m_AudioOutput.setOutputDevice(devices[ui->deviceCombo->currentIndex()]);
       
   490         QList<Phonon::Effect *> currEffects = m_audioOutputPath.effects();
       
   491         QList<Phonon::EffectDescription> availableEffects = Phonon::BackendCapabilities::availableAudioEffects();
       
   492 
       
   493         if (ui->audioEffectsCombo->currentIndex() > 0){
       
   494             Phonon::Effect *currentEffect = currEffects.size() ? currEffects[0] : 0;    
       
   495             if (!currentEffect || currentEffect->description() != nextEffect->description()){
       
   496                 foreach(Phonon::Effect *effect, currEffects) {
       
   497                     m_audioOutputPath.removeEffect(effect);
       
   498                     delete effect;
       
   499                 }
       
   500                 m_audioOutputPath.insertEffect(nextEffect);
       
   501             }
       
   502         } else {
       
   503             foreach(Phonon::Effect *effect, currEffects) {
       
   504                 m_audioOutputPath.removeEffect(effect);
       
   505                 delete effect;
       
   506                 nextEffect = 0;
       
   507             }
       
   508         }
       
   509     } else {
       
   510         // Restore previous settings
       
   511         m_videoWidget->setBrightness(oldBrightness);
       
   512         m_videoWidget->setSaturation(oldSaturation);
       
   513         m_videoWidget->setHue(oldHue);
       
   514         m_videoWidget->setContrast(oldContrast);
       
   515         m_videoWidget->setAspectRatio(oldAspect);
       
   516         m_videoWidget->setScaleMode(oldScale);
       
   517         ui->audioEffectsCombo->setCurrentIndex(currentEffect);
       
   518     }
       
   519 }
       
   520 
       
   521 void MediaPlayer::initVideoWindow()
       
   522 {
       
   523     QVBoxLayout *videoLayout = new QVBoxLayout();
       
   524     videoLayout->addWidget(m_videoWidget);
       
   525     videoLayout->setContentsMargins(0, 0, 0, 0);
       
   526     m_videoWindow.setLayout(videoLayout);
       
   527     m_videoWindow.setMinimumSize(100, 100);
       
   528 }
       
   529 
       
   530 
       
   531 void MediaPlayer::configureEffect()
       
   532 {
       
   533     if (!nextEffect)
       
   534         return;
       
   535 
       
   536 
       
   537     QList<Phonon::Effect *> currEffects = m_audioOutputPath.effects();
       
   538     const QList<Phonon::EffectDescription> availableEffects = Phonon::BackendCapabilities::availableAudioEffects();
       
   539     if (ui->audioEffectsCombo->currentIndex() > 0) {
       
   540         Phonon::EffectDescription chosenEffect = availableEffects[ui->audioEffectsCombo->currentIndex() - 1];
       
   541 
       
   542         QDialog effectDialog;
       
   543         effectDialog.setWindowTitle(tr("Configure effect"));
       
   544         QVBoxLayout *topLayout = new QVBoxLayout(&effectDialog);
       
   545 
       
   546         QLabel *description = new QLabel("<b>Description:</b><br>" + chosenEffect.description(), &effectDialog);
       
   547         description->setWordWrap(true); 
       
   548         topLayout->addWidget(description);
       
   549 
       
   550         QScrollArea *scrollArea = new QScrollArea(&effectDialog);
       
   551         topLayout->addWidget(scrollArea);
       
   552 
       
   553         QVariantList savedParamValues;
       
   554         foreach(Phonon::EffectParameter param, nextEffect->parameters()) {
       
   555             savedParamValues << nextEffect->parameterValue(param);
       
   556         }
       
   557 
       
   558         QWidget *scrollWidget = new Phonon::EffectWidget(nextEffect);
       
   559         scrollWidget->setMinimumWidth(320);
       
   560         scrollWidget->setContentsMargins(10, 10, 10,10);
       
   561         scrollArea->setWidget(scrollWidget);
       
   562 
       
   563         QDialogButtonBox *bbox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal, &effectDialog);
       
   564         connect(bbox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), &effectDialog, SLOT(accept()));
       
   565         connect(bbox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), &effectDialog, SLOT(reject()));
       
   566         topLayout->addWidget(bbox);
       
   567 
       
   568         effectDialog.exec();
       
   569 
       
   570         if (effectDialog.result() != QDialog::Accepted) {
       
   571             //we need to restore the paramaters values
       
   572             int currentIndex = 0;
       
   573             foreach(Phonon::EffectParameter param, nextEffect->parameters()) {
       
   574                 nextEffect->setParameterValue(param, savedParamValues.at(currentIndex++));
       
   575             }
       
   576 
       
   577         }
       
   578     }
       
   579 }
       
   580 
       
   581 void MediaPlayer::handleDrop(QDropEvent *e)
       
   582 {
       
   583     QList<QUrl> urls = e->mimeData()->urls();
       
   584     if (e->proposedAction() == Qt::MoveAction){
       
   585         // Just add to the queue:
       
   586         for (int i=0; i<urls.size(); i++)
       
   587             m_MediaObject.enqueue(Phonon::MediaSource(urls[i].toLocalFile()));
       
   588     } else {
       
   589         // Create new queue:
       
   590         m_MediaObject.clearQueue();
       
   591         if (urls.size() > 0) {
       
   592             QString fileName = urls[0].toLocalFile();
       
   593             QDir dir(fileName);
       
   594             if (dir.exists()) {
       
   595                 dir.setFilter(QDir::Files);            
       
   596                 QStringList entries = dir.entryList();
       
   597                 if (entries.size() > 0) {
       
   598                     setFile(fileName + QDir::separator() +  entries[0]);
       
   599                     for (int i=1; i< entries.size(); ++i)
       
   600                         m_MediaObject.enqueue(fileName + QDir::separator() + entries[i]);
       
   601                 }
       
   602             } else {
       
   603                 setFile(fileName);
       
   604                 for (int i=1; i<urls.size(); i++)
       
   605                     m_MediaObject.enqueue(Phonon::MediaSource(urls[i].toLocalFile()));
       
   606             }        
       
   607         }
       
   608     }
       
   609     forwardButton->setEnabled(m_MediaObject.queue().size() > 0);
       
   610     m_MediaObject.play();
       
   611 }
       
   612 
       
   613 void MediaPlayer::dropEvent(QDropEvent *e)
       
   614 {
       
   615     if (e->mimeData()->hasUrls() && e->proposedAction() != Qt::LinkAction) {
       
   616         e->acceptProposedAction();
       
   617         handleDrop(e);
       
   618     } else {
       
   619         e->ignore(); 
       
   620     }
       
   621 }
       
   622 
       
   623 void MediaPlayer::dragEnterEvent(QDragEnterEvent *e)
       
   624 {
       
   625     dragMoveEvent(e);
       
   626 }
       
   627 
       
   628 void MediaPlayer::dragMoveEvent(QDragMoveEvent *e)
       
   629 {
       
   630     if (e->mimeData()->hasUrls()) {
       
   631         if (e->proposedAction() == Qt::CopyAction || e->proposedAction() == Qt::MoveAction){
       
   632             e->acceptProposedAction();
       
   633         }
       
   634     }
       
   635 }
       
   636 
       
   637 void MediaPlayer::playPause()
       
   638 {
       
   639     if (m_MediaObject.state() == Phonon::PlayingState)
       
   640         m_MediaObject.pause();
       
   641     else {
       
   642         if (m_MediaObject.currentTime() == m_MediaObject.totalTime())
       
   643             m_MediaObject.seek(0);
       
   644         m_MediaObject.play();
       
   645     }
       
   646 }
       
   647 
       
   648 void MediaPlayer::setFile(const QString &fileName)
       
   649 {
       
   650     setWindowTitle(fileName.right(fileName.length() - fileName.lastIndexOf('/') - 1));
       
   651     m_MediaObject.setCurrentSource(Phonon::MediaSource(fileName));
       
   652     m_MediaObject.play();
       
   653 }
       
   654 
       
   655 void MediaPlayer::openFile()
       
   656 {
       
   657     QStringList fileNames = QFileDialog::getOpenFileNames(this, QString(),
       
   658                                                           QDesktopServices::storageLocation(QDesktopServices::MusicLocation));
       
   659     m_MediaObject.clearQueue();
       
   660     if (fileNames.size() > 0) {
       
   661         QString fileName = fileNames[0];
       
   662         setFile(fileName);
       
   663         for (int i=1; i<fileNames.size(); i++)
       
   664             m_MediaObject.enqueue(Phonon::MediaSource(fileNames[i]));
       
   665     }
       
   666     forwardButton->setEnabled(m_MediaObject.queue().size() > 0);
       
   667 }
       
   668 
       
   669 void MediaPlayer::bufferStatus(int percent)
       
   670 {
       
   671     if (percent == 0 || percent == 100)
       
   672         progressLabel->setText(QString());
       
   673     else {
       
   674         QString str = QString::fromLatin1("(%1%)").arg(percent);
       
   675         progressLabel->setText(str);
       
   676     }
       
   677 }
       
   678 
       
   679 void MediaPlayer::setSaturation(int val)
       
   680 {
       
   681     m_videoWidget->setSaturation(val / qreal(SLIDER_RANGE));
       
   682 }
       
   683 
       
   684 void MediaPlayer::setHue(int val)
       
   685 {
       
   686     m_videoWidget->setHue(val / qreal(SLIDER_RANGE));
       
   687 }
       
   688 
       
   689 void MediaPlayer::setAspect(int val)
       
   690 {
       
   691     m_videoWidget->setAspectRatio(Phonon::VideoWidget::AspectRatio(val));
       
   692 }
       
   693 
       
   694 void MediaPlayer::setScale(int val)
       
   695 {
       
   696     m_videoWidget->setScaleMode(Phonon::VideoWidget::ScaleMode(val));
       
   697 }
       
   698 
       
   699 void MediaPlayer::setBrightness(int val)
       
   700 {
       
   701     m_videoWidget->setBrightness(val / qreal(SLIDER_RANGE));
       
   702 }
       
   703 
       
   704 void MediaPlayer::setContrast(int val)
       
   705 {
       
   706     m_videoWidget->setContrast(val / qreal(SLIDER_RANGE));
       
   707 }
       
   708 
       
   709 void MediaPlayer::updateInfo()
       
   710 {
       
   711     int maxLength = 30;
       
   712     QString font = "<font color=#ffeeaa>";
       
   713     QString fontmono = "<font family=\"monospace,courier new\" color=#ffeeaa>";
       
   714 
       
   715     QMap <QString, QString> metaData = m_MediaObject.metaData();
       
   716     QString trackArtist = metaData.value("ARTIST");
       
   717     if (trackArtist.length() > maxLength)
       
   718         trackArtist = trackArtist.left(maxLength) + "...";
       
   719     
       
   720     QString trackTitle = metaData.value("TITLE");
       
   721     int trackBitrate = metaData.value("BITRATE").toInt();
       
   722 
       
   723     QString fileName;
       
   724     if (m_MediaObject.currentSource().type() == Phonon::MediaSource::Url) {
       
   725         fileName = m_MediaObject.currentSource().url().toString();
       
   726     } else {
       
   727         fileName = m_MediaObject.currentSource().fileName();
       
   728         fileName = fileName.right(fileName.length() - fileName.lastIndexOf('/') - 1);
       
   729         if (fileName.length() > maxLength)
       
   730             fileName = fileName.left(maxLength) + "...";
       
   731     }
       
   732     
       
   733     QString title;    
       
   734     if (!trackTitle.isEmpty()) {
       
   735         if (trackTitle.length() > maxLength)
       
   736             trackTitle = trackTitle.left(maxLength) + "...";
       
   737         title = "Title: " + font + trackTitle + "<br></font>";
       
   738     } else if (!fileName.isEmpty()) {
       
   739         if (fileName.length() > maxLength)
       
   740             fileName = fileName.left(maxLength) + "...";
       
   741         title = font + fileName + "</font>";
       
   742         if (m_MediaObject.currentSource().type() == Phonon::MediaSource::Url) {
       
   743             title.prepend("Url: ");
       
   744         } else {
       
   745             title.prepend("File: ");
       
   746         }
       
   747     }
       
   748         
       
   749     QString artist;
       
   750     if (!trackArtist.isEmpty())
       
   751         artist = "Artist:  " + font + trackArtist + "</font>";
       
   752 
       
   753     QString bitrate;
       
   754     if (trackBitrate != 0)
       
   755         bitrate = "<br>Bitrate:  " + font + QString::number(trackBitrate/1000) + "kbit</font>";
       
   756 
       
   757     info->setText(title + artist + bitrate);
       
   758 }
       
   759 
       
   760 void MediaPlayer::updateTime()
       
   761 {
       
   762     long len = m_MediaObject.totalTime();
       
   763     long pos = m_MediaObject.currentTime();
       
   764     QString timeString;    
       
   765     if (pos || len)
       
   766     {
       
   767         int sec = pos/1000;
       
   768         int min = sec/60;
       
   769         int hour = min/60;
       
   770         int msec = pos;
       
   771 
       
   772         QTime playTime(hour%60, min%60, sec%60, msec%1000);
       
   773         sec = len / 1000;
       
   774         min = sec / 60;
       
   775         hour = min / 60;
       
   776         msec = len;
       
   777 
       
   778         QTime stopTime(hour%60, min%60, sec%60, msec%1000);
       
   779         QString timeFormat = "m:ss";
       
   780         if (hour > 0)
       
   781             timeFormat = "h:mm:ss";        
       
   782         timeString = playTime.toString(timeFormat);
       
   783         if (len)
       
   784             timeString += " / " + stopTime.toString(timeFormat);
       
   785     }
       
   786     timeLabel->setText(timeString);
       
   787 }
       
   788 
       
   789 void MediaPlayer::rewind()
       
   790 {
       
   791     m_MediaObject.seek(0);
       
   792 }
       
   793 
       
   794 void MediaPlayer::forward()
       
   795 {
       
   796     QList<Phonon::MediaSource> queue = m_MediaObject.queue();
       
   797     if (queue.size() > 0) {
       
   798         m_MediaObject.setCurrentSource(queue[0]);
       
   799         forwardButton->setEnabled(queue.size() > 1);
       
   800         m_MediaObject.play();
       
   801     }
       
   802 }
       
   803 
       
   804 void MediaPlayer::openUrl()
       
   805 {
       
   806     QSettings settings;
       
   807     settings.beginGroup(QLatin1String("BrowserMainWindow"));
       
   808     QString sourceURL = settings.value("location").toString();
       
   809     bool ok = false;
       
   810     sourceURL = QInputDialog::getText(this, tr("Open Location"), tr("Please enter a valid address here:"), QLineEdit::Normal, sourceURL, &ok);
       
   811     if (ok && !sourceURL.isEmpty()) {
       
   812         setWindowTitle(sourceURL.right(sourceURL.length() - sourceURL.lastIndexOf('/') - 1));
       
   813         m_MediaObject.setCurrentSource(Phonon::MediaSource(QUrl::fromEncoded(sourceURL.toUtf8())));
       
   814         m_MediaObject.play();
       
   815         settings.setValue("location", sourceURL);
       
   816     }
       
   817 }
       
   818 
       
   819 void MediaPlayer::finished()
       
   820 {
       
   821 }
       
   822 
       
   823 void MediaPlayer::showContextMenu(const QPoint &p)
       
   824 {
       
   825     fileMenu->popup(m_videoWidget->isFullScreen() ? p : mapToGlobal(p));
       
   826 }
       
   827 
       
   828 void MediaPlayer::scaleChanged(QAction *act)
       
   829 {
       
   830     if (act->text() == tr("Scale and crop"))
       
   831         m_videoWidget->setScaleMode(Phonon::VideoWidget::ScaleAndCrop);
       
   832     else 
       
   833         m_videoWidget->setScaleMode(Phonon::VideoWidget::FitInView);    
       
   834 }
       
   835 
       
   836 void MediaPlayer::aspectChanged(QAction *act)
       
   837 {
       
   838     if (act->text() == tr("16/9"))
       
   839         m_videoWidget->setAspectRatio(Phonon::VideoWidget::AspectRatio16_9);
       
   840     else if (act->text() == tr("Scale"))
       
   841         m_videoWidget->setAspectRatio(Phonon::VideoWidget::AspectRatioWidget);
       
   842     else if (act->text() == tr("4/3"))
       
   843         m_videoWidget->setAspectRatio(Phonon::VideoWidget::AspectRatio4_3);
       
   844     else
       
   845         m_videoWidget->setAspectRatio(Phonon::VideoWidget::AspectRatioAuto);    
       
   846 }
       
   847 
       
   848 void MediaPlayer::hasVideoChanged(bool bHasVideo)
       
   849 {
       
   850     info->setVisible(!bHasVideo);
       
   851     m_videoWindow.setVisible(bHasVideo);
       
   852 }