source: trunk/demos/qmediaplayer/mediaplayer.cpp@ 814

Last change on this file since 814 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

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