centralize and fixup example sources install targets

This follows suit with aeb036e in qtbase.

Change-Id: Ie8580d0a1f38ab9858b0e44c9f99bdc552a1752a
Reviewed-by: Oswald Buddenhagen <oswald.buddenhagen@digia.com>
Reviewed-by: hjk <qthjk@ovi.com>
This commit is contained in:
Joerg Bornemann
2012-12-05 13:03:09 +01:00
committed by The Qt Project
parent 90c8ba233b
commit 6b4994c265
407 changed files with 216 additions and 271 deletions

View File

@@ -0,0 +1,96 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the documentation of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:FDL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Digia. For licensing terms and
** conditions see http://qt.digia.com/licensing. For further information
** use the contact form at http://qt.digia.com/contact-us.
**
** GNU Free Documentation License Usage
** Alternatively, this file may be used under the terms of the GNU Free
** Documentation License version 1.3 as published by the Free Software
** Foundation and appearing in the file included in the packaging of
** this file. Please review the following information to ensure
** the GNU Free Documentation License version 1.3 requirements
** will be met: http://www.gnu.org/copyleft/fdl.html.
** $QT_END_LICENSE$
**
****************************************************************************/
/*!
\example player
\title Media Player Example
\ingroup video_examples
This example creates a simple multimedia player. We can play audio and
or video files using various codecs.
The example uses a QMediaPlayer object passed into a QVideoWidget to
control the video output. To give the application playlist capability
we also use a QPlayList object.
To activate the various functions such as play and stop on the dialog
we connect clicked() signals to slots that emit the play() and stop()
signals and in turn which we connect to the play() and stop() slots in
QMediaPlayer.
\code
connect(controls, SIGNAL(play()), player, SLOT(play()));
connect(controls, SIGNAL(pause()), player, SLOT(pause()));
connect(controls, SIGNAL(stop()), player, SLOT(stop()));
\endcode
We can get the volume (and set our user interface representation)
\code
controls->setVolume(player->volume());
\endcode
and we can make widget 'volume' changes change the volume
\code
connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int)));
\endcode
The example also allows us to change various video properties by means
of the QVideoWidget object. We can go to Full Screen mode with a single
button click, and back again. Or if we press the "Color Options" dialog
button we can have access to more subtle influences. The dialog has a
set of sliders so that we can change the brightness, contrast, hue and
saturation of the video being watched. The connect() statements are in
pairs so that changes to either the user interface widget (the relevant
slider) or the QVideoWidget object will update the other object.
\code
connect(brightnessSlider, SIGNAL(sliderMoved(int)), videoWidget,
SLOT(setBrightness(int)));
connect(videoWidget, SIGNAL(brightnessChanged(int)),
brightnessSlider, SLOT(setValue(int)));
connect(contrastSlider, SIGNAL(sliderMoved(int)), videoWidget,
SLOT(setContrast(int)));
connect(videoWidget, SIGNAL(contrastChanged(int)), contrastSlider,
SLOT(setValue(int)));
connect(hueSlider, SIGNAL(sliderMoved(int)), videoWidget,
SLOT(setHue(int)));
connect(videoWidget, SIGNAL(hueChanged(int)), hueSlider,
SLOT(setValue(int)));
connect(saturationSlider, SIGNAL(sliderMoved(int)), videoWidget,
SLOT(setSaturation(int)));
connect(videoWidget, SIGNAL(saturationChanged(int)),
saturationSlider, SLOT(setValue(int)));
\endcode
*/

View File

@@ -0,0 +1,154 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "histogramwidget.h"
#include <QPainter>
HistogramWidget::HistogramWidget(QWidget *parent)
: QWidget(parent)
, m_levels(128)
, m_isBusy(false)
{
m_processor.moveToThread(&m_processorThread);
qRegisterMetaType<QVector<qreal> >("QVector<qreal>");
connect(&m_processor, SIGNAL(histogramReady(QVector<qreal>)), SLOT(setHistogram(QVector<qreal>)));
m_processorThread.start(QThread::LowestPriority);
}
HistogramWidget::~HistogramWidget()
{
m_processorThread.quit();
m_processorThread.wait(10000);
}
void HistogramWidget::processFrame(QVideoFrame frame)
{
if (m_isBusy)
return; //drop frame
m_isBusy = true;
QMetaObject::invokeMethod(&m_processor, "processFrame",
Qt::QueuedConnection, Q_ARG(QVideoFrame, frame), Q_ARG(int, m_levels));
}
void HistogramWidget::setHistogram(QVector<qreal> histogram)
{
m_isBusy = false;
m_histogram = histogram;
update();
}
void HistogramWidget::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event);
QPainter painter(this);
if (m_histogram.isEmpty()) {
painter.fillRect(0, 0, width(), height(), QColor::fromRgb(0, 0, 0));
return;
}
qreal barWidth = width() / (qreal)m_histogram.size();
for (int i = 0; i < m_histogram.size(); i++) {
qreal h = m_histogram[i] * height();
// draw level
painter.fillRect(barWidth * i, height() - h, barWidth * (i + 1), height(), Qt::red);
// clear the rest of the control
painter.fillRect(barWidth * i, 0, barWidth * (i + 1), height() - h, Qt::black);
}
}
void FrameProcessor::processFrame(QVideoFrame frame, int levels)
{
QVector<qreal> histogram(levels);
do {
if (!levels)
break;
if (!frame.map(QAbstractVideoBuffer::ReadOnly))
break;
if (frame.pixelFormat() == QVideoFrame::Format_YUV420P ||
frame.pixelFormat() == QVideoFrame::Format_NV12) {
// Process YUV data
uchar *b = frame.bits();
for (int y = 0; y < frame.height(); y++) {
uchar *lastPixel = b + frame.width();
for (uchar *curPixel = b; curPixel < lastPixel; curPixel++)
histogram[(*curPixel * levels) >> 8] += 1.0;
b += frame.bytesPerLine();
}
} else {
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(frame.pixelFormat());
if (imageFormat != QImage::Format_Invalid) {
// Process RGB data
QImage image(frame.bits(), frame.width(), frame.height(), imageFormat);
image = image.convertToFormat(QImage::Format_RGB32);
const QRgb* b = (const QRgb*)image.bits();
for (int y = 0; y < image.height(); y++) {
const QRgb *lastPixel = b + frame.width();
for (const QRgb *curPixel = b; curPixel < lastPixel; curPixel++)
histogram[(qGray(*curPixel) * levels) >> 8] += 1.0;
b = (const QRgb*)((uchar*)b + image.bytesPerLine());
}
}
}
// find maximum value
qreal maxValue = 0.0;
for (int i = 0; i < histogram.size(); i++) {
if (histogram[i] > maxValue)
maxValue = histogram[i];
}
if (maxValue > 0.0) {
for (int i = 0; i < histogram.size(); i++)
histogram[i] /= maxValue;
}
frame.unmap();
} while (false);
emit histogramReady(histogram);
}

View File

@@ -0,0 +1,83 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef HISTOGRAMWIDGET_H
#define HISTOGRAMWIDGET_H
#include <QThread>
#include <QVideoFrame>
#include <QWidget>
class FrameProcessor: public QObject
{
Q_OBJECT
public slots:
void processFrame(QVideoFrame frame, int levels);
signals:
void histogramReady(QVector<qreal> histogram);
};
class HistogramWidget : public QWidget
{
Q_OBJECT
public:
explicit HistogramWidget(QWidget *parent = 0);
~HistogramWidget();
void setLevels(int levels) { m_levels = levels; }
public slots:
void processFrame(QVideoFrame frame);
void setHistogram(QVector<qreal> histogram);
protected:
void paintEvent(QPaintEvent *event);
private:
QVector<qreal> m_histogram;
int m_levels;
FrameProcessor m_processor;
QThread m_processorThread;
bool m_isBusy;
};
#endif // HISTOGRAMWIDGET_H

View File

@@ -0,0 +1,62 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "player.h"
#include <QApplication>
int main(int argc, char *argv[])
{
#ifdef Q_WS_MAEMO_6
//Meego graphics system conflicts with xvideo during fullscreen transition
QApplication::setGraphicsSystem("raster");
#endif
QApplication app(argc, argv);
Player player;
#if defined(Q_WS_SIMULATOR)
player.setAttribute(Qt::WA_LockLandscapeOrientation);
player.showMaximized();
#else
player.show();
#endif
return app.exec();
}

View File

@@ -0,0 +1,428 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "player.h"
#include "playercontrols.h"
#include "playlistmodel.h"
#include "histogramwidget.h"
#include <QMediaService>
#include <QMediaPlaylist>
#include <QVideoProbe>
#include <QtWidgets>
Player::Player(QWidget *parent)
: QWidget(parent)
, videoWidget(0)
, coverLabel(0)
, slider(0)
#ifndef PLAYER_NO_COLOROPTIONS
, colorDialog(0)
#endif
{
//! [create-objs]
player = new QMediaPlayer(this);
// owned by PlaylistModel
playlist = new QMediaPlaylist();
player->setPlaylist(playlist);
//! [create-objs]
connect(player, SIGNAL(durationChanged(qint64)), SLOT(durationChanged(qint64)));
connect(player, SIGNAL(positionChanged(qint64)), SLOT(positionChanged(qint64)));
connect(player, SIGNAL(metaDataChanged()), SLOT(metaDataChanged()));
connect(playlist, SIGNAL(currentIndexChanged(int)), SLOT(playlistPositionChanged(int)));
connect(player, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)),
this, SLOT(statusChanged(QMediaPlayer::MediaStatus)));
connect(player, SIGNAL(bufferStatusChanged(int)), this, SLOT(bufferingProgress(int)));
connect(player, SIGNAL(videoAvailableChanged(bool)), this, SLOT(videoAvailableChanged(bool)));
connect(player, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(displayErrorMessage()));
//! [2]
videoWidget = new VideoWidget(this);
player->setVideoOutput(videoWidget);
playlistModel = new PlaylistModel(this);
playlistModel->setPlaylist(playlist);
//! [2]
playlistView = new QListView(this);
playlistView->setModel(playlistModel);
playlistView->setCurrentIndex(playlistModel->index(playlist->currentIndex(), 0));
connect(playlistView, SIGNAL(activated(QModelIndex)), this, SLOT(jump(QModelIndex)));
slider = new QSlider(Qt::Horizontal, this);
slider->setRange(0, player->duration() / 1000);
labelDuration = new QLabel(this);
connect(slider, SIGNAL(sliderMoved(int)), this, SLOT(seek(int)));
labelHistogram = new QLabel(this);
labelHistogram->setText("Histogram:");
histogram = new HistogramWidget(this);
QHBoxLayout *histogramLayout = new QHBoxLayout;
histogramLayout->addWidget(labelHistogram);
histogramLayout->addWidget(histogram, 1);
probe = new QVideoProbe(this);
connect(probe, SIGNAL(videoFrameProbed(const QVideoFrame&)), histogram, SLOT(processFrame(QVideoFrame)));
probe->setSource(player);
QPushButton *openButton = new QPushButton(tr("Open"), this);
connect(openButton, SIGNAL(clicked()), this, SLOT(open()));
PlayerControls *controls = new PlayerControls(this);
controls->setState(player->state());
controls->setVolume(player->volume());
controls->setMuted(controls->isMuted());
connect(controls, SIGNAL(play()), player, SLOT(play()));
connect(controls, SIGNAL(pause()), player, SLOT(pause()));
connect(controls, SIGNAL(stop()), player, SLOT(stop()));
connect(controls, SIGNAL(next()), playlist, SLOT(next()));
connect(controls, SIGNAL(previous()), this, SLOT(previousClicked()));
connect(controls, SIGNAL(changeVolume(int)), player, SLOT(setVolume(int)));
connect(controls, SIGNAL(changeMuting(bool)), player, SLOT(setMuted(bool)));
connect(controls, SIGNAL(changeRate(qreal)), player, SLOT(setPlaybackRate(qreal)));
connect(controls, SIGNAL(stop()), videoWidget, SLOT(update()));
connect(player, SIGNAL(stateChanged(QMediaPlayer::State)),
controls, SLOT(setState(QMediaPlayer::State)));
connect(player, SIGNAL(volumeChanged(int)), controls, SLOT(setVolume(int)));
connect(player, SIGNAL(mutedChanged(bool)), controls, SLOT(setMuted(bool)));
fullScreenButton = new QPushButton(tr("FullScreen"), this);
fullScreenButton->setCheckable(true);
#ifndef PLAYER_NO_COLOROPTIONS
colorButton = new QPushButton(tr("Color Options..."), this);
colorButton->setEnabled(false);
connect(colorButton, SIGNAL(clicked()), this, SLOT(showColorDialog()));
#endif
QBoxLayout *displayLayout = new QHBoxLayout;
displayLayout->addWidget(videoWidget, 2);
displayLayout->addWidget(playlistView);
QBoxLayout *controlLayout = new QHBoxLayout;
controlLayout->setMargin(0);
controlLayout->addWidget(openButton);
controlLayout->addStretch(1);
controlLayout->addWidget(controls);
controlLayout->addStretch(1);
controlLayout->addWidget(fullScreenButton);
#ifndef PLAYER_NO_COLOROPTIONS
controlLayout->addWidget(colorButton);
#endif
QBoxLayout *layout = new QVBoxLayout;
layout->addLayout(displayLayout);
QHBoxLayout *hLayout = new QHBoxLayout;
hLayout->addWidget(slider);
hLayout->addWidget(labelDuration);
layout->addLayout(hLayout);
layout->addLayout(controlLayout);
layout->addLayout(histogramLayout);
setLayout(layout);
if (!player->isAvailable()) {
QMessageBox::warning(this, tr("Service not available"),
tr("The QMediaPlayer object does not have a valid service.\n"\
"Please check the media service plugins are installed."));
controls->setEnabled(false);
playlistView->setEnabled(false);
openButton->setEnabled(false);
#ifndef PLAYER_NO_COLOROPTIONS
colorButton->setEnabled(false);
#endif
fullScreenButton->setEnabled(false);
}
metaDataChanged();
QStringList arguments = qApp->arguments();
arguments.removeAt(0);
addToPlaylist(arguments);
}
Player::~Player()
{
}
void Player::open()
{
QStringList fileNames = QFileDialog::getOpenFileNames(this, tr("Open Files"));
addToPlaylist(fileNames);
}
void Player::addToPlaylist(const QStringList& fileNames)
{
foreach (QString const &argument, fileNames) {
QFileInfo fileInfo(argument);
if (fileInfo.exists()) {
QUrl url = QUrl::fromLocalFile(fileInfo.absoluteFilePath());
if (fileInfo.suffix().toLower() == QLatin1String("m3u")) {
playlist->load(url);
} else
playlist->addMedia(url);
} else {
QUrl url(argument);
if (url.isValid()) {
playlist->addMedia(url);
}
}
}
}
void Player::durationChanged(qint64 duration)
{
this->duration = duration/1000;
slider->setMaximum(duration / 1000);
}
void Player::positionChanged(qint64 progress)
{
if (!slider->isSliderDown()) {
slider->setValue(progress / 1000);
}
updateDurationInfo(progress / 1000);
}
void Player::metaDataChanged()
{
if (player->isMetaDataAvailable()) {
setTrackInfo(QString("%1 - %2")
.arg(player->metaData(QMediaMetaData::AlbumArtist).toString())
.arg(player->metaData(QMediaMetaData::Title).toString()));
if (coverLabel) {
QUrl url = player->metaData(QMediaMetaData::CoverArtUrlLarge).value<QUrl>();
coverLabel->setPixmap(!url.isEmpty()
? QPixmap(url.toString())
: QPixmap());
}
}
}
void Player::previousClicked()
{
// Go to previous track if we are within the first 5 seconds of playback
// Otherwise, seek to the beginning.
if(player->position() <= 5000)
playlist->previous();
else
player->setPosition(0);
}
void Player::jump(const QModelIndex &index)
{
if (index.isValid()) {
playlist->setCurrentIndex(index.row());
player->play();
}
}
void Player::playlistPositionChanged(int currentItem)
{
playlistView->setCurrentIndex(playlistModel->index(currentItem, 0));
}
void Player::seek(int seconds)
{
player->setPosition(seconds * 1000);
}
void Player::statusChanged(QMediaPlayer::MediaStatus status)
{
handleCursor(status);
// handle status message
switch (status) {
case QMediaPlayer::UnknownMediaStatus:
case QMediaPlayer::NoMedia:
case QMediaPlayer::LoadedMedia:
case QMediaPlayer::BufferingMedia:
case QMediaPlayer::BufferedMedia:
setStatusInfo(QString());
break;
case QMediaPlayer::LoadingMedia:
setStatusInfo(tr("Loading..."));
break;
case QMediaPlayer::StalledMedia:
setStatusInfo(tr("Media Stalled"));
break;
case QMediaPlayer::EndOfMedia:
QApplication::alert(this);
break;
case QMediaPlayer::InvalidMedia:
displayErrorMessage();
break;
}
}
void Player::handleCursor(QMediaPlayer::MediaStatus status)
{
#ifndef QT_NO_CURSOR
if (status == QMediaPlayer::LoadingMedia ||
status == QMediaPlayer::BufferingMedia ||
status == QMediaPlayer::StalledMedia)
setCursor(QCursor(Qt::BusyCursor));
else
unsetCursor();
#endif
}
void Player::bufferingProgress(int progress)
{
setStatusInfo(tr("Buffering %4%").arg(progress));
}
void Player::videoAvailableChanged(bool available)
{
if (!available) {
disconnect(fullScreenButton, SIGNAL(clicked(bool)),
videoWidget, SLOT(setFullScreen(bool)));
disconnect(videoWidget, SIGNAL(fullScreenChanged(bool)),
fullScreenButton, SLOT(setChecked(bool)));
videoWidget->setFullScreen(false);
} else {
connect(fullScreenButton, SIGNAL(clicked(bool)),
videoWidget, SLOT(setFullScreen(bool)));
connect(videoWidget, SIGNAL(fullScreenChanged(bool)),
fullScreenButton, SLOT(setChecked(bool)));
if (fullScreenButton->isChecked())
videoWidget->setFullScreen(true);
}
#ifndef PLAYER_NO_COLOROPTIONS
colorButton->setEnabled(available);
#endif
}
void Player::setTrackInfo(const QString &info)
{
trackInfo = info;
if (!statusInfo.isEmpty())
setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
else
setWindowTitle(trackInfo);
}
void Player::setStatusInfo(const QString &info)
{
statusInfo = info;
if (!statusInfo.isEmpty())
setWindowTitle(QString("%1 | %2").arg(trackInfo).arg(statusInfo));
else
setWindowTitle(trackInfo);
}
void Player::displayErrorMessage()
{
setStatusInfo(player->errorString());
}
void Player::updateDurationInfo(qint64 currentInfo)
{
QString tStr;
if (currentInfo || duration) {
QTime currentTime((currentInfo/3600)%60, (currentInfo/60)%60, currentInfo%60, (currentInfo*1000)%1000);
QTime totalTime((duration/3600)%60, (duration/60)%60, duration%60, (duration*1000)%1000);
QString format = "mm:ss";
if (duration > 3600)
format = "hh:mm:ss";
tStr = currentTime.toString(format) + " / " + totalTime.toString(format);
}
labelDuration->setText(tStr);
}
#ifndef PLAYER_NO_COLOROPTIONS
void Player::showColorDialog()
{
if (!colorDialog) {
QSlider *brightnessSlider = new QSlider(Qt::Horizontal);
brightnessSlider->setRange(-100, 100);
brightnessSlider->setValue(videoWidget->brightness());
connect(brightnessSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setBrightness(int)));
connect(videoWidget, SIGNAL(brightnessChanged(int)), brightnessSlider, SLOT(setValue(int)));
QSlider *contrastSlider = new QSlider(Qt::Horizontal);
contrastSlider->setRange(-100, 100);
contrastSlider->setValue(videoWidget->contrast());
connect(contrastSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setContrast(int)));
connect(videoWidget, SIGNAL(contrastChanged(int)), contrastSlider, SLOT(setValue(int)));
QSlider *hueSlider = new QSlider(Qt::Horizontal);
hueSlider->setRange(-100, 100);
hueSlider->setValue(videoWidget->hue());
connect(hueSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setHue(int)));
connect(videoWidget, SIGNAL(hueChanged(int)), hueSlider, SLOT(setValue(int)));
QSlider *saturationSlider = new QSlider(Qt::Horizontal);
saturationSlider->setRange(-100, 100);
saturationSlider->setValue(videoWidget->saturation());
connect(saturationSlider, SIGNAL(sliderMoved(int)), videoWidget, SLOT(setSaturation(int)));
connect(videoWidget, SIGNAL(saturationChanged(int)), saturationSlider, SLOT(setValue(int)));
QFormLayout *layout = new QFormLayout;
layout->addRow(tr("Brightness"), brightnessSlider);
layout->addRow(tr("Contrast"), contrastSlider);
layout->addRow(tr("Hue"), hueSlider);
layout->addRow(tr("Saturation"), saturationSlider);
QPushButton *button = new QPushButton(tr("Close"));
layout->addRow(button);
colorDialog = new QDialog(this);
colorDialog->setWindowTitle(tr("Color Options"));
colorDialog->setLayout(layout);
connect(button, SIGNAL(clicked()), colorDialog, SLOT(close()));
}
colorDialog->show();
}
#endif

View File

@@ -0,0 +1,127 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef PLAYER_H
#define PLAYER_H
#include "videowidget.h"
#include <QWidget>
#include <QMediaPlayer>
#include <QMediaPlaylist>
QT_BEGIN_NAMESPACE
class QAbstractItemView;
class QLabel;
class QMediaPlayer;
class QModelIndex;
class QPushButton;
class QSlider;
class QVideoProbe;
class QVideoWidget;
QT_END_NAMESPACE
class PlaylistModel;
class HistogramWidget;
class Player : public QWidget
{
Q_OBJECT
public:
Player(QWidget *parent = 0);
~Player();
signals:
void fullScreenChanged(bool fullScreen);
private slots:
void open();
void durationChanged(qint64 duration);
void positionChanged(qint64 progress);
void metaDataChanged();
void previousClicked();
void seek(int seconds);
void jump(const QModelIndex &index);
void playlistPositionChanged(int);
void statusChanged(QMediaPlayer::MediaStatus status);
void bufferingProgress(int progress);
void videoAvailableChanged(bool available);
void displayErrorMessage();
#ifndef PLAYER_NO_COLOROPTIONS
void showColorDialog();
#endif
void addToPlaylist(const QStringList &fileNames);
private:
void setTrackInfo(const QString &info);
void setStatusInfo(const QString &info);
void handleCursor(QMediaPlayer::MediaStatus status);
void updateDurationInfo(qint64 currentInfo);
QMediaPlayer *player;
QMediaPlaylist *playlist;
VideoWidget *videoWidget;
QLabel *coverLabel;
QSlider *slider;
QLabel *labelDuration;
QPushButton *fullScreenButton;
#ifndef PLAYER_NO_COLOROPTIONS
QPushButton *colorButton;
QDialog *colorDialog;
#endif
QLabel *labelHistogram;
HistogramWidget *histogram;
QVideoProbe *probe;
PlaylistModel *playlistModel;
QAbstractItemView *playlistView;
QString trackInfo;
QString statusInfo;
qint64 duration;
};
#endif // PLAYER_H

View File

@@ -0,0 +1,28 @@
TEMPLATE = app
TARGET = player
QT += network \
xml \
multimedia \
multimediawidgets \
widgets
HEADERS = \
player.h \
playercontrols.h \
playlistmodel.h \
videowidget.h \
histogramwidget.h
SOURCES = main.cpp \
player.cpp \
playercontrols.cpp \
playlistmodel.cpp \
videowidget.cpp \
histogramwidget.cpp
maemo* {
DEFINES += PLAYER_NO_COLOROPTIONS
}
target.path = $$[QT_INSTALL_EXAMPLES]/multimediawidgets/player
INSTALLS += target

View File

@@ -0,0 +1,205 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "playercontrols.h"
#include <QBoxLayout>
#include <QSlider>
#include <QStyle>
#include <QToolButton>
#include <QComboBox>
PlayerControls::PlayerControls(QWidget *parent)
: QWidget(parent)
, playerState(QMediaPlayer::StoppedState)
, playerMuted(false)
, playButton(0)
, stopButton(0)
, nextButton(0)
, previousButton(0)
, muteButton(0)
, volumeSlider(0)
, rateBox(0)
{
playButton = new QToolButton(this);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
connect(playButton, SIGNAL(clicked()), this, SLOT(playClicked()));
stopButton = new QToolButton(this);
stopButton->setIcon(style()->standardIcon(QStyle::SP_MediaStop));
stopButton->setEnabled(false);
connect(stopButton, SIGNAL(clicked()), this, SIGNAL(stop()));
nextButton = new QToolButton(this);
nextButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipForward));
connect(nextButton, SIGNAL(clicked()), this, SIGNAL(next()));
previousButton = new QToolButton(this);
previousButton->setIcon(style()->standardIcon(QStyle::SP_MediaSkipBackward));
connect(previousButton, SIGNAL(clicked()), this, SIGNAL(previous()));
muteButton = new QToolButton(this);
muteButton->setIcon(style()->standardIcon(QStyle::SP_MediaVolume));
connect(muteButton, SIGNAL(clicked()), this, SLOT(muteClicked()));
volumeSlider = new QSlider(Qt::Horizontal, this);
volumeSlider->setRange(0, 100);
connect(volumeSlider, SIGNAL(sliderMoved(int)), this, SIGNAL(changeVolume(int)));
rateBox = new QComboBox(this);
rateBox->addItem("0.5x", QVariant(0.5));
rateBox->addItem("1.0x", QVariant(1.0));
rateBox->addItem("2.0x", QVariant(2.0));
rateBox->setCurrentIndex(1);
connect(rateBox, SIGNAL(activated(int)), SLOT(updateRate()));
QBoxLayout *layout = new QHBoxLayout;
layout->setMargin(0);
layout->addWidget(stopButton);
layout->addWidget(previousButton);
layout->addWidget(playButton);
layout->addWidget(nextButton);
layout->addWidget(muteButton);
layout->addWidget(volumeSlider);
layout->addWidget(rateBox);
setLayout(layout);
}
QMediaPlayer::State PlayerControls::state() const
{
return playerState;
}
void PlayerControls::setState(QMediaPlayer::State state)
{
if (state != playerState) {
playerState = state;
switch (state) {
case QMediaPlayer::StoppedState:
stopButton->setEnabled(false);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
break;
case QMediaPlayer::PlayingState:
stopButton->setEnabled(true);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPause));
break;
case QMediaPlayer::PausedState:
stopButton->setEnabled(true);
playButton->setIcon(style()->standardIcon(QStyle::SP_MediaPlay));
break;
}
}
}
int PlayerControls::volume() const
{
return volumeSlider ? volumeSlider->value() : 0;
}
void PlayerControls::setVolume(int volume)
{
if (volumeSlider)
volumeSlider->setValue(volume);
}
bool PlayerControls::isMuted() const
{
return playerMuted;
}
void PlayerControls::setMuted(bool muted)
{
if (muted != playerMuted) {
playerMuted = muted;
muteButton->setIcon(style()->standardIcon(muted
? QStyle::SP_MediaVolumeMuted
: QStyle::SP_MediaVolume));
}
}
void PlayerControls::playClicked()
{
switch (playerState) {
case QMediaPlayer::StoppedState:
case QMediaPlayer::PausedState:
emit play();
break;
case QMediaPlayer::PlayingState:
emit pause();
break;
}
}
void PlayerControls::muteClicked()
{
emit changeMuting(!playerMuted);
}
qreal PlayerControls::playbackRate() const
{
return rateBox->itemData(rateBox->currentIndex()).toDouble();
}
void PlayerControls::setPlaybackRate(float rate)
{
for (int i = 0; i < rateBox->count(); ++i) {
if (qFuzzyCompare(rate, float(rateBox->itemData(i).toDouble()))) {
rateBox->setCurrentIndex(i);
return;
}
}
rateBox->addItem(QString("%1x").arg(rate), QVariant(rate));
rateBox->setCurrentIndex(rateBox->count() - 1);
}
void PlayerControls::updateRate()
{
emit changeRate(playbackRate());
}

View File

@@ -0,0 +1,98 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef PLAYERCONTROLS_H
#define PLAYERCONTROLS_H
#include <QMediaPlayer>
#include <QWidget>
QT_BEGIN_NAMESPACE
class QAbstractButton;
class QAbstractSlider;
class QComboBox;
QT_END_NAMESPACE
class PlayerControls : public QWidget
{
Q_OBJECT
public:
PlayerControls(QWidget *parent = 0);
QMediaPlayer::State state() const;
int volume() const;
bool isMuted() const;
qreal playbackRate() const;
public slots:
void setState(QMediaPlayer::State state);
void setVolume(int volume);
void setMuted(bool muted);
void setPlaybackRate(float rate);
signals:
void play();
void pause();
void stop();
void next();
void previous();
void changeVolume(int volume);
void changeMuting(bool muting);
void changeRate(qreal rate);
private slots:
void playClicked();
void muteClicked();
void updateRate();
private:
QMediaPlayer::State playerState;
bool playerMuted;
QAbstractButton *playButton;
QAbstractButton *stopButton;
QAbstractButton *nextButton;
QAbstractButton *previousButton;
QAbstractButton *muteButton;
QAbstractSlider *volumeSlider;
QComboBox *rateBox;
};
#endif // PLAYERCONTROLS_H

View File

@@ -0,0 +1,156 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "playlistmodel.h"
#include <QFileInfo>
#include <QUrl>
#include <QMediaPlaylist>
PlaylistModel::PlaylistModel(QObject *parent)
: QAbstractItemModel(parent)
, m_playlist(0)
{
}
int PlaylistModel::rowCount(const QModelIndex &parent) const
{
return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0;
}
int PlaylistModel::columnCount(const QModelIndex &parent) const
{
return !parent.isValid() ? ColumnCount : 0;
}
QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const
{
return m_playlist && !parent.isValid()
&& row >= 0 && row < m_playlist->mediaCount()
&& column >= 0 && column < ColumnCount
? createIndex(row, column)
: QModelIndex();
}
QModelIndex PlaylistModel::parent(const QModelIndex &child) const
{
Q_UNUSED(child);
return QModelIndex();
}
QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && role == Qt::DisplayRole) {
QVariant value = m_data[index];
if (!value.isValid() && index.column() == Title) {
QUrl location = m_playlist->media(index.row()).canonicalUrl();
return QFileInfo(location.path()).fileName();
}
return value;
}
return QVariant();
}
QMediaPlaylist *PlaylistModel::playlist() const
{
return m_playlist;
}
void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
{
if (m_playlist) {
disconnect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
disconnect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
disconnect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
disconnect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
disconnect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
}
beginResetModel();
m_playlist = playlist;
if (m_playlist) {
connect(m_playlist, SIGNAL(mediaAboutToBeInserted(int,int)), this, SLOT(beginInsertItems(int,int)));
connect(m_playlist, SIGNAL(mediaInserted(int,int)), this, SLOT(endInsertItems()));
connect(m_playlist, SIGNAL(mediaAboutToBeRemoved(int,int)), this, SLOT(beginRemoveItems(int,int)));
connect(m_playlist, SIGNAL(mediaRemoved(int,int)), this, SLOT(endRemoveItems()));
connect(m_playlist, SIGNAL(mediaChanged(int,int)), this, SLOT(changeItems(int,int)));
}
endResetModel();
}
bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_UNUSED(role);
m_data[index] = value;
emit dataChanged(index, index);
return true;
}
void PlaylistModel::beginInsertItems(int start, int end)
{
m_data.clear();
beginInsertRows(QModelIndex(), start, end);
}
void PlaylistModel::endInsertItems()
{
endInsertRows();
}
void PlaylistModel::beginRemoveItems(int start, int end)
{
m_data.clear();
beginRemoveRows(QModelIndex(), start, end);
}
void PlaylistModel::endRemoveItems()
{
endInsertRows();
}
void PlaylistModel::changeItems(int start, int end)
{
m_data.clear();
emit dataChanged(index(start,0), index(end,ColumnCount));
}

View File

@@ -0,0 +1,88 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef PLAYLISTMODEL_H
#define PLAYLISTMODEL_H
#include <QAbstractItemModel>
QT_BEGIN_NAMESPACE
class QMediaPlaylist;
QT_END_NAMESPACE
class PlaylistModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum Column
{
Title = 0,
ColumnCount
};
PlaylistModel(QObject *parent = 0);
int rowCount(const QModelIndex &parent = QModelIndex()) const;
int columnCount(const QModelIndex &parent = QModelIndex()) const;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
QModelIndex parent(const QModelIndex &child) const;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
QMediaPlaylist *playlist() const;
void setPlaylist(QMediaPlaylist *playlist);
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole);
private slots:
void beginInsertItems(int start, int end);
void endInsertItems();
void beginRemoveItems(int start, int end);
void endRemoveItems();
void changeItems(int start, int end);
private:
QMediaPlaylist *m_playlist;
QMap<QModelIndex, QVariant> m_data;
};
#endif // PLAYLISTMODEL_H

View File

@@ -0,0 +1,81 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "videowidget.h"
#include <QKeyEvent>
#include <QMouseEvent>
VideoWidget::VideoWidget(QWidget *parent)
: QVideoWidget(parent)
{
setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
QPalette p = palette();
p.setColor(QPalette::Window, Qt::black);
setPalette(p);
setAttribute(Qt::WA_OpaquePaintEvent);
}
void VideoWidget::keyPressEvent(QKeyEvent *event)
{
if (event->key() == Qt::Key_Escape && isFullScreen()) {
setFullScreen(false);
event->accept();
} else if (event->key() == Qt::Key_Enter && event->modifiers() & Qt::Key_Alt) {
setFullScreen(!isFullScreen());
event->accept();
} else {
QVideoWidget::keyPressEvent(event);
}
}
void VideoWidget::mouseDoubleClickEvent(QMouseEvent *event)
{
setFullScreen(!isFullScreen());
event->accept();
}
void VideoWidget::mousePressEvent(QMouseEvent *event)
{
QVideoWidget::mousePressEvent(event);
}

View File

@@ -0,0 +1,59 @@
/****************************************************************************
**
** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
** Contact: http://www.qt-project.org/legal
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** You may use this file under the terms of the BSD license as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of Digia Plc and its Subsidiary(-ies) nor the names
** of its contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef VIDEOWIDGET_H
#define VIDEOWIDGET_H
#include <QVideoWidget>
class VideoWidget : public QVideoWidget
{
Q_OBJECT
public:
VideoWidget(QWidget *parent = 0);
protected:
void keyPressEvent(QKeyEvent *event);
void mouseDoubleClickEvent(QMouseEvent *event);
void mousePressEvent(QMouseEvent *event);
};
#endif // VIDEOWIDGET_H